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

Is it possible to do following?

  1. Make git rebase --interactive to 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 rebase with the name of edited file.
  4. Go on with the usual rebase process.

Usecase: scripted rebasing of course. See how to re-order commits in Git non-interactively for example.

  • Difference between Contents of two SVN Branches
  • How to run a Nant task with Ant?
  • Bitbucket Webhooks
  • Alternatives to Git for Minecraft server backup/version control
  • git post-commit hook - script on committed files
  • How many repositories should I use to maintain my scripts under version control?
  • How to find the previous authors of all changed lines in git?
  • is there a hack for fully functional cross-platform shebang line?
  • 7 Solutions collect form web for “How do I run git rebase –interactive in non-interactive manner?”

    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.

    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.

    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.

    Expanding on pfalcon’s answer:

    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.

    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:

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

    I use this script (in add it allows to simplify commit splitting):

    #!/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
    

    Add an alias to your .gitconfig:

    [alias]
      autorebase = ! path_to_your_script
    

    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:

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

    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-interactive editor – that is an editor that accepts commands on stdin, you can work with --interactive in a non-interactive way 🙂
    I know for sure vim accepts commands, and so does the standard editor ed, ofcourse.

    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"
    

    You can use touch as the editor which will touch the file so it will appear modified. For example

    GIT_SEQUENCE_EDITOR=touch git rebase -i [commit]
    

    To alias it, given baseline as a tag I want to rebase against

    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.

    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.

    I also made it simpler and removed the t/split action
    and delete->drop conversion
    which IMO are out of this script’s scope.

    Git Baby is a git and github fan, let's start git clone.