是否可以进行以下操作?
- 仅将
git rebase --interactive
标准样板输出到文件,而不是输出到文件并在编辑器中打开它。 - 让用户编辑文件。
- 让用户以编辑后的文件名重新运行
git rebase
。 - 继续通常的变基过程。
用例:当然是脚本化的变基。例如,查看如何以非交互方式在 Git 中重新排序提交。
是否可以进行以下操作?
git rebase --interactive
标准样板输出到文件,而不是输出到文件并在编辑器中打开它。git rebase
。用例:当然是脚本化的变基。例如,查看如何以非交互方式在 Git 中重新排序提交。
经过一番思考和研究,答案被证明是微不足道的:git rebase -i
从著名的 EDITOR/VISUAL 环境变量中获取编辑器名称,因此覆盖它以指向非交互式脚本就可以了。
但是,EDITOR/VISUAL 对提交列表、改写时的提交消息和其他任何内容都无动于衷。因此,由于http://git.kernel.org/?p=git /git.git;a=commit;h=821881d88d3012a64a52ece9a8c2571ca00c35cd ,有一个特殊的环境变量 GIT_SEQUENCE_EDITOR 仅适用于提交列表。
因此,重新排序或展平提交的方法是:
运行:GIT_SEQUENCE_EDITOR=<script> git rebase -i <params>
。您<script>
应该接受一个参数:包含标准变基提交列表的文件的路径。它应该就地重写它并退出。之后发生通常的变基处理。
添加到@pfalcon 的答案,您可以使用 sed 作为您的 GIT_SEQUENCE_EDITOR。例如,我想编辑每个提交,所以我这样做了:
GIT_SEQUENCE_EDITOR="sed -i -re 's/^pick /e /'" git rebase -i
该变量GIT_SEQUENCE_EDITOR
最初用于更改编辑器。可以将脚本传递给该变量以git rebase -i
以非交互方式使用。所以可以使用:
GIT_SEQUENCE_EDITOR="sed -i -re 's/^pick 134567/e 1234567/'" git rebase -i 1234567^
此命令将在 .sed
提供的文件上运行git rebase -i
。它将将该行更改pick 134567
为e 1234567
(因此,编辑提交 1234567)。您可以e
使用r
(rework)、f
(fixup)、s
(squash) 或d
(drop) 进行更改(旧版本不支持后者git
)。
基于此,我编写了一个脚本来自动化这个任务:
#!/bin/bash
ACTION=$1
COMMIT=$(git rev-parse --short $2)
[[ "$COMMIT" ]] || exit 1
CORRECT=
for A in p pick r reword e edit s squash f fixup d drop t split; do
[[ $ACTION == $A ]] && CORRECT=1
done
[[ "$CORRECT" ]] || exit 1
git merge-base --is-ancestor $COMMIT HEAD || exit 1
if [[ $ACTION == "drop" || $ACTION == "d" ]]; then
GIT_SEQUENCE_EDITOR="sed -i -e '/^pick $COMMIT/d'" git rebase -i $COMMIT^^
elif [[ $ACTION == "split" || $ACTION == "t" ]]; then
GIT_SEQUENCE_EDITOR="sed -i -e 's/^pick $COMMIT/edit $COMMIT/'" git rebase -i $COMMIT^^ || exit 1
git reset --soft HEAD^
echo "Hints:"
echo " Select files to be commited using 'git reset', 'git add' or 'git add -p'"
echo " Commit using 'git commit -c $COMMIT'"
echo " Finish with 'git rebase --continue'"
else
GIT_SEQUENCE_EDITOR="sed -i -e 's/^pick $COMMIT/$1 $COMMIT/'" git rebase -i $COMMIT^^
fi
第一个参数应该是一个动作。该脚本使用与 git-rebase 相同的操作名称。它还添加了“拆分”操作(并允许drop
与旧版本的 git 一起使用)。
它还检查您要求的提交是否是 HEAD 的祖先。这是一个常见(而且非常烦人)的错误rebase -i
。
第二个参数是要编辑/删除/拆分/改写的提交。
然后你为你的 .gitconfig 添加一个别名:
[alias]
autorebase = ! path_to_your_script
扩展 pfalcon 的答案:
运行
GIT_SEQUENCE_EDITOR=<script> git rebase -i <params>
。<script>
应该接受单个参数 - 包含标准变基提交列表的文件的路径。脚本应该就地重写它并退出。之后发生通常的变基处理。
如果您有一个包含所需内容的环境变量:
GIT_SEQUENCE_EDITOR='echo "$REBASE_DATA" >' git rebase -i [<additional params>]
Catting 文件也可以:
GIT_SEQUENCE_EDITOR='cat rebase_data_file >' git rebase -i [<additional params>]
您可以touch
用作编辑器,它会触摸文件,因此它会显示为已修改。例如
GIT_SEQUENCE_EDITOR=touch git rebase -i [commit]
给它取别名,baseline
作为我想要重新定位的标签给出
git config alias.baseline '!GIT_SEQUENCE_EDITOR=touch git rebase -i baseline'
该别名在 Windows 下工作,因为它正在执行的 shellbash
不是cmd
.
交互模式会调出要使用的集合编辑器。
可以通过以下方式检索正在使用的编辑器:
git config --get core.editor
因此,如果您设置了一个非交互式编辑器——即在标准输入上接受命令的编辑器,您可以--interactive
以非交互式方式使用 :)
我知道肯定vim
接受命令,标准编辑器 ed
也是如此,当然。
所以,拿着交互式编辑器(如果需要)
$ ied="$(git config --get core.editor)"
设置非交互式编辑器
$ git config --unset-all core.editor
$ git config --add core.editor ed
并使用它..
$ printf '%s\n' "some-ed-cmd" "another-ed-cmd" "wq" | git rebase -i HEAD~5
并恢复编辑器(如果需要)
$ git config --unset-all core.editor
$ git config --add core.editor "$ied"
我找到了解决方案。您可以使用:
$ GIT_SEQUENCE_EDITOR=true git rebase -i --autosquash $COMMIT_HASH~1
要完全按照原始问题的要求进行操作,请sed -i '1s/^/b\n/'
用作您的编辑器
git -c sequence.editor="sed -i '1s/^/b\n/'" rebase --interactive
git -c
指定以指定的设置运行以下 git 命令sequence.editor
确定将编辑 redbase-todo 文件的“编辑器”的设置sed -i
就地运行 sed 命令
1s
在第一行^
匹配开头b\n
插入b
和换行符\n
。b
或者break
是停止交互式变基的变基命令。rebase --interactive
运行变基命令这会立即停止交互式变基。现在您可以编辑.git/rebase-merge/git-rebase-todo
并运行git rebase --continue
.
正如其他人所提到的,您需要提供一个自定义GIT_SEQUENCE_EDITOR
值来修改交互式变基文件。如果您只想对单个提交执行操作,可以按如下方式执行:
# Runs "edit" on HEAD~3
GIT_SEQUENCE_EDITOR="sed -i -ze 's/^pick/edit/'" git rebase -i HEAD~3
或者,这是一个概括这一点的函数:
# Usage: git-rebase-custom edit HEAD~3
git-rebase-custom() {
local action=$1
shift
GIT_SEQUENCE_EDITOR="sed -i -ze 's/^pick/$action/'" git rebase -i "$@"
}