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

Re: rebasing merges

From
Stephen Haberman <stephen@exigencecorp.com>
Date
Sep 23, 2008, 18:29 UTC
Message-ID
<20080923132916.b9603658.stephen@exigencecorp.com>
In-Reply-To
<20080923043039.bf380694.stephen@exigencecorp.com>
Show 5 quoted lines
> > That's beside the point though, as I firmly believe git should be more
> > helpful in this situation. If "git rebase -i -p" doesn't help you fix
> > the problems, I'll see what I can do to help.
> 
> That's very cool, thanks. I'll start writing a test now.

I've attached a test. You were both correct, `git rebase -i -p` keeps the merge intact and doesn't duplicate the commits. This is awesome.

So, I'm wondering what the best way to integrate this into our workflow is. Ideally, I think it would be great to just do:

    git pull --rebase --preserve-merges

Or even better just `git pull` with branch.x.rebase=true and branch.x.preserve-merges=true property (throw in a branch.autosetuppreservemerges and I'll be set, haha).

While `git fetch + git rebase -i -p` will work every time, it won't be fun to have the editor pop open, just exit it because we're not really doing an interactive rebase, we're just borrowing its more powerful rebase implementation, and repeat this each time a dev wants to do a pull. Or, tell them to do a "git pull --rebase" most of the time, until it screws up, then back up and do the other. Both doable, but not ideal.

I understand Johannes's scenario of rebasing the entire branch, and it looks like rebase--interactive already supports this as well--e.g. if you pass `-p`, you get our desired behavior, and if you don't pass `-p`, you get Johannes's desired behavior of merge squashing.

Given rebase--interactive seems to be a superset of the current rebase implementation, could the current rebase implementation just go away and instead become a non-interactive caller (e.g. just avoid popping up the editor with the pick list) of rebase--interactive's more powerful rebase logic?

(Disclaimer: I'm throwing the term "more powerful" around without really knowing whether that is true or not--for our scenario, it seems that way, but there could be other cases I don't know about where the current rebase implementation is superior to rebase--interactive's.)

Thanks, Stephen

#!/bin/sh # # Copyright (c) 2005 Amos Waterland #

test_description='git rebase should not destroy author information

This test runs git rebase and checks that the author information is not lost. ' . ./test-lib.sh

GIT_AUTHOR_EMAIL=bogus_email_address export GIT_AUTHOR_EMAIL

echo 'Setting up:
A1--A2  <-- origin/master
 \   \
  B1--M  <-- topic
   \
    B2  <-- origin/topic
'
test_expect_success 'prepare repository with topic branches' \
    'echo First > A &&
     git add A &&
     git-commit -m "Add A1" &&
     git checkout -b topic &&
     echo Second > B &&
     git add B &&
     git-commit -m "Add B1" &&
     git checkout -f master &&
     echo Third >> A &&
     git-commit -a -m "Modify A2" &&
     git clone ./. clone1 &&
     cd clone1 &&
     git checkout -b topic origin/topic &&
     git merge origin/master &&
     cd ..
     git clone ./. clone2
     cd clone2 &&
     git checkout -b topic origin/topic &&
     git merge origin/master &&
     cd .. &&
     git checkout topic &&
     echo Fourth >> B &&
     git commit -a -m "Modify B2"
'
# Blatant copy/paste from t3404-rebase-interactive.sh--needs cleaned up
echo "#!$SHELL_PATH" >fake-editor.sh
cat >> fake-editor.sh <<\EOF
case "$1" in
*/COMMIT_EDITMSG)
	test -z "$FAKE_COMMIT_MESSAGE" || echo "$FAKE_COMMIT_MESSAGE" > "$1"
	test -z "$FAKE_COMMIT_AMEND" || echo "$FAKE_COMMIT_AMEND" >> "$1"
	exit
	;;
esac
test -z "$EXPECT_COUNT" ||
	test "$EXPECT_COUNT" = $(sed -e '/^#/d' -e '/^$/d' < "$1" | wc -l) ||
	exit
test -z "$FAKE_LINES" && exit
grep -v '^#' < "$1" > "$1".tmp
rm -f "$1"
cat "$1".tmp
action=pick
for line in $FAKE_LINES; do
	case $line in
	squash|edit)
		action="$line";;
	*)
		echo sed -n "${line}s/^pick/$action/p"
		sed -n "${line}p" < "$1".tmp
		sed -n "${line}s/^pick/$action/p" < "$1".tmp >> "$1"
		action=pick;;
	esac
done
EOF

test_set_editor "$(pwd)/fake-editor.sh" chmod a+x fake-editor.sh

test_expect_failure 'rebase merge on moved topic' '
     cd clone1 &&
     git pull --rebase &&
     test $(git rev-list --all --pretty=oneline | grep "Modify A" | wc -l) = 1
'
test_expect_success 'rebase -i -p merge on moved topic' '
     cd ../clone2 &&
     git fetch &&
     FAKE_LINES="1 2" git rebase -i -p origin/topic &&
     test 1 = $(git rev-list --all --pretty=oneline | grep "Modify A" | wc -l) &&
     test 1 = $(git rev-list --all --pretty=oneline | grep "Merge commit" | wc -l)
'
test_done
Previous: Stephen HabermanNext: SZEDER Gábor
Message 13 of 14 in “rebasing merges”
  1. Stephen HabermanSep 22, 2008
  2. Stephen HabermanSep 23, 2008
  3. Johannes SixtSep 23, 2008
  4. Samuel TardieuSep 23, 2008
  5. Johannes SixtSep 23, 2008
  6. Andreas EricssonSep 23, 2008
  7. Stephen HabermanSep 23, 2008
  8. Johannes SixtSep 23, 2008
  9. Andreas EricssonSep 23, 2008
  10. Stephen HabermanSep 23, 2008
  11. Andreas EricssonSep 23, 2008
  12. Stephen HabermanSep 23, 2008
  13. Stephen HabermanSep 23, 2008
  14. SZEDER GáborSep 23, 2008

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.