在保留提交时间戳的同时执行git rebase
是否有意义?
我认为结果是新分支不一定按时间顺序排列日期。那理论上可能吗? (例如使用管道命令;这里很好奇)
如果理论上可行,那么在实践中是否可以使用rebase,而不是更改时间戳?
例如,假设我有以下树:
master <jun 2010>
|
:
:
: oldbranch <feb 1984>
: /
oldcommit <jan 1984>
现在,如果我在oldbranch
上重新定义master
,则提交日期将从1984年2月更改为2010年6月。是否可以更改该行为以便不更改提交时间戳?最后我会得到:
oldbranch <feb 1984>
/
master <jun 2010>
|
:
这有意义吗?甚至在git中是否允许有一个旧提交最近提交作为父项的历史记录?
答案 0 :(得分:127)
2014年6月更新:David Fraser使用选项--committer-date-is-author-date
(最初于2009年1月在{{3中引入)中提及“in the comments”中详述的解决方案Change timestamps while rebasing git branch }}
请注意,
--committer-date-is-author-date
选项似乎保留了作者的时间戳,并将提交者时间戳设置为与原始作者时间戳相同,这是commit 3f01ad6所需的。我发现最后一次提交的日期正确,并且确实:
git rebase --committer-date-is-author-date SHA
--committer-date-is-author-date
默认情况下,该命令将电子邮件中的日期记录为提交作者日期,并将提交创建时间用作提交者日期。
这允许用户使用与作者日期相同的值来说谎提交者日期。
(原始答案,2012年6月)
您可以尝试使用非交互式 rebase
git rebase --ignore-date
(来自此git am
)
这传递给SO answer,提及:
--ignore-date
默认情况下,该命令将电子邮件中的日期记录为提交作者日期,并将提交创建时间用作提交者日期。
这允许用户使用与提交者日期相同的值来说谎作者日期。
对于git am
,此选项为“与--interactive选项不兼容。”
自git rebase
(带you can change at will the timestamp of old commit date)以来,我认为您可以使用您想要/需要的任何提交日期顺序来组织您的Git历史记录,甚至是git filter-branch
。
正如set it to the future!在他的问题中提到的那样,作者日期永远不会被rebase改变;
来自Olivier:
- 作者是最初撰写作品的人,
- 而提交者是最后一次申请工作的人。
因此,如果您向项目发送补丁并且其中一个核心成员应用了补丁,那么您都会获得信誉。
要明确,在这种情况下,正如奥利维尔的评论:
--ignore-date
与我想要实现的目标相反!
也就是说,它会删除作者的时间戳并将其替换为提交时间戳! 所以我的问题的正确答案是:
不要做任何事情,因为git rebase
实际上并没有默认改变作者的时间戳。
答案 1 :(得分:113)
如果您已经搞砸了提交日期(可能带有rebase)并希望将它们重置为相应的作者日期,则可以运行:
git filter-branch --env-filter 'GIT_COMMITTER_DATE=$GIT_AUTHOR_DATE; export GIT_COMMITTER_DATE'
答案 2 :(得分:30)
关于Von C的一个关键问题帮助我理解了发生了什么:当您的rebase,提交者的时间戳发生变化时,而不是作者的时间戳,这突然之间感。所以我的问题实际上不够精确。
答案是,rebase实际上并没有改变作者的时间戳(你不需要做任何事情),这完全适合我。
答案 3 :(得分:13)
默认情况下,git rebase会将提交者的时间戳设置为时间戳 创建了新提交,但保持作者的时间戳保持不变。大部分时间, 这是期望的行为,但在某些情况下,我们不希望改变 提交者的时间戳也是。我们怎样才能做到这一点?好吧,这是 我经常做的伎俩。
首先,确保您要进行rebase的每个提交都具有唯一性 提交消息和作者时间戳(这是技巧需要改进的地方,但目前它适合我的需要)。
在rebase之前,记录提交者的时间戳,作者的时间戳以及将被重新绑定到文件的所有提交的提交消息。
#NOTE: BASE is the commit where your rebase begins
git log --pretty='%ct %at %s' BASE..HEAD > hashlog
然后,让实际的rebase发生。
最后,如果使用git filter-branch
提交消息相同,我们将当前提交者的时间戳替换为文件中记录的时间戳。
git filter-branch --env-filter '__date=$(__log=$(git log -1 --pretty="%at %s" $GIT_COMMIT); grep -m 1 "$__log" ../../hashlog | cut -d" " -f1); test -n "$__date" && export GIT_COMMITTER_DATE=$__date || cat'
如果出现问题,只需检查git reflog
或所有refs/original/
参考号。
更进一步,你可以对作者的时间戳做类似的事情。
例如,如果作者的某些提交的时间戳不正常,那么 如果没有重新排列这些提交,我们只想让作者的时间戳显示出来 顺序,然后以下命令将有所帮助。
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'