是不是可以停止跟踪git中的目录并在本地删除它,确保它会在从另一台机器上拉出git之后重新发送?

时间:2017-04-18 23:24:38

标签: git gitignore

我有一个我不想再跟踪的目录。我甚至想删除该目录中的一些文件,而不会影响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下的答案中所述,是否真的无法执行此类操作?

1 个答案:

答案 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,所以你真的 使用这两个其他命令。它是从badc0ff123face的合并步骤,获取并遵守上游指示的更改 - 删除文件;并删除文件,因为文件确实已删除。这是从一次提交到下一次提交所需的内容。)

该怎么做

这里缺少什么 - 从未被认为是一个重要的设计功能 - 是告诉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

一切都很好。