如果文件的名称和内容已更改,是否可以在提交发生后标记移动?
例如
file1.txt
更改为file2.txt
和内容更改。git commit
- Git 认为
file1.txt
已被删除,file2.txt
是一个不相关的新文件。
有没有办法在提交发生后将其标记为重命名?
如果文件的名称和内容已更改,是否可以在提交发生后标记移动?
例如
file1.txt
更改为file2.txt
和内容更改。git commit
file1.txt
已被删除,file2.txt
是一个不相关的新文件。有没有办法在提交发生后将其标记为重命名?
不,不是,因为 Git 不进行重命名跟踪……但它确实进行了重命名检测
(基于文件的内容和名称的相似程度)。
这意味着
git log --follow file2.txt
将通过重命名来跟踪文件历史记录(注意:不幸的是,这并不总是能正常工作,就像--follow
一些黑客攻击一样),git blame -C -C file2.txt
将在文件重命名、内容复制和跨文件和内部文件移动时遵循逐行文件历史记录git show -C
将显示有文件重命名(您可以将 Git 配置为在显示差异时始终进行重命名,甚至可以选择进行复制检测)。高温高压
正如您所发现的,git 不会检测到真正重大更改和同时移动的组合作为重命名。
要理解的是,每次查看历史记录时,git 都会通过将提交的内容与其父提交进行比较来检测提交中的更改。这可能看起来太简单了,但事实证明这是一种简单的好方法。
所以你需要插入一个新的提交,一个 git log 等可以检测到的重命名,然后是你从那时起积累的其余历史,这意味着你的分支的新历史,即 rebase 或cherry -挑选。
所以:
# make a new history with a rename that can be detected by comparing commits
# check out the glitched commit's ancestor by its sha,
# this work won't take enough time to bother inventing a transient name for it
git checkout commit-before-rename+bigchange
git mv file1.txt file2.txt
git commit
git checkout commit-with-rename+bigchange -- file2.txt
git commit
# Now add the rest of the changes, also detectable by comparing commits,
# by re-applying them on top of this new history:
git cherry-pick commit-before-rename+bigchange..branch-it\'s-on
# and force the old branch name to refer to this new history you just made
# the old history will be garbage-collected after 90 days or so if
# it's not part of the history of any other references
git checkout -B branch-it\'s-on
你已经完成了,除非任何其他存储库通过 fetch 或 push 或 clone 获取了混乱的历史记录,那么你将不得不强制推送或让那些 repo 的所有者强制重新获取(以及他们的任何后续历史记录)已经建立在此之上,这就是为什么你真的不想太早发布)。
不,那里没有。Git 没有任何文件标识的概念。它存储目录树的内容。只有整个树才有历史的概念。
跟踪文件被重命名而不是删除旧文件和添加新文件的原因只有一个,那就是允许合并该文件中的更改。由于您更改了文件(超出了重命名检测认为相似的内容),因此无论如何都没有机会在没有冲突的情况下合并更改,因此应该没有实际区别。
请注意,Git 确实通过搜索类似文件来处理合并原因。它会git status
在所有合并中自动执行此操作,并且git log
如果git diff
您要求,其他命令会显示更改。如果它没有找到重命名,则不太可能进行合并。