我正在将旧的SVN存储库转换为Git,其中包括尝试在所有正确的位置获取所有分支/标记。这部分进展顺利,但有时候我想在我的脚本中添加历史记录中的提交,后来我想用下一次提交压缩。问题是我不是一个接一个地抓取提交,而是作为一个大组,因此当我将它们从SVN存储库中拉出时,我无法压缩它们。最后,我的存储库看起来像这样:
* (branch_2, HEAD) commit 5
* commit 4
* commit 3
* SQUASH ME!
* (branch_1) commit 2
* commit 1
我希望能够挤压 commit 3
同 SQUASH ME!
使用交互式rebase显然很容易,但在脚本中更具挑战性。我似乎遇到的主要问题是虽然很容易结账 branch_1
或者在它之前的任何提交,很难以编程方式请求提交 后 它和我很难预测有多少提交 branch_2
我要走了。我真的希望能够做到这样的事情:
git checkout branch_1+2
有什么指针吗?
你所说的不是一个 壁球,但是 修理,因为壁球会以交互方式询问你提交msg,而 fixup使用来自HEAD提交的提交消息。
这是一个没有干预的脚本。
剧本 : /usr/bin/git-fixup
#/bin/bash
# This command fixesup one commit onto his parent
set -e
# We need a commit from the first argument of that command
commit=${1:?No commit given as first argument}
startingbranch=$(git rev-parse --abbrev-ref HEAD)
# Checkout the parent of the asked commit
git checkout "$commit"
git checkout HEAD~
# Merge the commit into it's parent, keeping the commit message of the parent
git merge --squash "$commit"
git add .
git add --update
git commit --amend --no-edit
# Store the current commit
newcommit=$(git rev-parse HEAD)
# Rebase the starting branch onto the new commit
git checkout "$startingbranch"
git rebase "$newcommit"
使用它
git fixup <commit-id>
例如,如果您的历史记录是:
ce0e2fd (master, HEAD) commit 4
72ab3c4 commit 3
8150939 commit 2
301c1e1 commit 1
你可以做 git fixup 72ab3c4
它将“commit 3”和“commit 2”合并为一个提交,并带有消息“commit 2”,并将您放回主分支。
从 git rebase --help
:
--autosquash
当提交日志消息以“squash!...”(或“fixup!...”)开头时,并且提交的标题以相同的提交开头
...,自动修改rebase -i的待办事项列表
因此,标记为压缩的提交在修改提交之后立即生效,并更改已移动提交的操作
从挑选到壁球(或修复)。
此选项仅在使用--interactive选项时有效。
如果输入的形式正确,那看起来它会做你想要的一半。
另一半是阻止它启动交互式编辑器。幸运的是,编辑器是可配置的,所以我们可以将其设置为无害的。
尝试这个:
env EDITOR=true git rebase -i --autosquash <from-here>
将编辑器设置为 true
(一个简单地退出成功的工具)就足以说服git继续使用默认的rebase设置,自动壁球应该设置为有用的东西。
或者,如果 --autosquash
没有你想要的,你可以设置 EDITOR
到你喜欢的任何脚本:
env EDITOR=mysquasher.sh git rebase -i <from-here>
该脚本可以执行您需要的任何操作,但在您的情况下,它只需要找到包含的每一行 "SQUASHME!"
,并改变 "pick"
在以下行阅读 "fixup"
。使用awk可能最容易实现这一点:
#!/bin/bash -e
awk -- 'BEGIN {dosquash=0}
dosquash==1 {gsub(/^pick/, "fixup"); dosquash=0}
/SQUASHME/ {dosquash=1}
{print}' "$1" > /tmp/tmp.$$
mv /tmp/tmp.$$ "$1"