我有一个我不想再跟踪的目录。我甚至想删除该目录中的一些文件,而不会影响git。意味着我想删除文件并且没有git状态来显示要提交的更改,以避免来自另一台机器的git pull最终会删除文件。
我已经尝试过选项:
git rm --cached directory/
但是在我从另一台机器上执行git pull之后,最终删除了文件。
也尝试过:
git update-index --assume-unchanged directory/
但删除目录后,我仍然在git状态下获得输出,说明该目录已被删除。我甚至将该目录添加到.gitignore文件中。
如Stop tracking a file in git - without having it deleted either locally or on pull下的答案中所述,是否真的无法执行此类操作?
答案 0 :(得分:1)
简短的回答是"它不可能"。
问题不仅限于(实际上与目录无关)目录。这是因为该目录中的文件确实已被删除。 (这里也值得注意的是,Git根本不跟踪目录,它只是在需要包含文件时创建它们。)
为了完整性,我们选择一个实际的文件名。称之为conf/config.ini
。您克隆了一些存储库,并在其中有一个名为conf/config.ini
的文件,位于提交badc0ff
中,这是分支master
的提示。您的Git会检查此提交,因此您的Git会在您的工作树中尽职地创建目录conf
和该目录中名为config.ini
的文件。
现在命令您的Git获取更多修订版本(git fetch
)。 badc0ff
之后有一个新版本,即123face
。您的origin/master
现在名称提交123face
。
接下来,您命令Git将更改从badc0ff
集成到123face
(使用git merge origin/master
或类似)。有什么变化?好吧,除了其他任何事情,有人已删除 conf/config.ini
。所以你的Git删除了conf/config.ini
。
(注意:您可能正在通过运行git pull
来执行这两个Git命令。在这种情况下,所有git pull
都会运行git fetch
然后运行git merge
,所以你真的 使用这两个其他命令。它是从badc0ff
到123face
的合并步骤,获取并遵守上游指示的更改 - 删除文件;并删除文件,因为文件确实已删除。这是从一次提交到下一次提交所需的内容。)
这里缺少什么 - 从未被认为是一个重要的设计功能 - 是告诉Git的一种方式:"尽管您可以执行从提交 X 到提交的转换删除路径 P 的 Y ,请不要从工作树中删除路径 P - 仅将其从索引中删除。 "
由于缺少这个,你需要一个解决方法......而且它非常简单。只需再次检查上一次提交并保存文件 - 或者等效地从上一次提交中提取文件而不检查它:
$ git show HEAD@{1}:conf/config.ini > conf/config.ini
(这里的HEAD@{1}
语法来自gitrevisions,意思是"提交HEAD
指向我们之前通过遵守上游的变化来改变它#34;)
(如果有很多这样的文件,就像你的情况一样,git checkout
之前的提交可能更方便,即告诉你的Git"回到过去&#34 ;一步,然后重命名整个目录 - 完整文件,并及时返回到现在。然后你可以重命名目录。)
假设您的conf/config.ini
您的 Git坐在提交badc0ff
上,与实际中的不完全相同提交badc0ff
。也就是说,您已修改了配置。
如果您现在运行git merge
(正如git pull
那样)来合并来自123face
的更改,您的Git会告诉您否:它无法执行此操作。原因是你的工作树不干净&#34 ;;您对自己未提交的已跟踪,已提交文件进行了更改。您的Git必须删除该文件,这将丢失您的更改。所以这种情况不应该首先发生。要进行合并,您应该提交更改。让我们说你做了,结果你得到了提交fedbeef
。
提交更改后,您就可以合并了。你会得到一个"合并冲突"合并他们的"删除文件"使用您的"我更改了文件",您可以通过删除文件来解决该合并冲突。这将使您获得正确的最终状态(文件已消失,但如果您创建它,它将被取消跟踪)。然后,您只需从提交中提取已提交的版本:
git show fedbeef:conf/config.ini > conf/config.ini
一切都很好。