如何以非交互方式运行 git rebase --interactive?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12394166/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I run git rebase --interactive in non-interactive manner?
提问by pfalcon
Is it possible to do following?
是否可以进行以下操作?
- Make
git rebase --interactive
to just output standard boilerplate to a file, instead to outputting to a file and opening it in editor. - Let the user edit the file.
- Let user re-run
git rebase
with the name of edited file. - Go on with the usual rebase process.
- 制作
git rebase --interactive
只是将标准样板输出到文件,而不是输出到文件并在编辑器中打开它。 - 让用户编辑文件。
- 让用户
git rebase
以编辑后的文件名重新运行。 - 继续通常的变基过程。
Usecase: scripted rebasing of course. See how to re-order commits in Git non-interactivelyfor example.
用例:当然是脚本化的变基。例如,查看如何在 Git 中以非交互方式重新排序提交。
回答by pfalcon
After some thinking and research, the answer turned out to be trivial: git rebase -i
takes the editor name from the well-known EDITOR/VISUAL environment variables, so overriding that to point to a non-interactive script does the job.
经过一些思考和研究,答案变得微不足道:git rebase -i
从众所周知的 EDITOR/VISUAL 环境变量中获取编辑器名称,因此覆盖它以指向非交互式脚本即可完成这项工作。
However, EDITOR/VISUAL applies indifferently to the list of commits, commit messages when rewording and anything else. So, since http://git.kernel.org/?p=git/git.git;a=commit;h=821881d88d3012a64a52ece9a8c2571ca00c35cd, there's a special environment variable GIT_SEQUENCE_EDITOR which applies only to the commit list.
但是,EDITOR/VISUAL 对提交列表、改写时的提交消息和其他任何内容无动于衷。因此,由于http://git.kernel.org/?p=git/git.git;a=commit;h=821881d88d3012a64a52ece9a8c2571ca00c35cd,有一个特殊的环境变量 GIT_SEQUENCE_EDITOR 仅适用于提交列表。
So, the recipe to re-order or flatten commits is:
因此,重新排序或扁平化提交的方法是:
Run: GIT_SEQUENCE_EDITOR=<script> git rebase -i <params>
.
Your <script>
should accept a single argument: the path to the file containing the standard rebase commit list. It should rewrite it in-place and exit. Usual rebase processing happens after that.
运行:GIT_SEQUENCE_EDITOR=<script> git rebase -i <params>
。您<script>
应该接受一个参数:包含标准变基提交列表的文件的路径。它应该就地重写它并退出。通常的变基处理在此之后发生。
回答by Leif Wickland
Adding on to @pfalcon's answer, you can use sed as your GIT_SEQUENCE_EDITOR. For example, I wanted to edit each commit, so I did this:
添加到@pfalcon 的答案,您可以使用 sed 作为您的 GIT_SEQUENCE_EDITOR。例如,我想编辑每个提交,所以我这样做了:
GIT_SEQUENCE_EDITOR="sed -i -re 's/^pick /e /'" git rebase -i
回答by James Foucar
Expanding on pfalcon's answer:
扩展 pfalcon 的回答:
Run
GIT_SEQUENCE_EDITOR=<script> git rebase -i <params>
.<script>
should accept single argument - path to file containing standard rebase commit list. The script should rewrite it in-place and exit. Usual rebase processing happens after that.
运行
GIT_SEQUENCE_EDITOR=<script> git rebase -i <params>
。<script>
应该接受单个参数 - 包含标准变基提交列表的文件路径。脚本应该就地重写它并退出。通常的变基处理在此之后发生。
If you have an environment variable that contains the contents you want:
如果您有一个包含所需内容的环境变量:
GIT_SEQUENCE_EDITOR='echo "$REBASE_DATA" >' git rebase -i [<additional params>]
Catting a file would work too:
Catting 文件也可以:
GIT_SEQUENCE_EDITOR='cat rebase_data_file >' git rebase -i [<additional params>]
回答by Jér?me Pouiller
The variable GIT_SEQUENCE_EDITOR
was initially used to change the editor. It is possible to pass a script to this variable to use git rebase -i
in a non-interactive manner. So it is possible to use:
该变量GIT_SEQUENCE_EDITOR
最初用于更改编辑器。可以将脚本传递给此变量以git rebase -i
非交互方式使用。所以可以使用:
GIT_SEQUENCE_EDITOR="sed -i -re 's/^pick 134567/e 1234567/'" git rebase -i 1234567^
This command will run sed
on file provided by git rebase -i
. It will change the line pick 134567
into e 1234567
(and so, edit the commit 1234567). You can change e
with r
(rework), f
(fixup), s
(squash) or d
(drop) (the latter is not supported by old versions of git
).
此命令将sed
在git rebase -i
. 它将将该行更改pick 134567
为e 1234567
(因此,编辑提交 1234567)。您可以e
使用r
(rework)、f
(fixup)、s
(squash) 或d
(drop)进行更改(旧版本的 不支持后者git
)。
Based on that, I wrote a script that automatizes this task:
基于此,我编写了一个脚本来自动执行此任务:
#!/bin/bash
ACTION=
COMMIT=$(git rev-parse --short )
[[ "$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/ $COMMIT/'" git rebase -i $COMMIT^^
fi
The first argument should be one action. The script uses the same action names than git-rebase. It also add 'split' action (and allow to use drop
with old versions of git).
第一个参数应该是一个动作。该脚本使用与 git-rebase 相同的操作名称。它还添加了“拆分”操作(并允许drop
与旧版本的 git一起使用)。
It also checks that commit you ask for is an ancestor of HEAD. It a common (and really annoying) mistake with rebase -i
.
它还检查您要求的提交是否是 HEAD 的祖先。这是一个常见的(而且真的很烦人)错误rebase -i
。
The second argument is the commit to want to edit/delete/split/reword.
第二个参数是要编辑/删除/拆分/改写的提交。
Then you add an alias to your .gitconfig:
然后你给你的 .gitconfig 添加一个别名:
[alias]
autorebase = ! path_to_your_script
回答by c00kiemon5ter
interactive modes brings up the set editor to work with.
the editor in use can be retrieved with:
交互模式会调出要使用的集合编辑器。
可以通过以下方式检索正在使用的编辑器:
git config --get core.editor
So, if you set a non-interactiveeditor - that is an editor that accepts commands on stdin, you can work with --interactive
in a non-interactiveway :)
I know for sure vim
accepts commands, and so does the standard editored
, ofcourse.
因此,如果您设置了一个非交互式编辑器 - 即一个接受 stdin 命令的编辑器,您可以--interactive
以非交互式方式使用 :)
我肯定知道vim
接受命令,当然标准编辑器也是如此ed
。
so, hold the interactive editor (if wanted)
因此,请按住交互式编辑器(如果需要)
$ ied="$(git config --get core.editor)"
set the non-interactive editor
设置非交互式编辑器
$ git config --unset-all core.editor
$ git config --add core.editor ed
and do work with it..
并使用它..
$ printf '%s\n' "some-ed-cmd" "another-ed-cmd" "wq" | git rebase -i HEAD~5
and restore the editor (if wanted)
并恢复编辑器(如果需要)
$ git config --unset-all core.editor
$ git config --add core.editor "$ied"
回答by Archimedes Trajano
You can use touch
as the editor which will touch the file so it will appear modified. For example
您可以将其touch
用作编辑器,该编辑器将触摸该文件,使其看起来已被修改。例如
GIT_SEQUENCE_EDITOR=touch git rebase -i [commit]
To alias it, given baseline
as a tag I want to rebase against
给它取别名,baseline
作为我想要重新定位的标签
git config alias.baseline '!GIT_SEQUENCE_EDITOR=touch git rebase -i baseline'
The alias works under Windows because the shell it is executing is bash
not cmd
.
别名在 Windows 下工作,因为它正在执行的 shellbash
不是cmd
.
回答by Matthew D. Scholefield
As others have mentioned, you need to provide a custom GIT_SEQUENCE_EDITOR
value that will modify the interactive rebase file. If you just want to perform an action on a single commit, you can do it as follows:
正如其他人所提到的,您需要提供一个自定义GIT_SEQUENCE_EDITOR
值来修改交互式 rebase 文件。如果您只想对单个提交执行操作,您可以按如下方式进行:
# Runs "edit" on HEAD~3
GIT_SEQUENCE_EDITOR="sed -i -ze 's/^pick/edit/'" git rebase -i HEAD~3
Alternatively, here's a function to generalize this:
或者,这是一个概括这一点的函数:
# Usage: git-rebase-custom edit HEAD~3
git-rebase-custom() {
local action=
shift
GIT_SEQUENCE_EDITOR="sed -i -ze 's/^pick/$action/'" git rebase -i "$@"
}
回答by Wooseong Kim
I found the solution. You can use:
我找到了解决方案。您可以使用:
$ GIT_SEQUENCE_EDITOR=true git rebase -i --autosquash $COMMIT_HASH~1
回答by John Gliksberg
Based on Jezz's answer,
I made a shell-agnostic script (GitReb)
which works with multiple-argument revisions,
:/<text>
syntax, root commit and also does some sanity checks.
根据Jezz 的回答,我制作了一个与 shell 无关的脚本 ( GitReb),它适用于多参数修订、
:/<text>
语法、根提交,并且还进行了一些完整性检查。
I also made it simpler and removed the t
/split
action
and delete
->drop
conversion
which IMO are out of this script's scope.
我还使它更简单,并删除了IMO 超出此脚本范围的t
/split
操作和delete
->drop
转换。