git - 是否可以在不使用交互式 rebase 的情况下 rebase 和编辑 git 提交?

标签 git rebase

我定期使用 git rebase -i ,我希望找到一种方法来加快这个过程。

例如,我想编辑我的 git 历史记录中的第二个最新提交。
我可以使用:

git rebase -i HEAD~2

...然后将提交设置为“e”并保存

我希望能够执行以下操作:
git rebase edit HEAD~2

可以这样使用rebase吗?

最佳答案

不是直接的,但是你可以写一个脚本来做到这一点,因为 git rebase -i调用两个不同的编辑器。更准确地说,它首先在 pick 的集合上调用序列编辑器。命令,然后为您更改的文件调用核心编辑器 pickeditreword .

因此,通过将序列编辑器设置为与普通交互式编辑器不同的命令,您可以使交互式 rebase 的交互比平时少。 (您还可以调整您的核心编辑器设置,使其根本不交互,即使在交互行为时也是如此。)

序列编辑器取自 $GIT_SEQUENCE_EDITOR如果设置,或 git config --get sequence.editor ,或使用标准回退。核心编辑器摘自$GIT_EDITOR如果设置,或 git 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

关于git - 是否可以在不使用交互式 rebase 的情况下 rebase 和编辑 git 提交?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36462397/

相关文章:

git - 如何线性化 Git 中的 "splintered" merge 历史记录?

git - 为什么 git log 会显示我的密码?

git - .gitignore 不会忽略子目录中的文件

node.js - 维护单独的 git 分支 - 一个用于 heroku,另一个用于 github

Git:多个子特征分支依赖 rebase

Git rebase 噪声

git - 如何仅 stash 已更改的多个文件中的一个文件?

没有任何提交历史的 Git merge 功能分支

git - 从 git 历史记录中删除大文件?

git - 如何压缩一个分支中的提交?