默认情况下,git rebase 会将提交者的时间戳设置为新提交创建的时间,但保持作者的时间戳不变。大多数时候,这是期望的行为,但在某些情况下,我们也不希望更改提交者的时间戳。我们怎样才能做到这一点?好吧,这是我通常做的把戏。
首先,确保您要变基的每个提交都有一个唯一的提交消息和作者时间戳(这是技巧需要改进的地方,但目前它适合我的需要)。
在 rebase 之前,记录提交者的时间戳、作者的时间戳和所有将要 rebase 到文件的提交的提交消息。
#NOTE: BASE is the commit where your rebase begins
git log --pretty='%ct %at %s' BASE..HEAD > hashlog
然后,让实际的变基发生。
最后,如果提交消息相同,我们使用文件中记录的时间戳替换当前提交者的时间戳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'