我正在尝试使用git checkout <hash> <directory>
检查我的仓库中目录的先前版本。这可以将目录中的文件恢复到以前的状态,唯一的问题是自我签出的修订版本以来添加的子目录不会消失。
例如,如果我的目录结构如下:
HEAD:
thing/dir1/
thing/dir2/
HEAD^:
thing/dir1/
如果我git checkout <hash>
,那么我进入分离的HEAD模式,一切都很好。如果我执行git checkout <hash> thing/
,thing/dir1/
的内容将恢复,但thing/dir2/
将保留。
正在运行git status
会显示thing/dir1/
的文件修改,但未提及thing/dir2/
。这很奇怪,因为在HEAD ^的上下文中,thing/dir2/
不应该存在,因此应该消失。 git clean
没有帮助,因为它甚至没有显示为未跟踪。
有没有办法检查完全匹配的目录的先前版本,而不必检查整个工作树?
更新
看起来这样可行:
git reset <hash> thing/
git checkout <hash> thing/
git clean -fd thing/
这使我的工作树和索引处于一种奇怪的状态,但具有所需的效果。
答案 0 :(得分:1)
正如您已经提到git checkout <hash>
使git进入分离头模式。检查特定文件时,实际上只将文件复制到工作目录中,而其他所有文件都不会被触及。
因此,thing/dir2/
中的文件未显示在git status
中,因为它们处于HEAD
的当前状态,而thing/dir1
将显示已修改的文件。
如果你真的想拥有像上一版本一样的整个thing/
文件夹,为什么不在之前删除呢?
rm thing/
git checkout <hash> thing/
我不确定它是否符合您的需求。谨慎使用! (虽然当没有本地未经修改的更改时,应该可以恢复。)
答案 1 :(得分:1)
来自http://git-scm.com/docs/git-checkout:
将工作树中的文件更新为 匹配索引中的版本或 指定树。如果没有给出路径, git checkout还会将HEAD更新为 将指定的分支设置为 现任分支。
下面还说:
何时&lt;路径&gt;或 - 补丁,git 结帐不会切换分支。它 更新工作中的命名路径 索引文件中的树或来自 命名(最常见的是 承诺)。在这种情况下,-b和 --track选项毫无意义,并给出其中任何一个结果 错误。争论可以是 用于指定特定的树 (即提交,标记或树)更新 之前给定路径的索引 更新工作树。
换句话说,由于您没有切换分支,工作目录不会反映HEAD指针的任何更改,但会显示属于tree-ish的文件,在这种情况下它是HEAD ^
事物/ dir2仍留在光盘上的原因是它仍然属于当前的HEAD(记住,HEAD没有被移动)并且树中没有任何信息从三个中缺失(在此case thing / dir2)。所以实际上你有东西/ dir1签出来反映HEAD ^ hash的状态以及disc上的thing / dir2,因为它属于HEAD。