git reset –hard head`和git clean --force -d`vs`git checkout-之间有什么区别? [英] What is the difference between `git reset --hard head` vs `git clean --force -d ` vs `git checkout -- .` to discard local changes

查看:137
本文介绍了git reset –hard head`和git clean --force -d`vs`git checkout-之间有什么区别?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

git reset --hard head vs git clean --force -d vs git checkout -- .git pull之间的区别是什么?丢弃本地更改并从Git服务器存储库获取最新信息?

What are the differences between git reset --hard head vs git clean --force -d vs git checkout -- . then git pull to discard local changes and get the latest from the Git server repository?

推荐答案

As Ryan commented, git clean is very different from the other two (which are pretty close, but not identical).

要详细比较git checkout -- .git reset --hard HEAD,请参阅我对结帐-."和"git reset HEAD --hard"?请密切注意 index 的描述,因为这将使您了解下一部分.

For comparing, in gory detail, git checkout -- . and git reset --hard HEAD, see my answer to What is the difference between "git checkout -- ." and "git reset HEAD --hard"? Pay close attention to the descriptions of the index since that will inform you about the next part.

请记住,尽管您不能直接看到索引,但是 1 下一次提交的内容.因此,至关重要的是要了解Git使用索引而不是工作树进行提交.通常,通过将索引与HEAD提交进行比较来查看"索引就足够了:只要索引中的文件与HEAD提交中的同一文件完全相同,而git status则什么也不说.但是只要文件不同,git status都会打印出一些东西.

Remember, although you cannot see the index directly,1 it's what goes into the next commit. As such it is crucial that you understand that Git makes commits using the index, not the work-tree. Usually, it's sufficient to "see" the index by comparing it to the HEAD commit: wherever a file in the index is exactly the same as that same file in the HEAD commit, git status says nothing; but wherever a file is different, git status prints something.

(注意:git status还将索引与工作树分别进行比较.如果索引不同,则表示某些内容-除外用于未跟踪但被忽略的文件.仅适用于-根据定义,树文件可以被取消跟踪,因此毫无疑问索引文件是否被取消.总结它运行的两个git diff时,git status可以一次执行一次,在默认的长格式输出中,或一次全部显示在--short输出中.)

