commit c3ee8dfb01e357eba1ab18003be1490a46325992
Author: John S. Gruber <JohnSGruber@gmail.com>
Date: Wed Feb 22 22:20:19 2017 -0500
test rename again
diff --git a/yyy/power.py b/zzz/power.py
similarity index 100%
rename from yyy/power.py
rename to zzz/power.py
commit ae181377154eca800832087500c258a20c95d1c3
Author: John S. Gruber <JohnSGruber@gmail.com>
Date: Wed Feb 22 22:19:17 2017 -0500
rename test
diff --git a/power.py b/yyy/power.py
similarity index 100%
rename from power.py
rename to yyy/power.py
请注意,无论何时使用diff,这都有效,而不仅仅是 git log . 例如:
$ git diff HEAD c3ee8df
diff --git a/power.py b/zzz/power.py
similarity index 100%
rename from power.py
rename to zzz/power.py
$ git merge -v master
Auto-merging single
Merge made by the 'recursive' strategy.
one => single | 4 ++++
1 file changed, 4 insertions(+)
rename one => single (67%)
9 回答
我移动文件,然后做
将所有删除/新文件放入sataging区域 . 这里git意识到文件被移动了 .
我不知道为什么但这对我有用 .
Git检测重命名而不是使用提交持久化操作,因此无论使用
git mv
还是mv
无关紧要 .log
命令采用--follow
参数,该参数在重命名操作之前继续历史记录,即,它使用启发式方法搜索类似的内容:http://git-scm.com/docs/git-log
要查找完整历史记录,请使用以下命令:
虽然可以在整个存储库历史记录中重命名文件,但可以重命名文件并保持历史记录不变 . 这可能只适用于痴迷的git-log爱好者,并且有一些严重的影响,包括:
你可能正在重写一个共享历史记录,这是最重要的事情,这样做会打破它 . 他们将不得不重新克隆以避免头痛 . 如果重命名非常重要,这可能没问题,但是您需要仔细考虑这一点 - 最终可能会破坏整个开源社区!
如果您在存储库历史记录中早先使用了've referenced the file using it'的旧名称,那么're effectively breaking earlier versions. To remedy this, you'将不得不做更多的跳跃 . 这不是不可能的,只是单调乏味,可能不值得 .
现在,因为你're still with me, you'可能是个人开发者重命名完全隔离的文件 . 让我们使用
filter-tree
移动文件!假设您要将文件
old
移动到文件夹dir
并将其命名为new
这可以通过
git mv old dir/new && git add -u dir/new
完成,但这打破了历史 .代替:
将重做分支中的每个提交,在每次迭代的ticks中执行命令 . 当你这样做时,很多东西都可能出错 . 我通常会测试文件是否存在(否则它还没有移动)然后执行必要的步骤来按照自己的喜好对树进行修剪 . 在这里,您可以通过文件来修改对文件的引用,等等 . 把自己打昏! :)
完成后,文件将被移动并且日志完好无损 . 你觉得自己像个忍者海盗 .
也;只有将文件移动到新文件夹时才需要mkdir目录 . if将避免在历史记录中早于文件存在而创建此文件夹 .
号
简短的回答是 NO ,无法在Git中重命名文件并记住历史记录 . 这是一种痛苦 .
有传言说
git log --follow
--find-copies-harder会起作用但它对我不起作用,即使文件内容没有变化,并且已经用git mv进行了移动 .(最初我使用Eclipse在一个操作中重命名和更新包,这可能让git感到困惑 . 但这是非常常见的事情 . 如果只执行
mv
然后commit
和mv
不是,那么--follow
似乎确实有效太远 . )Linus说,您应该全面了解软件项目的全部内容,而不需要跟踪单个文件 . 好吧,可悲的是,我的小脑子不能这样做 .
很多人都盲目地重复了git自动跟踪动作的说法,这是 really annoying . 他们浪费了我的时间 . Git没有这样的事情 . By design(!) Git does not track moves at all.
我的解决方案是将文件重命名回原始位置 . 更改软件以适合源控件 . 使用git,你似乎需要第一次正确使用git .
不幸的是,这破坏了Eclipse,它似乎使用
--follow
.git log --follow有时不会显示具有复杂重命名历史的文件的完整历史记录,即使
git log
也是如此 . (我不知道为什么 . )(有一些太聪明的黑客可以追溯并重新开始做旧工作,但它们相当令人恐惧 . 请参阅GitHub-Gist:emiller/git-mv-with-history . )
将通过重命名向您显示历史记录 .
我做:
目标
使用git am(灵感来自Smar,借鉴Exherbo)
添加复制/移动文件的提交历史记录
从一个目录到另一个目录
或从一个存储库到另一个存储库
限制
不保留标签和分支
历史记录被剪切在路径文件重命名(目录重命名)
摘要
使用以电子邮件格式提取历史记录
git log --pretty=email -p --reverse --full-index --binary
重新组织文件树并更新文件名
使用添加新历史记录
cat extracted-history | git am --committer-date-is-author-date
1.以电子邮件格式提取历史记录
示例:提取
file3
,file4
和file5
的历史记录设置/清除目的地
以电子邮件格式提取每个文件的历史记录
不幸的是,选项
--follow
或--find-copies-harder
不能与--reverse
结合使用 . 这就是重命名文件时(或重命名父目录时)切断历史记录的原因 .电子邮件格式的临时历史记录:
Dan Bonachea建议在第一步中反转git log generation命令的循环:不是每个文件运行一次git log,而是在命令行上使用一个文件列表运行一次,并生成一个统一的日志 . 这种方式提交修改多个文件仍然是结果中的单个提交,并且所有新提交都保持其原始相对顺序 . 请注意,在(现在统一)日志中重写文件名时,还需要在下面的第二步中进行更改 .
2.重新组织文件树并更新文件名
假设您要在这个其他仓库中移动这三个文件(可以是相同的仓库) .
因此,重新组织您的文件:
您的临时历史现在是:
更改历史记录中的文件名:
3.应用新历史记录
你的另一个回购是:
从临时历史文件中应用提交:
--committer-date-is-author-date
保留原始提交时间戳(Dan Bonachea的评论) .你的其他回购现在是:
使用
git status
查看准备推送的提交量:-)额外技巧:检查您的仓库中重命名/移动的文件
列出已重命名的文件:
更多自定义:您可以使用选项
--find-copies-harder
或--reverse
完成命令git log
. 您还可以使用cut -f3-
和grepping完整模式'{.* => .*}'删除前两列 .不(8年后,Git 2.19,Q8 2018),因为Git将会 detect the directory rename ,现在这个记录更好了 .
请参见commit b00bf1c,commit 1634688,commit 0661e49,commit 4d34dff,commit 983f464,commit c840e1a,commit 9929430(2018年6月27日)和commit d4e8062,commit 5dacd4a(2018年6月25日)Elijah Newren (newren) .
(由Junio C Hamano合并 - gitster - 提交0ce5a69,2018年7月24日)
现在在_821652中解释了这个问题:
例:
但它们还有很多其他情况,例如:
为简化目录重命名检测,这些规则由Git强制执行:
当目录重命名检测适用时,一些基本规则限制:
您可以在t/t6043-merge-rename-directories.sh中看到很多测试,这也指出:
虽然git的核心是git管道没有跟踪重命名,但是如果你愿意的话,使用git log“porcelain”显示的历史可以检测到它们 .
对于给定的
git log
,请使用-M选项:使用当前版本的git .
这适用于其他命令,如
git diff
.有一些选项可以使比较或多或少严格 . 如果重命名文件而不同时对文件进行重大更改,则git日志和朋友可以更轻松地检测重命名 . 出于这个原因,有些人在一次提交中重命名文件,在另一次提交中更改它们 .
每当你要求git找到重命名文件的位置时,使用cpu就会有成本,所以无论你是否使用它,以及什么时候取决于你 .
如果您希望始终在特定存储库中使用重命名检测报告您的历史记录,则可以使用:
检测到从一个目录移动到另一个目录的文件 . 这是一个例子:
请注意,无论何时使用diff,这都有效,而不仅仅是
git log
. 例如:作为试验,我在功能分支中的一个文件中做了一个小的更改并提交了它,然后在主分支中我重命名了文件,提交了,然后在文件的另一部分做了一个小的更改并提交了 . 当我进入功能分支并从主服务器合并时,合并重命名了该文件并合并了更改 . 这是合并的输出:
结果是一个工作目录,文件重命名和两个文本更改 . 因此git可以做正确的事情,尽管它没有明确跟踪重命名 .
这是对旧问题的迟到答案,因此其他答案可能对于当时的git版本是正确的 .