我經常使用git rebase -i,我希望找到一種方法來加速這個過程。是否可以在不使用交互式底圖的情況下重新綁定和編輯Git提交?
例如,我想編輯我的git歷史記錄中的第二個最新提交。 我可以使用:
git rebase -i HEAD~2
...然後將致力於「e」和保存
我寧願能夠做這樣的事情:
git rebase edit HEAD~2
可以變基以這種方式使用?
我經常使用git rebase -i,我希望找到一種方法來加速這個過程。是否可以在不使用交互式底圖的情況下重新綁定和編輯Git提交?
例如,我想編輯我的git歷史記錄中的第二個最新提交。 我可以使用:
git rebase -i HEAD~2
...然後將致力於「e」和保存
我寧願能夠做這樣的事情:
git rebase edit HEAD~2
可以變基以這種方式使用?
不是直接的,但你可以寫一個腳本來做到這一點,因爲git rebase -i
調用兩個不同編輯。更確切地說,它首先調用了一套pick
命令的序列編輯器,然後調用用於您已經更改pick
要麼edit
或reword
文件核心編輯。
因此,通過將序列編輯器設置爲與普通交互式編輯器不同的命令,可以使交互式重新分片交互比平常少。 (您也可以調整核心編輯器設置,使其根本不會互動,即使在交互行爲時也是如此)。
序列編輯器取自$GIT_SEQUENCE_EDITOR
(如果設置爲git config --get sequence.editor
)或使用標準回退。核心編輯器取自$GIT_EDITOR
(如果已設置),或取自git config --get core.editor
或使用標準回退。
標準的回退是使用$VISUAL
,或如果未設置,則使用$EDITOR
,或者如果沒有設置,使用編譯的缺省(通常vi
或vim
)。
把所有這一切在一起(使用來自git-sh-setup
位),我寫了下面沒有經過充分測試腳本改寫(不能修改)款。如何修改它以允許修改(編輯)提交應該是顯而易見的。
#! /bin/sh
#
# git-reword: use git rebase -i to reword one particular commit
SUBDIRECTORY_OK=Yes
USAGE="<commit>"
. $(git --exec-path)/git-sh-setup
case $# in
1) ;;
*) usage;;
esac
rev=$(git rev-parse "$1") || exit 1
# We now know which commit to reword; find it relative to HEAD,
# and find the parent argument to pass to "git rebase -i".
# If we wanted to allow multiple rewords we would need to sort
# them topologically so as to find the correct parent argument.
# "git rev-list --no-walk --topo-order <rev> <rev> ..." can do this
# now, but watch out, older rev-lists do not apply the sort if there
# are specific revisions listed on the command line.
if ! git merge-base --is-ancestor $rev HEAD; then
fatal "$1 is not an ancestor of HEAD, cannot reword by rebasing"
fi
# Is it the root commit? Are there merges between it and HEAD?
if parent=$(git rev-parse -q --verify ${rev}^); then
# it has a (first) parent, so don't need --root
nmerge=$(git rev-list --count --merges $parent..HEAD)
else
# it has no first parent, so use --root instead
parent="--root"
nmerge=$(git rev-list --count --merges HEAD)
fi
# Refuse to run if there are merges. This is partly a matter
# of taste since we could attempt to combine -i and -p (since
# we are not deleting any pick lines) but it's definitely safer
# to refuse to re-do merges: we don't know if there are evil
# merges, for instance, nor want to force manual re-merges.
if [ $nmerge -gt 0 ]; then
[ $nmerge -gt 1 ] && msg="are $nmerge merges" || msg="is a merge"
fatal "Cannot reword: there $msg in the way."
fi
require_clean_work_tree "reword" "Please commit or stash them."
# If we allowed merges, the pick line we want might not be
# the very first pick command; but we don't, so it is, so
# that makes our "editor" pretty easy.
# If we want to allow multiple reword hashes, change this
# to write a script that reads each line and matches SHA-1s
# (we need to expand them a la git-rebase--interactive and
# then match them against the IDs we'd like to reword).
TF=$(mktemp)
trap "rm -f $TF" 0 1 2 3 15
cat <<END> $TF
#! /bin/sh
# change first line from "pick ..." to "reword ..."
# copy the remaining lines unchanged
sed -e '1s/^pick/reword/'
END
chmod +x $TF
GIT_SEQUENCE_EDITOR=$TF git rebase -i $parent