让Git关注重命名和编辑的文件

时间:2012-10-08 15:52:31

标签: git version-control git-merge file-rename

以前在Git have been asked中重命名文件的问题,但我无法解决我的具体问题。

我已经移动并编辑了多个文件(我没有使用git mv - 不幸的是,现在已经太晚了)。现在我想要它,所以当我的同事从我的存储库中取出时,对这些相同的文件进行了自己的编辑(没有移动它们),它成功地将我的更改与他在文件的新位置中合并。为了成功合并,Git显然需要知道这些文件是相同的。

Git是否足够聪明地独自完成这项工作?似乎很难相信。如果是这样,我怎么能确定Git会选择一个特定的文件移动 - 即使内容已经改变了?

3 个答案:

答案 0 :(得分:18)

Git实际上并不跟踪存储库中的重命名,而是使用diff启发式来确定是否将文件重命名为另一个文件。也就是说,如果你git mv一个文件然后完全替换内容,那么它被认为是重命名,你需要使用{ {1}}检测重命名。

例如:

git mv

同样,% mv d.txt e.txt % git rm d.txt rm 'd.txt' % git add e.txt % git commit -m"rename without git mv" [master f70ae76] rename without git mv 1 file changed, 0 insertions(+), 0 deletions(-) rename d.txt => e.txt (100%) % git diff --summary --find-renames HEAD~1 HEAD rename d.txt => e.txt (100%) 并不意味着文件将被重命名,它仍然会使用diff算法:

git mv

答案 1 :(得分:8)

默认情况下,只要在提交之间删除文件,git就会检查重命名 - 无需手动告诉它。如果您确实移动了一个文件(使用git mv,而不是手动删除它并再次添加它),它会忽略该提示。出于性能原因,启发式算法不会一直运行 - 如果您移动文件然后添加一个原始名称的新文件,则可能无法检测到移动。

请注意,从逻辑上讲,git只存储每个修订版本中存在的树:它不会存储有关版本之间所做更改的任何跟踪信息。

如果您想查看检测到的内容,可以使用-M--find-renames)切换到git diff来显示重命名。此开关还会打开启发式,如果您有一个不会触发它们的提交,这很有用。

这种基于启发式的方法是一个很好的理由(如果你需要另一个)来保持小而自包含的提交,因为这使得git的工作更容易。

答案 2 :(得分:1)

git diff没有提到我已重命名文件更改了其内容。我的情况是我有文件A,B,C,并插入了一个新的B,所以旧B现在是C,旧C现在是D. git diff告诉我B和C现在完全不同了!

我使用的解决方案既乏味又手动,但确实完成了工作。

  1. 尽我所能重新命名文件。即B到Bnew,C到B,D到C。
  2. 做差异,检查没有错误。
  3. 承诺。
  4. 使用git mv将文件命名为新名称。 B至C,C至D.
  5. 承诺。
  6. 对方是否重命名,并将其作为新文件提交。即告诉B。