在以前版本的检出目录中的子目录没有在Git中消失?

时间:2011-05-02 16:52:38

标签: git version-control dvcs git-checkout

我正在尝试使用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/

这使我的工作树和索引处于一种奇怪的状态,但具有所需的效果。

2 个答案:

答案 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。