git rebase没有改变提交时间戳
在保留提交时间戳的同时执行git rebase
是否有意义?
我相信一个后果就是新的分支不一定会按时间顺序提交date。 这在理论上是可能的吗? (例如使用pipe道命令;只是在这里好奇)
如果这在理论上是可行的,那么在实践中是否可以使用rebase,而不是改变时间戳?
例如,假设我有以下树:
master <jun 2010> | : : : oldbranch <feb 1984> : / oldcommit <jan 1984>
现在,如果我在master
oldbranch
,提交的date从1984年2月更改为2010年6月。是否可以更改该行为,以便提交时间戳不被更改? 最后我会得到:
oldbranch <feb 1984> / master <jun 2010> | :
那有意义吗? 它甚至允许在git中有一个旧的提交具有更近的提交作为父母的历史?
如果你已经搞砸了提交date(可能是用rebase)并且想把它们重置为相应的作者date,你可以运行:
git filter-branch --env-filter 'GIT_COMMITTER_DATE=$GIT_AUTHOR_DATE; export GIT_COMMITTER_DATE'
2014年6月更新: David Fraser 在评论中提到了一个解决scheme,该解决scheme在“更新时间戳,同时重新设定git分支 ”中也有详细说明,使用选项--committer-date-is-author-date
(最初于2009年1月在commit 3f01ad6
注意
--committer-date-is-author-date
选项似乎留下了作者时间戳,并将提交者时间戳设置为与原作者时间戳相同,这是OP Olivier Verdier所需要的。我发现最后一次提交的date是正确的:
git rebase --committer-date-is-author-date SHA
请参阅git am
:
--committer-date-is-author-date
默认情况下,命令将来自电子邮件的datelogging为落实作者date,并使用提交创build时间作为提交者date。
这允许用户通过使用与作者date相同的值来说谎提交者date 。
(原文,2012年6月)
你可以尝试,为一个非交互式的 rebase
git rebase --ignore-date
(从这个答案 )
这是传给git am
,里面提到:
--ignore-date
默认情况下,命令将来自电子邮件的datelogging为落实作者date,并使用提交创build时间作为提交者date。
这允许用户通过使用与提交者date相同的值来说谎作者date。
对于git rebase
,这个选项是“与-interactive选项不兼容”。
既然你可以随意更改旧提交date (使用git filter-branch
) 的时间戳 ,我想你可以用你想要/需要的任何提交date顺序来组织你的Git历史logging,甚至将它设置为未来! 。
正如奥利维尔在他的提问中提到的那样, 作者的date永远不会被改变;
从Pro Git Book :
- 作者是原本写作的人,
- 而提交者是最后一个应用工作的人。
所以,如果你给一个项目打补丁,而其中一个核心成员应用这个补丁,那么你们都得到了信任。
在这种情况下,如奥利维尔所言:
--ignore-date
与我试图达到的目的相反 !
也就是说,它会删除作者的时间戳,并用提交时间戳replace它们!
所以我的问题的正确答案是:
不要做任何事情,因为默认情况下,git rebase
确实不会改变作者的时间戳。
冯·C的一个关键问题帮助我理解了发生了什么事情:当你的基金会, 提交者的时间戳发生变化,而不是作者的时间戳,这一切都是有道理的。 所以我的问题其实不够精确。
答案是rebase实际上不会改变作者的时间戳(你不需要做任何事情),这完全适合我。
默认情况下,git rebase会将提交者的时间戳设置为创build新提交的时间,但保持作者的时间戳完好无损。 大多数情况下,这是期望的行为,但在某些情况下,我们不希望更改提交者的时间戳。 我们怎样才能做到这一点? 那么,这是我通常所做的诀窍。
首先,确保你要提交的每个提交都有一个唯一的提交信息(这就是技巧需要改进的地方,目前它虽然适合我的需求)。
在rebase之前,logging提交者的时间戳和提交所有提交的提交信息,这些提交将被重新发布到一个文件中。
#NOTE: BASE is the commit where your rebase begins git log --pretty='%ct %s' BASE..HEAD > hashlog
然后,让实际rebase发生。
最后,如果通过使用git filter-branch
提交消息是相同的,我们用当前提交者的时间戳replace文件中logging的时间戳。
git filter-branch --env-filter '__date=$(__log=$(git log -1 --pretty="%s" $GIT_COMMIT); grep -m 1 "$__log" ../../hashlog | cut -d" " -f1); test -n "$__date" && export GIT_COMMITTER_DATE=$__date || cat'
如果出现问题,只需签出git reflog
或所有的refs/original/
refs。
还有,你可以做类似的事情作者的时间戳。
例如,如果作者的某些提交的时间戳不符合要求,并且不重新排列这些提交,我们只是希望作者的时间戳按顺序显示,那么以下命令将有所帮助。
git log --pretty='%at %s' COMMIT1..COMMIT2 > hashlog join -1 1 -2 1 <(cat hashlog | cut -f 1 | sort -nr | awk '{ print NR" "$1 }') <(cat hashlog | awk '{ print NR" "$0 }') | cut -d" " -f2,4- > hashlog_ mv hashlog_ hashlog git filter-branch --env-filter '__date=$(__log=$(git log -1 --pretty="%s" $GIT_COMMIT); grep -m 1 "$__log" ../../hashlog | cut -d" " -f1); test -n "$__date" && export GIT_AUTHOR_DATE=$__date || cat'