我正在将旧的SVN存储库转换为Git,其中包括尝试将所有分支/标记放在所有正确的位置。这部分进展得很顺利,但是有时我想在脚本的历史记录中添加一个提交,然后我想在下一次提交时删除它。问题是,我不是一个一个地抓取提交,而是作为一个大的组来抓取,所以当我将它们从SVN存储库中取出时,我不能压缩它们。最后,我的存储库看起来像这样:
* (branch_2, HEAD) commit 5
* commit 4
* commit 3
* SQUASH ME!
* (branch_1) commit 2
* commit 1
我希望能够用SQUASH ME!
压制commit 3
,这显然很容易与交互式重基,但从脚本内更具挑战性。我似乎遇到的主要问题是,虽然很容易检出branch_1
或之前的任何提交,但很难以编程方式要求在之后提交,而且我很难预测我需要从branch_2
返回多少提交。我真的很想做这样的事情:
git checkout branch_1+2
指针吗?
你说的不是压缩,而是修复,因为压缩会交互式地向你询问提交msg,而修复使用来自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"one_answers"commit 2"合并在一起,作为一个带有"commit 2"消息的提交,并将你放回主分支。
From git rebase --help
:
——autosquash
当提交日志消息以"squash!"……"(或"修正!…"),并且存在标题以相同开头的提交…,自动修改rebase -i的todo列表这样,标记为压缩的提交就在要修改的提交之后出现,并改变被移动的提交的动作从采摘到挤压(或修复)。
此选项仅在使用——interactive选项时有效。
如果输入的格式正确,看起来它可以完成你想要的一半。
另一半是阻止它启动交互式编辑器。幸运的是,编辑器是可配置的,所以我们可以把它设置成无害的。
试试这个:
env EDITOR=true git rebase -i --autosquash <from-here>
将编辑器设置为true
(一个简单地成功退出的工具)足以说服git继续默认的重基设置,自动压缩应该设置为有用的东西。
或者,如果--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"