簡體   English   中英

是否可以在不使用交互式重新設置基礎的情況下重新設置和編輯git commit?

[英]Is it possible to rebase and edit a git commit without using interactive rebase?

我定期使用git rebase -i,希望能找到一種方法來加快此過程。

例如,我要編輯我的git歷史記錄中的第二次最新提交。 我可以使用:

git rebase -i HEAD~2

...然后將提交設置為“ e”並保存

我希望能夠執行以下操作:

git rebase edit HEAD~2

可以以這種方式使用rebase嗎?

不是直接的,但是您可以編寫腳本來執行此操作,因為git rebase -i調用兩個不同的編輯器。 更准確地說,它首先在pick命令集上調用序列編輯器 ,然后為您已將pick更改為editreword文件調用核心編輯器

因此,通過將序列編輯器設置為與普通交互式編輯器不同的命令,可以使交互式庫的交互比平時少。 (您也可以調整核心編輯器設置,以使它根本不交互,即使是交互行為也是如此。)

如果設置了序列編輯器,則從$GIT_SEQUENCE_EDITOR ,或者從git config --get sequence.editor ,或者使用標准后備。 如果設置了核心編輯器,則使用$GIT_EDITORgit config --get core.editor ,或使用標准后備。

標准的后備方法是使用$VISUAL ,或者,如果未設置,則使用$EDITOR ,或者,如果未設置,則使用嵌入式默認值(通常是vivim )。

將所有這些放在一起(並使用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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM