难以使工作树看起来像索引?
Pro Git解释如下的git reset :
概括
reset命令按照特定的顺序覆盖这三棵树,当你告诉它时:
--soft ,则停在此处) --hard ) 我理解的方式是,如果我git reset --hard ,那么我的两个指标,我的工作目录将成为完全像我的头。 所以我继续做下去:
# make a git repo
mkdir mygitrepo
cd mygitrepo
git init
# init commit
touch old_file
git commit -a
# stage a file
touch staged
git add staged
# create file that is not staged
touch unstaged
到目前为止,我的回购看起来像这样:
HEAD old_file index old_file +上演 working dir old_file + staged + unstaged 现在,如果我运行git reset --hard那么我希望我的回购变成:
HEAD old_file index old_file working dir old_file 但我会得到这个:
HEAD old_file index old_file working dir old_file + unstaged 我通过显式传递目标参数来做类似的测试,比如git reset --hard target ,而且我得到了类似的结果:staged文件全部没了,但未归档的文件在git reset --hard后仍然存在。
有人可以解释我是否误解了有关git reset任何内容?
正如“撤销更改”中所述
git clean命令通常与git reset --hard一起执行。
请记住,重置仅影响跟踪的文件,因此需要单独的命令清理未跟踪的文件 。
结合起来,这两个命令可让您将工作目录返回到特定提交的确切状态。
--hard选项记录为:
重置索引和工作树。
放弃自<commit>以来对工作树中跟踪文件所做的任何更改。
早在2008年就已经讨论过了。
Linux Torvalds简单地说:
如果你习惯做“ git checkout -f ”或“ git reset --hard ”,那么这两个检查(*)都会被忽略。 毕竟,你要求强制切换。
(*检查=脏文件或未跟踪文件)
至少在第二种情况下, 我认为会发生的事情是git不会删除它不知道的文件,所以你会留下一个“烂”字 。
虽然增加了文件,即使从未提交过(即全新的),仍然会被git reset --hard删除,如2008年所见:
我实际上意外删除了数百个新添加的文件,昨天就这样做了。
我的问题是为什么“ git reset --hard ”不能为新添加的跟踪文件制作特殊情况?
毕竟,“ git status ”知道它们是“新文件”,而“ git reset --hard ”可以意识到,将它们从地球表面抹去并不是最有用的可能。
作为一个建议,在git reset --hard前git read-tree -m HEAD或git rm --cached <file list> git reset --hard会帮助保留这些新文件(将它们从索引中删除)
Junio C. Hamano stil认为:
当HEAD中不存在路径但在其他情况下在索引中存在路径时,您会想要“ reset --hard ”来移除该路径 。
这是我的经验,往往不是它是可取的。
(比如摆脱冲突合并中的残酷)
请注意,在这种情况下, git fsck仍然可以帮助恢复这些被删除的新文件。
Git总会遵循一条重要规则(除非明确告知不要这样做): 不要触摸未跟踪的文件 。
使用默认功能,Git不会执行任何会导致未跟踪文件数据丢失的操作。 这是因为来自未跟踪文件的信息永远无法通过Git恢复:它不会“知道”它们,因此它不会将其内容存储到任何地方,因此对它们进行任何操作都非常危险。 所以它不会触及它们。
这也是为什么如果分支包含具有相同路径的跟踪文件,Git不会让您切换到未跟踪文件的分支。 因为这样做会覆盖未跟踪的文件,将其替换为来自该分支的文件,但无法恢复未跟踪的文件。 因此,Git将不会切换分支,要求您首先处理未跟踪的文件(这可能意味着将其重命名,将其添加到Git中,甚至删除它)。
所以当你做git reset ,你只会影响索引。 而git reset --hard会影响索引和工作目录。 而对于Git,工作目录只包含跟踪的文件。 这就是为什么git reset --hard既不会删除未记录的文件,也不会删除位于.gitignore文件。 Git不会“知道”它们,所以它不会触及它们。
如果你想删除未跟踪的文件,有一个命令负责:git clean。 该命令附带了不同的参数组合,它们都执行各种不同的作业。
默认情况下, git clean -f会删除未跟踪的文件,但保留忽略的文件。 如果你还想删除被忽略的文件,你可以使用git clean -x -f 。 请注意,您通常必须始终指定-f (或--force )作为git clean来执行任何操作。 这只是一个额外的安全机制,以确保你知道你在做什么。 您可以使用-n来执行干运行,并只显示Git将删除的文件。 这可以很容易地避免问题。
