How do I run git rebase --interactive in non-inter

2019-01-05 00:49发布

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.

7条回答
Fickle 薄情
2楼-- · 2019-01-05 01:06

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.

查看更多
该账号已被封号
3楼-- · 2019-01-05 01:07

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
4楼-- · 2019-01-05 01:17

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
查看更多
来,给爷笑一个
5楼-- · 2019-01-05 01:17

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"
查看更多
Explosion°爆炸
6楼-- · 2019-01-05 01:19

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.

查看更多
小情绪 Triste *
7楼-- · 2019-01-05 01:20

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
查看更多
登录 后发表回答