From: Martin von Zweigbergk <martin.von.zweigbergk@gmail.com>
To: git@vger.kernel.org, trast@student.ethz.ch, santi@agolina.net,
newren@gmail.com
Cc: Martin von Zweigbergk <martin.von.zweigbergk@gmail.com>
Subject: [RFC] rebase: be cleverer with rebased upstream branches
Date: Fri, 12 Nov 2010 21:11:53 +0100 [thread overview]
Message-ID: <1289592713-11786-1-git-send-email-martin.von.zweigbergk@gmail.com> (raw)
Since c85c792 (pull --rebase: be cleverer with rebased upstream
branches, 2008-01-26), 'git pull --rebase' has used the reflog to try to
rebase from the old upstream onto the new upstream.
However, if, instead of 'git pull --rebase', the user were to do 'git
fetch' followed by 'git rebase @{upstream}', the reflog would not be
walked. This patch teaches "git rebase" the same reflog-walking tricks
that 'git pull --rebase' already knows.
Apart from making 'git rebase' better aligned with 'git pull --rebase',
this may also be useful on its own for rebasing one branch against
another local branch that has been rebased. Currently, you would have to
do that using 'git rebase --onto' or by configuring it on the branch.
It might seem like most of the related code in git-pull.sh can be
removed once git-rebase.sh supports reflog walking. Unfortunately, not
much of it can be removed, though. The reason is that git-pull.sh does
one step of 'reflog' walking even when the reflog is not used. There are
at least two cases where the reflog is not used: a) when it is disabled,
b) when the remote branch was specified on the command line (let's say
'git pull --rebase origin master'). In both of these cases, git-pull.sh
remembers the position of the reference before the fetch and uses that
in place of '$ref@{1}'.
---
Junio, don't apply this patch yet, as I will rebase it on top of the
refactored rebase code once I'm done with that (to make it work with
interactive rebase as well).
However, it should apply cleanly on top of the patches in
http://thread.gmane.org/gmane.comp.version-control.git/160682/, and maybe
even right on top of master.
The documentation was copied from git-pull before the patch on on that
documentation that I sent out a little while ago, so the documentation
for this patch will at the very least be updated accordingly.
Should the "RECOVERING FROM UPSTREAM REBASE" section of
Documentation/git-rebase.txt be updated?
Documentation/git-rebase.txt | 7 ++++++-
git-rebase.sh | 13 +++++++++++++
t/t3400-rebase.sh | 26 ++++++++++++++++++++++++++
3 files changed, 45 insertions(+), 1 deletions(-)
diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt
index 30e5c0e..1baddd2 100644
--- a/Documentation/git-rebase.txt
+++ b/Documentation/git-rebase.txt
@@ -24,7 +24,12 @@ it remains on the current branch.
All changes made by commits in the current branch but that are not
in <upstream> are saved to a temporary area. This is the same set
of commits that would be shown by `git log <upstream>..HEAD` (or
-`git log HEAD`, if --root is specified).
+`git log HEAD`, if --root is specified). If, however, there is a ref
+for the upstream branch, and this branch was rebased since the
+current branch was last rebased, the rebase uses that information to
+avoid rebasing changes done on the upstream branch. If you do not want
+'git rebase' to use this intelligence, refer to the upstream without
+using a reference (e.g. 'master~0').
The current branch is reset to <upstream>, or <newbase> if the
--onto option was supplied. This has the exact same effect as
diff --git a/git-rebase.sh b/git-rebase.sh
index 847555c..fade99a 100755
--- a/git-rebase.sh
+++ b/git-rebase.sh
@@ -495,6 +495,19 @@ case "$#" in
esac
orig_head=$branch
+test -n $upstream_name && for reflog in \
+ $(git rev-list -g $upstream_name 2>/dev/null)
+do
+ if test $reflog = $(git merge-base $reflog $branch)
+ then
+ if test $reflog != $(git merge-base $onto $reflog)
+ then
+ upstream=$reflog
+ fi
+ break
+ fi
+done
+
# Now we are rebasing commits $upstream..$branch (or with --root,
# everything leading up to $branch) on top of $onto
diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh
index 349eebd..b64df31 100755
--- a/t/t3400-rebase.sh
+++ b/t/t3400-rebase.sh
@@ -209,4 +209,30 @@ test_expect_success 'rebase -m can copy notes' '
test "a note" = "$(git notes show HEAD)"
'
+test_expect_success 'rebase against rebased upstream uses reflog' '
+ git checkout my-topic-branch &&
+ echo "Conflicting modification" > B &&
+ git add B &&
+ git commit -m "Modify B" &&
+ git reset --hard nonlinear &&
+ git checkout -b old-topic my-topic-branch@{1} &&
+ echo def > D &&
+ git add D &&
+ git commit -m "Add D" &&
+ git rebase my-topic-branch &&
+ test $(git rev-parse HEAD^) = $(git rev-parse my-topic-branch)
+'
+
+test_expect_success 'rebase against forwarded upstream does not reapply patches' '
+ git checkout my-topic-branch &&
+ echo abc > B &&
+ git add B &&
+ git commit -m "Conficting B" &&
+ git reset HEAD~2 &&
+ git reset HEAD@{1} &&
+ git checkout old-topic &&
+ git rebase my-topic-branch &&
+ test $(git rev-parse HEAD^) = $(git rev-parse my-topic-branch)
+'
+
test_done
--
1.7.3.2.167.ga361b
next reply other threads:[~2010-11-13 2:12 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-11-12 20:11 Martin von Zweigbergk [this message]
2010-11-13 23:30 ` [RFC] rebase: be cleverer with rebased upstream branches Santi Béjar
2010-11-14 2:46 ` Martin von Zweigbergk
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1289592713-11786-1-git-send-email-martin.von.zweigbergk@gmail.com \
--to=martin.von.zweigbergk@gmail.com \
--cc=git@vger.kernel.org \
--cc=newren@gmail.com \
--cc=santi@agolina.net \
--cc=trast@student.ethz.ch \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).