使用 shell 脚本更改 git *n* 次提交的历史记录(提交日期)
change git history (commit date) of *n* commits with shell script
我的问题概况:
我想为 今天 的最后 n 个提交中的 change the history 写一个脚本,例如:./myscript.sh 5
会将最后 5 次提交的 提交日期 更改为 今天 .
来自 this link,我可以:
- 将上次提交的日期设置为当前日期
- 将最后一次提交的日期设置为任意日期
- 将任意提交的日期设置为任意或当前日期
因为我想要的是改变最后n次提交的历史记录,而不仅仅是1次,所以我必须采用第三种技术,它需要调用git rebase -i
并打开一个编辑器。我想写一个脚本来自动完成这个任务。
这是手动完成任务的方式(将最后 5 次提交的提交日期更改为今天):
git rebase -i HEAD~5
然后它打开编辑器
pick 81888d1 committed 9 months ago
pick 7363124 committed a month ago
pick eea43f7 committed yesterday
pick 48c3e85 committed yesterday
pick a62cbec commit recently
# change all the `pick` to `edit`
关闭编辑器,重复以下5次
GIT_COMMITTER_DATE="$(date)" git commit --amend --no-edit --date "$(date)"
git rebase --continue
完成。
约束:因为我提前知道我在编辑器中所做的部分是将所有 pick
关键字替换为 edit
,所以我希望它静默完成。只需键入 ./myscript.sh 5
即可完成工作,没有打开任何编辑器。我该怎么做 (在脚本中)?
在答案的帮助下,这是我的最终脚本:
#!/bin/bash
# wish design:
#./myscript.sh [number of days]
#./myscript.sh 5 # make the last 5 commits's commit dates to today
declare -r integer_pattern="^[0-9]+$"
if [[ =~ $integer_pattern ]]; then
count=
GIT_SEQUENCE_EDITOR="sed -i -re 's/^pick /e /'" git rebase -i "HEAD~$count"
for ((i=0; i<count; i++)); do
GIT_COMMITTER_DATE="$(date)" git commit --amend --no-edit --date "$(date)"
git rebase --continue
done
else
echo "invalid argument [number of days] "
fi
如所述here。
Interactive rebase 打开提交列表中的默认 $EDITOR
。它也可以被名为 GIT_SEQUENCE_EDITOR
的环境变量覆盖,因此您需要拦截调用并将此变量与某些脚本一起使用
运行:GIT_SEQUENCE_EDITOR=<script> git rebase -i <params>
。您的 <script>
应该接受一个参数:包含标准 rebase 提交列表的文件的路径。它应该就地重写并退出。通常的变基处理在那之后发生。
示例:
GIT_SEQUENCE_EDITOR="sed -i -re 's/^pick /e /'" git rebase -i
但您也可以使用一些 bash/python/whatever 脚本。
将 n 次提交压缩为一个提交可以在没有 rebase interactive 的情况下完成……甚至根本不需要 rebase。要压缩最后 5 次提交,您可以这样做:
git reset --soft HEAD~5
git commit -m "some comment"
大功告成
我的问题概况:
我想为 今天 的最后 n 个提交中的 change the history 写一个脚本,例如:./myscript.sh 5
会将最后 5 次提交的 提交日期 更改为 今天 .
来自 this link,我可以:
- 将上次提交的日期设置为当前日期
- 将最后一次提交的日期设置为任意日期
- 将任意提交的日期设置为任意或当前日期
因为我想要的是改变最后n次提交的历史记录,而不仅仅是1次,所以我必须采用第三种技术,它需要调用git rebase -i
并打开一个编辑器。我想写一个脚本来自动完成这个任务。
这是手动完成任务的方式(将最后 5 次提交的提交日期更改为今天):
git rebase -i HEAD~5
然后它打开编辑器
pick 81888d1 committed 9 months ago
pick 7363124 committed a month ago
pick eea43f7 committed yesterday
pick 48c3e85 committed yesterday
pick a62cbec commit recently
# change all the `pick` to `edit`
关闭编辑器,重复以下5次
GIT_COMMITTER_DATE="$(date)" git commit --amend --no-edit --date "$(date)"
git rebase --continue
完成。
约束:因为我提前知道我在编辑器中所做的部分是将所有 pick
关键字替换为 edit
,所以我希望它静默完成。只需键入 ./myscript.sh 5
即可完成工作,没有打开任何编辑器。我该怎么做 (在脚本中)?
在答案的帮助下,这是我的最终脚本:
#!/bin/bash
# wish design:
#./myscript.sh [number of days]
#./myscript.sh 5 # make the last 5 commits's commit dates to today
declare -r integer_pattern="^[0-9]+$"
if [[ =~ $integer_pattern ]]; then
count=
GIT_SEQUENCE_EDITOR="sed -i -re 's/^pick /e /'" git rebase -i "HEAD~$count"
for ((i=0; i<count; i++)); do
GIT_COMMITTER_DATE="$(date)" git commit --amend --no-edit --date "$(date)"
git rebase --continue
done
else
echo "invalid argument [number of days] "
fi
如所述here。
Interactive rebase 打开提交列表中的默认 $EDITOR
。它也可以被名为 GIT_SEQUENCE_EDITOR
的环境变量覆盖,因此您需要拦截调用并将此变量与某些脚本一起使用
运行:GIT_SEQUENCE_EDITOR=<script> git rebase -i <params>
。您的 <script>
应该接受一个参数:包含标准 rebase 提交列表的文件的路径。它应该就地重写并退出。通常的变基处理在那之后发生。
示例:
GIT_SEQUENCE_EDITOR="sed -i -re 's/^pick /e /'" git rebase -i
但您也可以使用一些 bash/python/whatever 脚本。
将 n 次提交压缩为一个提交可以在没有 rebase interactive 的情况下完成……甚至根本不需要 rebase。要压缩最后 5 次提交,您可以这样做:
git reset --soft HEAD~5
git commit -m "some comment"
大功告成