从另一个分支检出文件夹不会删除文件

10

我正在尝试将一个分支中整个文件夹的内容移动到另一个分支。在新分支中,所有修改或添加的文件都正确反映了出来,但是被删除的文件仍然显示为没有更新。

当我修改TSTGIT文件夹中的一个文件、添加新文件并删除一个现有文件,并提交更改后,从DEV分支检出UAT分支并检出TSTGIT文件夹,我希望看到所有三个更改,但被删除的文件完全被忽略了。

git checkout UAT
git checkout DEV -- TSTGIT
git status

待提交的更改:

    new file:   TSTGIT/addedFile.txt
    modified:   TSTGIT/modifiedFile.txt

我找到的唯一方法是使用“patch”参数,它让我选择删除文件,但我希望自动完成此操作,无需提供其他信息。

git checkout -p DEV -- TSTGIT

请问是否有一种方法可以强制包括所有更改?

非常感谢你的帮助 ;)

2个回答

15
默认情况下,git checkout 只会添加或修改工作目录中的文件,而不会删除它们。这被称为 overlay mode
引用模式:只向工作目录更新和添加文件,但不删除它们,类似于 cp -R 更新目标目录内容的方式,在从索引或树状对象检出文件时,这是默认模式。
在这里,<tree-ish> 是一个引用,指向一个树对象,通常是一个提交。 截至 Git 2.22 版本, 您可以通过传递 --no-overlay 选项到 git checkout 命令来删除工作目录中任何缺失于所引用树中的文件。
当指定 --no-overlay 时,出现在索引和工作树中但不在 <tree-ish> 中的文件会被移除,以使它们与 <tree-ish> 完全匹配。
您的命令应该是:
git checkout --no-overlay DEV -- TSTGIT 

有趣的是,当使用--patch选项时,你能够删除文件的原因是它隐含了--no-overlay
documentation中得知:

请注意,默认情况下,此选项使用无覆盖模式,并且当前不支持覆盖模式。


1
谢谢你,Enrico。这正是我所需要的,但问题在于该参数仅适用于 git 版本 2.22 及更高版本,而我使用的是旧版本,无法升级它 :( - janick
1
@janick 是的,--no-overlay选项是在2.22版本中添加的。如果您无法升级,那么运行“无覆盖”检出的唯一方法就是使用--patch选项,就像您目前正在做的那样。 - Enrico Campidoglio

2
使用git checkout DEV -- TSTGIT命令的问题在于该命令会复制文件而不是应用更改;而复制的文件肯定不包括已删除的文件。
如果要同步目录——即使其成为另一个分支目录的精确副本,您可以在从另一个分支签出之前删除该目录:
git checkout UAT
rm -rf TSTGIT
git checkout DEV -- TSTGIT

这种方法的问题在于它会删除在分支DEV中存在但从未存在(也未被删除)于UAT中的文件。

如果你想应用更改而不删除目录,那么类似于git checkout -p的方法是唯一的途径。可以使用git cherry-pick --no-commit;但之后你必须恢复除了TSTGIT之外的所有目录。

“Original Answer”翻译成“最初的回答”


谢谢。这对我很有用。只是出于好奇,您知道是否可以非交互式地使用--patch参数 - 这意味着我将应用它来处理所有更改(类似于--patch-all)吗? - janick
我能想到的唯一方法是 yes | git checkout --patch。程序 /usr/bin/yes 只会永远输出 y - phd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接