以前在Git have been asked中重命名文件的问题,但我无法解决我的具体问题。
我已经移动并编辑了多个文件(我没有使用git mv
- 不幸的是,现在已经太晚了)。现在我想要它,所以当我的同事从我的存储库中取出时,对这些相同的文件进行了自己的编辑(没有移动它们),它成功地将我的更改与他在文件的新位置中合并。为了成功合并,Git显然需要知道这些文件是相同的。
Git是否足够聪明地独自完成这项工作?似乎很难相信。如果是这样,我怎么能确定Git会选择一个特定的文件移动 - 即使内容已经改变了?
答案 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现在完全不同了!
我使用的解决方案既乏味又手动,但确实完成了工作。
git mv
将文件命名为新名称。 B至C,C至D.