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

如何以非交互方式运行git rebase——交互式?,git,scripting,git-rebase,non-interactive,Git,Scripting,Git Rebase,Non Interactive,有可能做到以下几点吗 Makegit-rebase--interactive将标准样板输出到文件,而不是输出到文件并在编辑器中打开它 让用户编辑该文件 让用户用编辑过的文件名重新运行git-rebase 继续进行通常的重设基础过程 用例:当然是脚本化的重定基调。例如,请参见。经过一些思考和研究,结果证明答案很简单:git-rebase-i从著名的编辑器/可视环境变量中获取编辑器名称,因此重写以指向非交互式脚本即可 然而,EDITOR/VISUAL对提交列表、重写时提交消息以及其他任何内容都不起作

有可能做到以下几点吗

  • Make
    git-rebase--interactive
    将标准样板输出到文件,而不是输出到文件并在编辑器中打开它
  • 让用户编辑该文件
  • 让用户用编辑过的文件名重新运行
    git-rebase
  • 继续进行通常的重设基础过程

  • 用例:当然是脚本化的重定基调。例如,请参见。

    经过一些思考和研究,结果证明答案很简单:
    git-rebase-i
    从著名的编辑器/可视环境变量中获取编辑器名称,因此重写以指向非交互式脚本即可

    然而,EDITOR/VISUAL对提交列表、重写时提交消息以及其他任何内容都不起作用。因此,因为有一个特殊的环境变量GIT_SEQUENCE_EDITOR,它只适用于提交列表

    因此,重新订购或展平提交的方法是:

    运行:
    GIT\u SEQUENCE\u EDITOR=GIT-rebase-i

    您的
    应该接受一个参数:包含标准rebase提交列表的文件的路径。它应该就地重写并退出。通常的重新基础处理在此之后进行。

    交互模式会打开集合编辑器进行操作。
    可以通过以下方式检索正在使用的编辑器:

    git config --get core.editor
    
    因此,如果您设置了一个非交互式编辑器,即接受stdin命令的编辑器,那么您可以以非交互式方式使用
    --interactive
    :)
    我确信
    vim
    接受命令,当然,标准编辑器
    ed
    也接受命令

    因此,按住交互式编辑器(如果需要)

    设置非交互式编辑器

    $ 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
    
    并恢复编辑器(如果需要)


    再加上@pfalcon的答案,您可以使用sed作为GIT\u序列编辑器。例如,我想编辑每个提交,所以我这样做:

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

    变量
    GIT\u SEQUENCE\u EDITOR
    最初用于更改编辑器。可以向该变量传递脚本,以非交互方式使用
    git-rebase-i
    。因此,可以使用:

    GIT_SEQUENCE_EDITOR="sed -i -re 's/^pick 134567/e 1234567/'" git rebase -i 1234567^
    
    此命令将在git rebase-i提供的文件上运行
    sed
    。它会将行
    pick 134567
    更改为
    e 1234567
    (因此,编辑commit 1234567)。您可以使用
    r
    (返工)、
    f
    (修复)、
    s
    (挤压)或
    d
    (拖放)更改
    e
    (旧版本的
    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相同的操作名称。它还添加了“拆分”操作(并允许对git的旧版本使用
    drop

    它还检查您请求的提交是否是HEAD的祖先。这是
    rebase-i
    的一个常见(而且非常恼人)错误

    第二个参数是要编辑/删除/拆分/重写的提交

    然后将别名添加到.gitconfig:

    [alias]
      autorebase = ! path_to_your_script
    

    扩展pfalcon的答案:

    运行
    GIT\u SEQUENCE\u EDITOR=GIT-rebase-i
    <代码>应接受单参数-包含标准重基提交列表的文件路径。脚本应该就地重写并退出。通常的重新基址处理在此之后进行

    如果您有一个包含所需内容的环境变量:

    GIT_SEQUENCE_EDITOR='echo "$REBASE_DATA" >' git rebase -i [<additional params>]
    
    GIT\u SEQUENCE\u EDITOR='echo“$REBASE\u DATA”>'GIT-REBASE-i[]
    
    归档也可以:

    GIT_SEQUENCE_EDITOR='cat rebase_data_file >' git rebase -i [<additional params>]
    
    GIT\u SEQUENCE\u EDITOR='cat rebase\u data\u file>'GIT rebase-i[]
    
    您可以使用
    触摸
    作为编辑器,该编辑器将触摸文件,使其显示为已修改。比如说

    GIT_SEQUENCE_EDITOR=touch git rebase -i [commit]
    
    为了给它取别名,我将
    基线
    作为我想要重新设置基线的标记

    git config alias.baseline '!GIT_SEQUENCE_EDITOR=touch git rebase -i baseline'
    
    别名在Windows下工作,因为它执行的shell是基于, 我制作了一个shell不可知脚本() 它适用于多个参数修订,
    :/
    语法、根提交,并执行一些健全性检查

    我还简化了它,删除了
    t
    /
    split
    操作 和
    删除
    ->
    删除
    转换
    哪些IMO超出了此脚本的范围。

    正如其他人所提到的,您需要提供一个自定义的
    GIT\u SEQUENCE\u编辑器
    值,该值将修改交互式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 "$@"
    }
    

    我找到了解决办法。您可以使用:

    $GIT\u SEQUENCE\u EDITOR=true GIT-rebase-i--autosquash$COMMIT\u HASH~1
    
    看看这在哪里有用。除了下面的git rebase,git filter branch是另一个选项:谢谢,我们可能在类似的时间开始写答案,在我发布我的答案之前,我没有看到你的答案;-)我认为在每个会话或每个命令的基础上重新定义编辑器更简单。我强烈建议不要执行
    git config--取消设置所有
    或任何可以在脚本中修改用户配置文件的操作。要为一个命令设置git config变量,请使用
    git-c var=val
    ,在本例中,设置
    EDITOR
    要简单得多。它是一个环境变量,因此仅适用于当前进程,不会干扰其他进程或将任何内容写入磁盘。我发现设置
    EDITOR
    不再有效,我需要使用
    GIT\u EDITOR
    。或者,使用现有命令
    true
    ,而不是为此目的创建脚本,它忽略任何参数,并具有固定的返回代码
    0
    @me\u,这仅在您希望执行
    rebase-i
    而不实际重新排序提交时才有用。下面是另一个修复最后五条提交消息中键入错误的示例:
    EDITOR=“sed-i-e's/borken/
    
    # 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 "$@"
    }