(Note: git status also, separately, compares the index to the work-tree. Where those are different, it says something—except for untracked-but-ignored files. Only work-tree files can be untracked, by definition, so there's no question about whether index files are untracked. When summarizing the two git diffs it ran, git status can either do it one at a time, in the default long-form output, or all at once, in the --short output.)

1 实际上,您可以看到索引:运行git ls-index --stage,Git会溢出整个内容. 2 实际上对于调试非常有用.但是,对于具有许多文件的大型存储库,它每天打印太多,而git status是更好的工具.

1Actually, you can see the index: run git ls-index --stage and Git will spill out the whole thing.2 This is actually quite useful for debugging. With a large repository with many files, though, it prints way too much for every-day use, and git status is a much better tool.

2 实际上,您需要添加--debug来获得 whole 内容,包括--assume-unchanged--skip-worktree标志,即使这样,Git也会隐藏特殊内容.撤消您的条目.

2Actually you need to add --debug to get the whole thing, including the --assume-unchanged and --skip-worktree flags, and even then Git hides the special undo entries from you.

在Git中,未跟踪的文件的定义实际上非常简单:它是不在索引中的文件.这几乎就是所有内容,尽管出于git clean的目的,我们还需要另外一项,即文件是否也被忽略.

In Git, an untracked file is actually remarkably simple to define: it's a file that is not in the index. That's almost all there is to it, though for git clean purposes, we also need one more item, namely, whether the file is ignored too.

如果文件被跟踪(位于索引中),则不能忽略它.这样的文件是Git已知的,因此git clean将永远不会碰到它们:这不是它的工作;它的工作是删除部分或全部 untracked 文件.只能忽略未跟踪的文件,因此,未跟踪的文件要么被跟踪但不被忽略,要么被跟踪也被忽略.

A file cannot be ignored if it is tracked (is in the index). Such files are known to Git, so git clean will never touch them: that's not its job; its job is to remove some or all of the untracked files. Only an untracked file can be ignored, so an untracked file is either untracked-but-not-ignored, or untracked-and-also-ignored.

默认情况下,根据--dry-run--force之类的选项,git clean会删除(或假装删除),只会删除那些也不会被忽略的未跟踪文件.

By default, git clean will remove—or pretend to remove, depending on options like --dry-run vs --force—only those untracked files that are not also ignored.

使用-X(大写X)选项,git clean将仅删除(或一如既往地假装删除)那些忽略了 的未跟踪文件.

With the -X (uppercase X) option, git clean will remove (or as always, pretend to remove) only those untracked files that are ignored.

使用-x(小写的x)选项,git clean绕过所有忽略"规则,这意味着所有未跟踪的文件将自动属于未跟踪且不可忽略的类别.因此,git clean -f -x将删除所有未跟踪的文件,即使那些通常被忽略的文件也是如此.

With the -x (lowercase x) option, git clean bypasses all the "ignore" rules, which means that all untracked files automatically fall into the untracked-and-not-ignored category. Thus, git clean -f -x will remove all untracked files, even those that are normally ignored.

对于-dgit clean还将删除目录.根据定义,目录永远不会被跟踪, 3 ,因此所有目录实际上都是未跟踪的,但是它们是未跟踪的目录,而不是未跟踪的文件.但是,Git对子目录使用一种特殊的捷径处理,该子目录只包含未跟踪的文件(或者完全为空):除了枚举该目录 中的每个(未跟踪的)文件之外,Git都认为这是 4 git clean命令通常将这些保留为空:

With -d, git clean will also remove directories. By definition, directories are never tracked,3 so all directories are effectively untracked—but they're untracked directories, not untracked files. Git uses a special short-cut treatment for a subdirectory that contains nothing but untracked files (or that is completely empty), though: instead of enumerating every (untracked) file in that directory, Git just considers this an "untracked directory".4 The git clean command normally leaves these alone:

$ mkdir tt
$ cd tt
$ git init
Initialized empty Git repository in ...
$ echo for testing git clean > README
$ git add README
$ touch untr
$ mkdir sub
$ touch sub/subfile
$ git status --short
A  README
?? sub/
?? untr

git status --short输出的双问号表示未跟踪的文件或未跟踪的目录.由于sub是其中包含未跟踪文件的目录,因此它显示为未跟踪目录.运行git clean -f(或git clean -n)表明Git删除了(或将删除)untr,这是一个不会被忽略的未跟踪文件.但是Git不会删除sub/subfile sub本身:

The double question mark output from git status --short indicates an untracked file or untracked directory. Since sub is a directory with an untracked file in it, it shows up as an untracked directory. Running git clean -f (or git clean -n) shows that Git removes (or would remove) untr, which is an untracked file that is not ignored; but Git does not remove either sub/subfile or sub itself:

$ git clean -f
Removing untr

git clean选项中添加-d可使Git删除sub/subfilesub:

Adding -d to the git clean options makes Git remove both sub/subfile and sub:

$ git clean -df
Removing sub/

(按照POSIX的要求,删除整个目录意味着首先删除其所有内容.)

(Removing the entire directory implies removing all of its contents first, as required by POSIX.)

git clean中添加路径名参数会将其清理限制为给定的路径名​​,这非常简单.

Adding pathname arguments to git clean restricts its cleaning to the given pathnames, which is pretty straightforward.

请注意,还有一个特殊的特殊情况,即目录不会被忽略,但包含另一个Git存储库(无论是作为常规存储库,还是作为当前存储库的子模块):git clean -dfgit clean -dfx不会删除此子存储库,但git clean -dffgit clean -dffx 将会.

Note that there is yet another special corner case for a directory that is not ignored but contains another Git repository (whether as a regular repository, or as a submodule of the current repository): git clean -df or git clean -dfx will not remove this sub-repository, but git clean -dff or git clean -dffx will.

3 这实际上意味着您无法将目录添加到索引. 如果您尝试了足够的尝试,使用管道命令,可以诱骗Git使用正确的模式和名称来存储条目,但要使用数字在一定条件下,Git将该条目的模式从目录"更改为"gitlink",此后事情就变得很糟糕.(存在Gitlink条目用于存储子模块信息,通常在 中找到该条目一个Git索引.)

3What this really means is that you cannot add a directory to the index. If you try hard enough, using the plumbing commands, you can trick Git into storing an entry with the right mode and name, but under a number of conditions, Git changes this entry's mode from "directory" to "gitlink", after which things go quite badly awry. (Gitlink entries exist to store submodule information, and are normally found in a Git index.)

4 Git秘密地确实stat信息关于(至少一些)目录存储在索引中,作为性能改进.要点是,如果Git发现某个目录(例如sub)仅包含未跟踪的文件,或者(递归地)仅包含未跟踪的文件的目录,则Git可以将其分类为在以后的工作树扫描中跳过" .加上Git的特殊忽略规则,这些规则可防止显式忽略"被忽略目录中的文件,如果自上次扫描以来未修改目录本身,Git可以避免在目录中扫描其他未跟踪但未被忽略的文件. (同样的想法-也就是说,如果目录本身未经修改,就不可能再添加任何新文件-甚至适用于包含跟踪文件的目录,尽管我不记得如果Git使用了事实,便会立即使用.)

4Git secretly does store stat information about (at least some) directories in the index, as a performance hack. The gist of this is that if Git has found that some directory such as sub contains nothing but untracked files or (recursively) directories with nothing but untracked files, Git can classify the thing as "to skip in future work-tree scans". This, plus Git's special ignore rules that prevent explicit "unignoring" of files within ignored directories, allow Git to avoid scanning the directory for additional untracked-but-not-ignored files if the directory itself is not modified since the last scan. (This same idea—that is, that if the directory itself is unmodified, no new files can possibly have been added to it—is even applicable to directories containing tracked files, although I don't remember offhand if Git uses the fact.)

这篇关于git reset –hard head`和git clean --force -d`vs`git checkout-之间有什么区别?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