git/list[1] front-page[2] threads[3] people[4] search[5] about
 

git rebase and merge commits

From
Dominique Quatravaux <domq@google.com>
Date
Oct 20, 2010, 16:45 UTC
Message-ID
<AANLkTikroNPehcyBsueCnJ5hR0idd3cBP4m1KNccdRqL@mail.gmail.com>

Hi all, I'm trying to write "git shove", a wrapper around git rebase --interactive that would turn this

# A---B---C---K targetbranch # / \ # D---E---F---G---H---I--J srcbranch

into this:

# A---B---C---I'---K' targetbranch # / \ # D---E---F---G---H'---J' srcbranch #

(ie I has been shoved into targetbranch).

It seemed to me that the first step should be to simply rebase I, H, and J (in this order) onto C. Unfortunately git rebase --interactive -p C proposes a git-rebase-todo that contains only "noop"; if I forcefully put this instead,

edit iiii I edit hhhh H edit jjjj J

it seems to me that the HEAD jumps backward to the original H on the second rebase step, instead of daisy-chaining H behind I. This is with git 1.7.3.1.

Here are the outputs of git log --graph --pretty=oneline --abbrev-commit at each rebase step:

1/3
* a810395 I
*   1cfccc7 H
|\
| * c477d4e C
| * 7002290 B
| * aa9f1d0 A
* | b614d31 G
* | 2ad4496 F
|/
* 0d512e9 E
* b6cbc2b D
2/3
*   1cfccc7 H
|\
| * c477d4e C
| * 7002290 B
| * aa9f1d0 A
* | b614d31 G
* | 2ad4496 F
|/
* 0d512e9 E
* b6cbc2b D
3/3
* 3a41a45 J
* a810395 I
*   1cfccc7 H
|\
| * c477d4e C
| * 7002290 B
| * aa9f1d0 A
* | b614d31 G
* | 2ad4496 F
|/
* 0d512e9 E
* b6cbc2b D
Is there a way to do a real rebase of a merge commit?

FWIW, here is the script I use to create my toy environment in the current directory:

function _make_commit() {
  echo "$1" > "$1"
  git add "$1"
  git commit -a -m "$1"
  git tag "$1" HEAD
}
function _prepare_merged_history() {
  git init
  _make_commit "D"
  git checkout -b targetbranch
  _make_commit "E"
  _make_commit "A"
  _make_commit "B"
  _make_commit "C"
  _make_commit "K"
  git checkout E
  git checkout -b srcbranch
  _make_commit "F"
  _make_commit "G"
  git merge  -m "H" C
  git tag H HEAD
  _make_commit "I"
  _make_commit "J"
}
function _git_rebase_todo_line() {
  echo -n "pick "
  git rev-list -n 1 --pretty=oneline --abbrev-commit --abbrev=7 "$1"
}
function _make_git_rebase_todo() {
  {
    _git_rebase_todo_line refs/tags/I
    _git_rebase_todo_line refs/tags/H
    _git_rebase_todo_line refs/tags/J
  } > git-rebase-todo
}

[ -d ".git" ] && exit _prepare_merged_history _make_git_rebase_todo

Thanks in advance,
-- 
  Dominique Quatravaux
  +41 79 609 40 72
Next: Jonathan Nieder
Message 1 of 5 in “git rebase and merge commits”
  1. Dominique QuatravauxOct 20, 2010
  2. Jonathan NiederOct 20, 2010
  3. Joshua JensenOct 20, 2010
  4. Joshua JensenOct 20, 2010
  5. Dominique QuatravauxOct 25, 2010

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.