如何以非交互方式运行 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-19 07:29:25  来源:igfitidea点击:

How do I run git rebase --interactive in non-interactive manner?

gitscriptinggit-rebasenon-interactive

提问by pfalcon

Is it possible to do following?

是否可以进行以下操作?

  1. Make git rebase --interactiveto just output standard boilerplate to a file, instead to outputting to a file and opening it in editor.
  2. Let the user edit the file.
  3. Let user re-run git rebasewith the name of edited file.
  4. Go on with the usual rebase process.
  1. 制作git rebase --interactive只是将标准样板输出到文件,而不是输出到文件并在编辑器中打开它。
  2. 让用户编辑文件。
  3. 让用户git rebase以编辑后的文件名重新运行。
  4. 继续通常的变基过程。

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 -itakes 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_EDITORwas initially used to change the editor. It is possible to pass a script to this variable to use git rebase -iin 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 sedon file provided by git rebase -i. It will change the line pick 134567into e 1234567(and so, edit the commit 1234567). You can change ewith r(rework), f(fixup), s(squash) or d(drop) (the latter is not supported by old versions of git).

此命令将sedgit rebase -i. 它将将该行更改pick 134567e 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 dropwith 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 --interactivein a non-interactiveway :)
I know for sure vimaccepts 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 touchas 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 baselineas 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 bashnot cmd.

别名在 Windows 下工作,因为它正在执行的 shellbash不是cmd.

回答by Matthew D. Scholefield

As others have mentioned, you need to provide a custom GIT_SEQUENCE_EDITORvalue 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/splitaction and delete->dropconversion which IMO are out of this script's scope.

我还使它更简单,并删除了IMO 超出此脚本范围的t/split操作和delete->drop转换。