如何以非交互方式运行git rebase --interactive?

时间:2012-09-12 18:22:32

标签: git scripting git-rebase non-interactive

可以做以下吗?

  1. git rebase --interactive只输出标准样板文件到文件,而不是输出到文件并在编辑器中打开它。
  2. 让用户编辑文件。
  3. 让用户使用已编辑文件的名称重新运行git rebase
  4. 继续使用通常的rebase流程。
  5. Usecase:当然是脚本式的变基。例如,请参阅how to re-order commits in Git non-interactively

9 个答案:

答案 0 :(得分:49)

经过一番思考和研究后,答案变得微不足道: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>应该接受一个参数:包含标准rebase提交列表的文件的路径。它应该就地重写并退出。在此之后会发生通常的rebase处理。

答案 1 :(得分:6)

扩展pfalcon的答案:

  

运行GIT_SEQUENCE_EDITOR=<script> git rebase -i <params><script>应该接受单个参数 - 包含标准rebase提交列表的文件路径。脚本应该就地重写并退出。在此之后会发生通常的rebase处理。

如果您的环境变量包含您想要的内容:

GIT_SEQUENCE_EDITOR='echo "$REBASE_DATA" >' git rebase -i [<additional params>]

捕获文件也会起作用:

GIT_SEQUENCE_EDITOR='cat rebase_data_file >' git rebase -i [<additional params>]

答案 2 :(得分:5)

添加@pfalcon的答案,你可以使用sed作为你的GIT_SEQUENCE_EDITOR。例如,我想编辑每个提交,所以我这样做了:

GIT_SEQUENCE_EDITOR="sed -i -re 's/^pick /e /'" git rebase -i

答案 3 :(得分:4)

我使用这个脚本(另外它允许简化提交拆分):

#!/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 x exec d delete t split; do
     [[ $ACTION == $A ]] && CORRECT=1
done 
[[ "$CORRECT" ]] || exit 1
if [[ $ACTION == "delete" || $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

为.gitconfig添加别名:

[alias]
  autorebase = ! path_to_your_script

答案 4 :(得分:3)

您可以使用touch作为编辑器,它将触摸该文件,使其显示为已修改。例如

GIT_SEQUENCE_EDITOR=touch git rebase -i [commit]

为了别名,给定baseline作为标签我要反对

git config alias.baseline '!GIT_SEQUENCE_EDITOR=touch git rebase -i baseline'

别名在Windows下运行,因为它正在执行的shell是bash而不是cmd

答案 5 :(得分:2)

交互模式会调出设置编辑器。
可以使用以下命令检索正在使用的编辑器:

git config --get core.editor

因此,如果您设置非交互式编辑器 - 这是一个接受stdin命令的编辑器,您可以在非交互式中使用--interactive way :)
我确信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"

答案 6 :(得分:0)

就像其他人提到的那样,您需要提供一个自定义GIT_SEQUENCE_EDITOR值,它将修改交互式rebase文件。如果只想对单个提交执行某项操作,则可以按照以下步骤进行操作:

# 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 "$@"
}

答案 7 :(得分:0)

我找到了解决方案。您可以使用:

let label = UILabel()
label.text = "I would like this text's ellipsis (wrap) to occur at the beginning instead of at the end as is currently the case."
label.lineBreakMode = .byTruncatingHead
self.navigationItem.titleView = label

答案 8 :(得分:-1)

基于Jezz's answer, 我制作了一个与shell无关的脚本(GitReb) 适用于多参数修订, :/<text>语法,root commit以及一些健全性检查。

我还使其更简单并删除了t / split操作 和delete - &gt; drop转化 哪个IMO超出了这个脚本的范围。