让Git跟踪重命名和编辑的文件
问题的原因是git默认会在每次提交时检查文件的重命名,无需手动告知。但是,如果使用git mv命令移动文件,git会忽略这个提示。为了性能考虑,git的启发式算法并不会一直运行,如果将文件移动到其他位置,然后再添加一个同名的新文件,移动操作可能就无法被检测到。需要注意的是,从逻辑上讲,git只存储每个版本中树的状态,不会存储关于版本之间更改的跟踪信息。
解决方法是,如果想要查看检测到的重命名,可以在git diff命令中使用-M (--find-renames)选项来显示重命名。这个选项也会启用启发式算法,对于无法触发启发式算法的提交非常有用。基于启发式算法的方法也是保持提交小而自包含的一个很好的理由。
所以,为了让git能够正确地跟踪重命名和编辑的文件,我们可以使用git mv命令来移动文件,而不是手动删除和添加。另外,在提交时保持小而自包含的提交也能够帮助git更容易地进行跟踪。
问题的原因是Git在存储库中实际上并不跟踪重命名,而是使用差异启发式算法来确定是否将文件重命名为另一个文件。也就是说,如果您使用git mv
命令重命名文件,然后完全更改其内容,Git不会将其视为重命名,并且您不需要使用git mv
命令来检测重命名。
解决方法是使用git diff
命令的--find-renames
选项来找到重命名的文件。以下是示例:
首先,执行以下命令将文件d.txt
重命名为e.txt
:
% 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
选项来查看重命名:
% git diff --summary --find-renames HEAD~1 HEAD rename d.txt => e.txt (100%)
类似地,使用git mv
命令重命名文件e.txt
为f.txt
:
% git mv e.txt f.txt % echo "Completely replacing f.txt" > f.txt % git add f.txt % git commit -m"git mv doesn't help here" [master 068d19c] git mv doesn't help here 2 files changed, 1 insertion(+), 14 deletions(-) delete mode 100644 e.txt create mode 100644 f.txt
然后,再次使用git diff
命令的--summary
和--find-renames
选项来查看重命名:
% git diff --summary --find-renames HEAD~1 HEAD delete mode 100644 e.txt create mode 100644 f.txt
通过使用git diff
命令的--find-renames
选项,可以在Git中检测到重命名和编辑的文件。