git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* interactive rebase not rebasing
@ 2008-09-29  4:50 Stephen Haberman
  2008-09-29  6:42 ` Andreas Ericsson
  0 siblings, 1 reply; 9+ messages in thread
From: Stephen Haberman @ 2008-09-29  4:50 UTC (permalink / raw)
  To: git

[-- Attachment #1: Type: text/plain, Size: 2715 bytes --]

Hello,

Per the emails from me last week, I'm working in an environment with
shared topic branches and am trying to find a bullet-proof way for devs
to rebase their local commits after the topic branch has moved.

The easy approach would be to just let `git pull` create merge commits,
and I would have been done with this long ago, but I'm striving to get
rebasing to "just work" and avoid the ugliness of same-branch merge
commits. Cross-branch merge commits are cool, but not same-branch.

So, here's a crazy scenario we've ran into--a new release has hit
stable, with two devs working on the same topic branch, and both of them
merge. One wins, and the other has to rebase. Previously, this was
replaying commits, but with great tips from the list last week, `rebase
-i -p` is handling most scenarios.

However, not this one:

# A --C------            <-- origin/stable
#  \  |      \
#   B -- D -- E -- F     <-- origin/topic2
#    \|
#     g -- h             <-- topic2

topic2 is a dev that has locally merged stable in g, moved on in h, is
ready to push, but another dev already merged stable in E, and also
committed F.

If we do a `git pull --no-rebase`, the result is:

# A --C------            <-- origin/stable
#  \  |      \
#   B -- D -- E -- F     <-- origin/topic2
#    \|             \
#     g -- h ------- i   <-- topic2

But i is a same-branch merge, and we'd rather rebase to something like:

# A --C------            <-- origin/stable
#  \         \
#   B -- D -- E -- F     <-- origin/topic2
#                   \
#                    h'  <-- topic2

(...maybe g' in there if g resolved stable conflicts differently
E did them. I'm not sure, I haven't gotten there yet.)

However, currently, `git rebase -i -p origin/topic2` results in:

# A --C------            <-- origin/stable
#  \  |      \
#   B -- D -- E -- F     <-- origin/topic2
#    \|
#     g -- h             <-- topic2

Nothing has changed. g & h haven't moved...I can keep executing this
operation and the commits never make it on top of origin/topic2's F. 

Frustratingly, if I run non-interactive rebase, it works perfectly. But
I've got other cases (see earlier posts) that do need the interactive
rebase. Personally, I could probably make do with trying each and
seeing what happened, but I'm really trying to find a bullet proof
command/alias/script for devs to run and have it "just work".

I've attached a test that sets up the DAG as above and currently passes
by asserting the not-desired/unchanged-DAG result. The assert for the
desired result is commented out at the end.

Am I correct in asserting this is some sort of bug in the interactive
rebase such that g & h are not ending up on top of F?

Thanks,
Stephen



[-- Attachment #2: t3404b.sh --]
[-- Type: text/x-sh, Size: 2680 bytes --]

#!/bin/sh

test_description='rebase interactive does not rebase'

. ./test-lib.sh

test_expect_success 'setup' '
	echo "setup" >a &&
	git add a &&
	git commit -m "setup" &&
	git clone ./. server &&
	rm -fr server/.git/hooks &&
	git remote add origin ./server &&
	git config --add branch.master.remote origin &&
	git config --add branch.master.merge refs/heads/master &&
	git fetch &&

	git checkout -b stable master &&
	echo "setup.stable" >a &&
	git commit -a -m "stable" &&
	git push origin stable
'
#
# A --C------            <-- origin/stable
#  \  |      \
#   B -- D -- E -- F     <-- origin/topic2
#    \|             \
#     g -- h ------- i   <-- topic2
#
# Trying to push F..i
#
# merge-base(F, h) has two options: B and C
#
test_expect_success 'merging in stable with tricky double baserev does not fool the script' '
	# B: start our topic2 branch, and share it
	git checkout -b topic2 origin/stable &&
	git config --add branch.topic2.merge refs/heads/topic2 &&
	echo "commit B" >a.topic2 &&
	git add a.topic2 &&
	git commit -m "commit B created topic2" &&
	git push origin topic2 &&

	# C: now, separately, move ahead stable, and share it
	git checkout stable
	echo "commit C" >a &&
	git commit -a -m "commit C moved stable" &&
	git push origin stable &&

	# D: have another client commit (in this case, it is the server, but close enough) moves topic2
	cd server &&
	git checkout topic2 &&
	echo "commit D continuing topic2" >a.client2 &&
	git add a.client2 &&
	git commit -m "commit D by client2" &&

	# E: the same other client merges the moved stable
	git merge stable &&

	# F: the same other client moves topic2 again
	echo "commit F" >a.client2 &&
	git commit -a -m "commit F by client2" &&
	F_hash=$(git rev-parse HEAD) &&
	cd .. &&

	# g: now locally merge in the moved stable (even though our topic2 is out of date)
	git checkout topic2 &&
	git merge stable &&
	g_hash=$(git rev-parse HEAD) &&

	# h: advance local topic2
	echo "commit H" >a.topic2 &&
	git commit -a -m "commit H continues local fork" &&
	h_hash=$(git rev-parse HEAD) &&

	# i: make a new merge commit
	git pull --no-rebase &&
	i_hash=$(git rev-parse HEAD) &&

	# Watch merge rejected as something that should get rebased
	# ! git push origin topic2
	test "$i_hash $h_hash $F_hash" = "$(git rev-list --parents --no-walk HEAD)"

	# Now fix it the merge by rebasing it
	git reset --hard ORIG_HEAD &&
	GIT_EDITOR=: git rebase -i -p origin/topic2 &&
	h2_hash=$(git rev-parse HEAD) &&

	# Should be:
	# test "$h2_hash $F_hash" = "$(git rev-list --parents --no-walk HEAD)"
	# But is just:
	test "$h_hash $g_hash" = "$(git rev-list --parents --no-walk HEAD)"
	# Where did $F_hash go?
'

test_done


^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2008-10-01 21:27 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-09-29  4:50 interactive rebase not rebasing Stephen Haberman
2008-09-29  6:42 ` Andreas Ericsson
2008-10-01  6:03   ` Stephen Haberman
2008-10-01  7:50     ` Andreas Ericsson
2008-10-01 14:52       ` Stephen Haberman
2008-10-01 15:26         ` Andreas Ericsson
2008-10-01 17:13           ` Stephen Haberman
2008-10-01 18:31             ` Shawn O. Pearce
2008-10-01 21:26             ` Andreas Ericsson

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).