hg addremove in git

29

我真的需要在git中使用这个命令

hg addremove

现在看看场景,看看Mercurial如何帮我解决这个问题:

我在这里有一个var/htdocs/static/static目录。 我无意中将文件移动到错误的位置(使用git-mv)。 无论如何...现在我手动移动了一些文件夹:

mv static static2
mv static2/static ./

也许我在这里改变了一些文件...现在一切都很好...所以现在git不知道发生了什么?如果没有像addremove那样通知它,它如何跟踪文件的移动。

例如,现在我可以用mercurial做到:

hg addremove --similarity 80%

就这样 - Mercurial通过识别文件内容来追踪文件的移动,并保存了我的文件历史记录。

这里的一个人提供了一些技巧:这里

git add .
git ls-files --deleted | xargs git rm

但这就像当时的CVS一样。你删除文件,你添加文件。那么如何保存文件的历史记录?

3个回答

27

实际上,当 Git 应用提交以更新工作树时,它总是会自动执行类似于“addremove”的操作:它会查看提交中添加和删除的文件,并检测可能是重命名的已添加和已删除文件对(使用“更改量”启发式)。所以你不需要使用特殊命令;只需进行添加和删除操作,Git 会在之后自己解决问题。

在你的示例场景中,只需告诉 Git 新建了哪些文件:git add static,并告诉它删除了哪些文件:git add -u static,然后就可以提交了。如果在提交之前执行 git status 命令,你会看到它已经检测出了重命名。

[正如另一篇答案提到的那样,git add -A 是一个很好的快捷方式,它只添加工作树中的所有内容,包括新建和删除的文件;使用上面较为狭窄的命令的唯一原因是想要避免添加一些恰好在工作树中的其他更改。]


1
终于有人通俗易懂地解释了这个问题 =) 谢谢。我认为很多用户都有这个疑问.. 没有人说过这些事情是在幕后进行的.. - holms
顺便提一下,如果你没有其他更改(我更新了我的答案以包括这个),"git add -A"是一个不错的快捷方式。 - snogglethorpe
我相当确定Git在提交时不会进行重命名检测,而是在提交后进行分析,正如Charles Bailey所提到的(https://dev59.com/qmsz5IYBdhLWcg3wQFe2#cCkCoYgBc1ULPQZFnS4W)。 - Max Nanasy
@MaxNanasy 您是正确的,但您似乎误解了我的意思(或者至少是我试图表达的意思)。我没有说git进行“提交时间”重命名检测,我说的是“git在将提交应用于工作树时检测重命名”,也就是“事后”。我认为我的措辞在技术上有点笨拙,因为git实际上并没有“应用提交”;我稍后会尝试修正措辞,使其更加精确。 - snogglethorpe

10

Git不通过额外的元数据来跟踪重命名,因此您可以放心地使用git add -A,并确信您没有丢失任何元数据。

虽然Git跟踪的是“整个树”历史记录而不是文件历史记录,但您可以通过像git log -M -Cgit log --follow <file>这样的命令在事后启用其重命名和复制检测功能。


1
抱歉,今天我有点笨,请问你能否编辑一下我应该输入的命令,以实现我的场景?我有五个命令,而不是一个(就像在hg中),这让我非常困惑,所以我想请你编辑一下你的帖子,包括所有引用的命令。 - holms
@holms:如果你的意思是hg addremove的等效操作,那么就像我说的一样,使用git add -A。Git在添加文件时不关心重命名,所以--similarity对于从hggit的转换是无关紧要的。 - CB Bailey
@holms: 注意 git add -A 还会将对已跟踪文件的更改提交到暂存区。我不确定 hg addremove 是否具有此效果。 - CB Bailey
所以你是在告诉我git add -A可以追踪重命名,并且所有文件的历史记录都将被保存?=) - holms
@holms:我的意思是,git并不明确地跟踪重命名,无论您如何添加或删除文件,它都不重要。任何重命名检测都是事后发生的。 - CB Bailey
@Charles Bailey:hg 不会“暂存”。 - moi

8

简短回答:在Git中与hg addremove最相似的命令是:

git add -A

Oooorr...

git add --all

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