Oli*_*ier 144 git timestamp git-rebase
git rebase
在保留提交时间戳的同时执行是否有意义?
我相信结果是新分支不一定按时间顺序排列日期.这在理论上是否可行?(例如使用管道命令;只是好奇这里)
如果理论上可行,那么在实践中是否可以使用rebase,而不是更改时间戳?
例如,假设我有以下树:
master <jun 2010>
|
:
:
: oldbranch <feb 1984>
: /
oldcommit <jan 1984>
Run Code Online (Sandbox Code Playgroud)
现在,如果我重新oldbranch
启动master
,则提交日期将从1984年2月更改为2010年6月.是否可以更改该行为以便不更改提交时间戳?最后我会得到:
oldbranch <feb 1984>
/
master <jun 2010>
|
:
Run Code Online (Sandbox Code Playgroud)
那会有意义吗?甚至允许在git中有一个旧提交最近提交作为父项的历史记录?
Von*_*onC 138
2014年6月更新:David Fraser 在评论中提到了一个解决方案,该解决方案也在" 更改时间戳同时重新定位git分支 "中详细说明,使用该选项--committer-date-is-author-date
(最初于2009年1月在提交3f01ad6中介绍)
请注意,该
--committer-date-is-author-date
选项似乎保留了作者的时间戳,并将提交者时间戳设置为与原始作者时间戳相同,这是OP Olivier Verdier所需要的.我找到了最后一次提交正确的日期,并做了:
git rebase --committer-date-is-author-date SHA
Run Code Online (Sandbox Code Playgroud)
见git am
:
--committer-date-is-author-date
Run Code Online (Sandbox Code Playgroud)
默认情况下,该命令将电子邮件中的日期记录为提交作者日期,并使用提交创建时间作为提交者日期.
这允许用户使用与作者日期相同的值来说谎提交者日期.
(原始答案,2012年6月)
对于非交互式 rebase ,您可以尝试
git rebase --ignore-date
Run Code Online (Sandbox Code Playgroud)
(从这个SO回答)
这被传递给git am
,提到:
--ignore-date
Run Code Online (Sandbox Code Playgroud)
默认情况下,该命令将电子邮件中的日期记录为提交作者日期,并使用提交创建时间作为提交者日期.
这允许用户使用与提交者日期相同的值来欺骗作者日期.
对于git rebase
,此选项是"与--interactive选项不兼容".
既然您可以随意更改旧提交日期(带git filter-branch
)的时间戳,我想您可以使用您想要/需要的任何提交日期顺序组织您的Git历史记录,甚至可以将其设置为将来!.
正如奥利维尔在他的问题中提到的那样,作者的约会从未被改变过;
来自Pro Git Book:
- 作者是最初写作的人,
- 而提交者是最后一次申请工作的人.
因此,如果您向项目发送补丁并且其中一个核心成员应用了补丁,那么您都会得到信任.
更为清楚的是,在这种情况下,正如奥利维尔评论:
与
--ignore-date
我想要达到的目标相反!
也就是说,它会删除作者的时间戳并将其替换为提交时间戳!
所以我的问题的正确答案是:
不要做任何事情,因为git rebase
默认情况下实际上并没有改变作者的时间戳.
And*_*ndy 114
如果您已经搞砸了提交日期(可能带有rebase)并想要将它们重置为相应的作者日期,则可以运行:
git filter-branch --env-filter 'GIT_COMMITTER_DATE=$GIT_AUTHOR_DATE; export GIT_COMMITTER_DATE'
Oli*_*ier 30
关于Von C的一个关键问题帮助我理解了发生了什么:当你的rebase,提交者的时间戳发生变化,而不是作者的时间戳时,这突然变得有意义.所以我的问题实际上不够准确.
答案是,rebase实际上并没有改变作者的时间戳(你不需要为此做任何事情),这完全适合我.
wey*_*amz 14
默认情况下,git rebase会将提交者的时间戳设置为创建新提交的时间,但保持作者的时间戳保持不变.大多数时候,这是期望的行为,但在某些情况下,我们不希望更改提交者的时间戳.我们怎样才能做到这一点?好吧,这是我通常做的伎俩.
首先,确保您要进行rebase的每个提交都有一个唯一的提交消息和作者时间戳(这是技巧需要改进的地方,但目前它适合我的需求).
在rebase之前,记录提交者的时间戳,作者的时间戳以及将被重新绑定到文件的所有提交的提交消息.
#NOTE: BASE is the commit where your rebase begins
git log --pretty='%ct %at %s' BASE..HEAD > hashlog
Run Code Online (Sandbox Code Playgroud)
然后,让实际的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'
Run Code Online (Sandbox Code Playgroud)
如果出现问题,只需结帐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'
Run Code Online (Sandbox Code Playgroud)
真正的解决方案似乎来自Reddit。稍微扩充一下,如下:
git -c rebase.instructionFormat='%s%nexec GIT_COMMITTER_DATE="%cD" git commit --amend --no-edit --allow-empty --allow-empty-message' rebase -i
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
37469 次 |
最近记录: |