tracking branch for a rebase

14 messages, 7 authors, 2016-06-15 · open the first message on its own page

tracking branch for a rebase

From: Pete Wyckoff <hidden>
Date: 2016-06-15 22:47:21

I received an interesting question today.

If "git pull" knows what remote tracking brach to pull from,
why doesn't "git rebase" automatically know I want to rebase
on top of my remote tracking branch?

He had done a "git remote update", reviewed the changes, and now
wants to rebase his changes on top of the new upstream.

I told him about git pull --rebase, and branch.name.rebase,
but didn't have an easy answer to the "what is my remote tracking
branch" question in this case.

All the information is in git config branch.name.{remote,merge},
but I can't find anything that just answers that question.  Nor
did I have a good answer for why "git rebase" doesn't just default
to rebasing the current branch on top of the tracking branch.

Thoughts?

		-- Pete

Re: tracking branch for a rebase

From: Michael J Gruber <hidden>
Date: 2016-06-15 22:47:21

Pete Wyckoff venit, vidit, dixit 04.09.2009 15:54:
I received an interesting question today.

If "git pull" knows what remote tracking brach to pull from,
why doesn't "git rebase" automatically know I want to rebase
on top of my remote tracking branch?

He had done a "git remote update", reviewed the changes, and now
wants to rebase his changes on top of the new upstream.

I told him about git pull --rebase, and branch.name.rebase,
but didn't have an easy answer to the "what is my remote tracking
branch" question in this case.
I guess he knows that branch if he reviewed it... More seriously,

git for-each-ref --format='%(upstream)' refs/heads/hisbranch

will return the upstream of hisbranch.
All the information is in git config branch.name.{remote,merge},
but I can't find anything that just answers that question.  Nor
did I have a good answer for why "git rebase" doesn't just default
to rebasing the current branch on top of the tracking branch.
Maybe because nobody has cared. Doing a "git pull --rebase" is not
equivalent (it may fetch more refs), but close enough for many people.

There was an initiative by Dscho a while ago to introduce a shortcut for
the upstream, which was dwarfed by the lack reserved characters for
refnames. Maybe 1.7 time frame would be a good time to change this?

Making this the default for rebase without arguments may meet some
objections (oh no, I didn't mean to rebase), but I guess it's worth trying.

Michael

Re: tracking branch for a rebase

From: Jeff King <hidden>
Date: 2016-06-15 22:47:21

On Fri, Sep 04, 2009 at 04:31:57PM +0200, Michael J Gruber wrote:
Making [rebase against upstream] the default for rebase without
arguments may meet some objections (oh no, I didn't mean to rebase),
but I guess it's worth trying.
FWIW, that has been a patch I have been meaning to do for a while. I
don't see it as any more error-prone than "git pull" without arguments.
In either case, you can always recover with a reset from the reflog.

The biggest question is whether it should respect branch.*.merge, or
just branch.*.rebase (I never use the latter simply because I never use
"git pull", but I think it is probably reasonable to restrict it to
cases where you said you are interested in rebasing in general).

-Peff

Re: tracking branch for a rebase

From: Björn Steinbrink <hidden>
Date: 2016-06-15 22:47:21

On 2009.09.04 14:18:46 -0400, Jeff King wrote:
On Fri, Sep 04, 2009 at 04:31:57PM +0200, Michael J Gruber wrote:
quoted
Making [rebase against upstream] the default for rebase without
arguments may meet some objections (oh no, I didn't mean to rebase),
but I guess it's worth trying.
FWIW, that has been a patch I have been meaning to do for a while. I
don't see it as any more error-prone than "git pull" without arguments.
In either case, you can always recover with a reset from the reflog.
Note that with:
	branch.foo.remote = origin
	branch.foo.merge = refs/heads/foo

"git pull --rebase" is not the same as:
"git fetch origin && git rebase origin/foo", but:

git fetch origin && git rebase --onto origin/foo $reflog_merge_base

Where $reflog_merge_base is the first merge base is found between the
current branch head, and the reflog entries for origin/foo.


Same deal for "git pull --rebase origin bla", which is not:
"git fetch origin bla && git rebase FETCH_HEAD", but:

git fetch origin && git rebase --onto FETCH_HEAD $reflog_merge_base

Where again $reflog_merge_base is found by looking at the reflog for
origin/foo.

It does that to try to automatically handle cases where upstream has
been rebased. I'm not completely sure whether I like or hate that.
Especially the "git pull --rebase <remote> <refspec>" case seems very
weird to me. And if "rebase" is to pickup the same default as "pull", I
guess it should also show the same behaviour, but just skips the "fetch"
part?
The biggest question is whether it should respect branch.*.merge, or
just branch.*.rebase (I never use the latter simply because I never use
"git pull", but I think it is probably reasonable to restrict it to
cases where you said you are interested in rebasing in general).
Hm, you'll probably want "git merge" to pickup the default as well then,
right? And that should only do so if branch.*.rebase is not set. So
effectively, you still have to use the right command, but can skip the
argument. Having to deal a lot with git-svn, I also regulary use its
"git svn rebase --local", which means "just rebase, don't fetch".

Now, basically "git svn rebase" is pretty much git-svn's "pull". Maybe
its idea could be taken, so we get "git pull --local" to just skip the
fetch part, but keep "git rebase" and "git merge" 'dumb', requiring
explicit arguments.

(In the past, I once argued for deprecating "pull", and having
merge/rebase doing the fetch as well, with a --local argument that stops
them from doing so. That was probably mostly due to the fact that I ran
into too many people that simply didn't understood that "git pull" is
not "svn up". I still kind of like the idea, but seeing just how often I
use rebase/merge with already fetched stuff, I can see how having to use
a --local flag with them all the time would be quite a PITA, but now,
having the --local flag for "pull" seems to make sense to me.)

Björn

Re: tracking branch for a rebase

From: Jeff King <hidden>
Date: 2016-06-15 22:47:21

On Fri, Sep 04, 2009 at 08:59:49PM +0200, Björn Steinbrink wrote:
"git pull --rebase" is not the same as:
"git fetch origin && git rebase origin/foo", but:

git fetch origin && git rebase --onto origin/foo $reflog_merge_base

Where $reflog_merge_base is the first merge base is found between the
current branch head, and the reflog entries for origin/foo.
Thanks, I didn't know about the trick (not being, as I mentioned, a pull
--rebase user). I can see arguments for or against a rebase-default
using that feature. On one hand, it simplifies the explanation for
people going between "pull --rebase" and "fetch && rebase". And I think
it should generally Do What You Mean in the case that upstream hasn't
rebased. Are there cases you know of where it will do the wrong thing?

I don't know if people would be confused that "git rebase" does not
exactly default to "git rebase $upstream", which is at least easy to
explain.
quoted
The biggest question is whether it should respect branch.*.merge, or
just branch.*.rebase (I never use the latter simply because I never use
"git pull", but I think it is probably reasonable to restrict it to
cases where you said you are interested in rebasing in general).
Hm, you'll probably want "git merge" to pickup the default as well then,
right? And that should only do so if branch.*.rebase is not set. So
effectively, you still have to use the right command, but can skip the
argument. Having to deal a lot with git-svn, I also regulary use its
"git svn rebase --local", which means "just rebase, don't fetch".
I hadn't considered whether "git merge" should get a default. To be
honest, my intended use case was not really to replace pull, but as a
shorthand for running "git rebase -i". Upstream has the published
commits, so it is a nice shortcut to say "let me munge all of the
commits that I haven't published yet".

Of course the "published" status of those commits is not guaranteed
(they might have been published in another branch, your
tracking refs might not be up to date, etc) but I think it's a good rule
of thumb.

And by automating the shorthand we reduce the chance of errors. For
example, I usually base my topic branches from origin/master. But the
other day I happened to be building a new branch, jk/date, off of
lt/approxidate, salvaged from origin/pu. I did "git rebase -i
origin/master" and accidentally rewrote the early part of
lt/approxidate.
Now, basically "git svn rebase" is pretty much git-svn's "pull". Maybe
its idea could be taken, so we get "git pull --local" to just skip the
fetch part, but keep "git rebase" and "git merge" 'dumb', requiring
explicit arguments.
That wouldn't help me, because you can't "pull -i". :)

-Peff

Re: tracking branch for a rebase

From: Björn Steinbrink <hidden>
Date: 2016-06-15 22:47:21

On 2009.09.05 02:12:50 -0400, Jeff King wrote:
On Fri, Sep 04, 2009 at 08:59:49PM +0200, Björn Steinbrink wrote:
quoted
"git pull --rebase" is not the same as:
"git fetch origin && git rebase origin/foo", but:

git fetch origin && git rebase --onto origin/foo $reflog_merge_base

Where $reflog_merge_base is the first merge base is found between the
current branch head, and the reflog entries for origin/foo.
Thanks, I didn't know about the trick (not being, as I mentioned, a pull
--rebase user). I can see arguments for or against a rebase-default
using that feature. On one hand, it simplifies the explanation for
people going between "pull --rebase" and "fetch && rebase". And I think
it should generally Do What You Mean in the case that upstream hasn't
rebased. Are there cases you know of where it will do the wrong thing?

I don't know if people would be confused that "git rebase" does not
exactly default to "git rebase $upstream", which is at least easy to
explain.
For me, the confusion would arise from the fact that "git rebase"
(without args) would seem like a "pull --rebase" without the fetch, but
isn't. And to reducing the difference to just the fetch would require a
quite change in bahaviour.

Currently, when branch.<name>.merge is set:
"git rebase <upstream>" ==> Can't really be done with "pull --rebase"
"git pull --rebase [...]" ==> Can't be done with "rebase" alone.

Currently, "pull" is a convenience thing, and thus may do more magic,
while "rebase" is dumb, and needs arguments. Starting to add _different_
magic to rebase seems wrong to me.
And by automating the shorthand we reduce the chance of errors. For
example, I usually base my topic branches from origin/master. But the
other day I happened to be building a new branch, jk/date, off of
lt/approxidate, salvaged from origin/pu. I did "git rebase -i
origin/master" and accidentally rewrote the early part of
lt/approxidate.
Hm, I'd prefer a shorthand for "upstream for this branch", instead of
magic defaults.
quoted
Now, basically "git svn rebase" is pretty much git-svn's "pull". Maybe
its idea could be taken, so we get "git pull --local" to just skip the
fetch part, but keep "git rebase" and "git merge" 'dumb', requiring
explicit arguments.
That wouldn't help me, because you can't "pull -i". :)
I probably shouldn't tell anyone, as it's a crude hack, but "git pull
--rebase -s -i" does the trick... *hides*

Björn

Re: tracking branch for a rebase

From: Jeff King <hidden>
Date: 2016-06-15 22:47:21

On Sat, Sep 05, 2009 at 04:01:27PM +0200, Björn Steinbrink wrote:
quoted
And by automating the shorthand we reduce the chance of errors. For
example, I usually base my topic branches from origin/master. But the
other day I happened to be building a new branch, jk/date, off of
lt/approxidate, salvaged from origin/pu. I did "git rebase -i
origin/master" and accidentally rewrote the early part of
lt/approxidate.
Hm, I'd prefer a shorthand for "upstream for this branch", instead of
magic defaults.
The more I think about, the more I think that is the right solution.
Because magic defaults for "rebase -i" don't help when you want to do
"gitk $UPSTREAM..".

The previous discussion on the topic seems to be here:

  http://article.gmane.org/gmane.comp.version-control.git/113666

And apparently you and I both participated in the discussion, which I
totally forgot about.

Looks like the discussion ended with people liking the idea but not
knowing what the specifier should look like. Maybe tightening the ref
syntax a bit to allow more extensible "special" refs is a good v1.7.0
topic? I dunno.
quoted
That wouldn't help me, because you can't "pull -i". :)
I probably shouldn't tell anyone, as it's a crude hack, but "git pull
--rebase -s -i" does the trick... *hides*
OK, that's just sick. :)

-Peff

Re: tracking branch for a rebase

From: Junio C Hamano <hidden>
Date: 2016-06-15 22:47:22

Jeff King [off-list ref] writes:
quoted
Hm, I'd prefer a shorthand for "upstream for this branch", instead of
magic defaults.
The more I think about, the more I think that is the right solution.
Because magic defaults for "rebase -i" don't help when you want to do
"gitk $UPSTREAM..".

The previous discussion on the topic seems to be here:

  http://article.gmane.org/gmane.comp.version-control.git/113666

And apparently you and I both participated in the discussion, which I
totally forgot about.

Looks like the discussion ended with people liking the idea but not
knowing what the specifier should look like. Maybe tightening the ref
syntax a bit to allow more extensible "special" refs is a good v1.7.0
topic? I dunno.
At-mark currently is reserved for anything that uses reflog, but we can
say that it is to specify operations on refs (as opposed to caret and
tilde are to specify operations on object names).

It specifies what ref to work on with the operand on its left side (and an
empty string stands for "HEAD"), and what operation is done to it by what
is in {} on the right side of it.  This view is quite consistent with the
following existing uses of the notation:

	ref@{number}	-- nth reflog entry
        ref@{time}	-- ref back then
	@{-number}	-- nth branch switching

So perhaps ref@{upstream}, or any string that is not a number and cannot
be time, can trigger the magic operation on the ref with ref@{magic}
syntax?

Re: tracking branch for a rebase

From: Michael J Gruber <hidden>
Date: 2016-06-15 22:47:22

Junio C Hamano venit, vidit, dixit 07.09.2009 07:05:
Jeff King [off-list ref] writes:
quoted
quoted
Hm, I'd prefer a shorthand for "upstream for this branch", instead of
magic defaults.
The more I think about, the more I think that is the right solution.
Because magic defaults for "rebase -i" don't help when you want to do
"gitk $UPSTREAM..".

The previous discussion on the topic seems to be here:

  http://article.gmane.org/gmane.comp.version-control.git/113666

And apparently you and I both participated in the discussion, which I
totally forgot about.

Looks like the discussion ended with people liking the idea but not
knowing what the specifier should look like. Maybe tightening the ref
syntax a bit to allow more extensible "special" refs is a good v1.7.0
topic? I dunno.
At-mark currently is reserved for anything that uses reflog, but we can
say that it is to specify operations on refs (as opposed to caret and
tilde are to specify operations on object names).

It specifies what ref to work on with the operand on its left side (and an
empty string stands for "HEAD"), and what operation is done to it by what
is in {} on the right side of it.  This view is quite consistent with the
following existing uses of the notation:

	ref@{number}	-- nth reflog entry
        ref@{time}	-- ref back then
	@{-number}	-- nth branch switching

So perhaps ref@{upstream}, or any string that is not a number and cannot
be time, can trigger the magic operation on the ref with ref@{magic}
syntax?
Even @{} is not taken so far... Alternatively, most people associate '^'
with 'up', just the way we use it for "upwards parentship" ref^ (and
somewhat the way we use it for upwards/backwards tag reference
relationship resolving ref^{type}), so
@^
or
@{^}
would be an option. Read "at upstream" :)

Michael

Re: tracking branch for a rebase

From: Jeff King <hidden>
Date: 2016-06-15 22:47:22

On Sun, Sep 06, 2009 at 10:05:21PM -0700, Junio C Hamano wrote:
At-mark currently is reserved for anything that uses reflog, but we can
say that it is to specify operations on refs (as opposed to caret and
tilde are to specify operations on object names).
I assume you meant that @{} is reserved; my reading of the previous
discussion was that "foo@bar" is still valid.
It specifies what ref to work on with the operand on its left side (and an
empty string stands for "HEAD"), and what operation is done to it by what
is in {} on the right side of it.  This view is quite consistent with the
following existing uses of the notation:

	ref@{number}	-- nth reflog entry
        ref@{time}	-- ref back then
	@{-number}	-- nth branch switching

So perhaps ref@{upstream}, or any string that is not a number and cannot
be time, can trigger the magic operation on the ref with ref@{magic}
syntax?
I think using @{} is a reasonable extension format. It's easy to read
and syntactically obvious. We need to watch out for conflicts with
things that might be valid times, but that is an easy thing to check
when adding new keywords. The only danger would be some extension
specifier that used arbitrary input, but that would probably be prefixed
with a keyword (and I can't even think of an example extension that
would want arbitrary input).

My only two complaints with ref@{upstream} are (and I don't think either
is a show-stopper, but maybe something we can improve on).

  1. It is a nice abstraction, but it doesn't save typing in most cases.
     "origin" is shorter than "master@{upstream}". One of the desired
     features in the last thread was that it be very short (which isn't
     to say we can't introduce @{upstream} _now_ and add a shorter
     synonym later on).

  2. I assume @{upstream} will be equivalent to HEAD@{upstream}. What
     should it do? The most useful thing to me would be to find the
     upstream for the current branch. But that is actually quite
     different from how HEAD@{1} works, which looks at the reflog for
     HEAD and not the branch.

     Maybe this is an inconsistency we can live with. The features are,
     after all, only syntactically related. I was just hoping to keep
     things as simple as possible for users to understand (and they
     often take semantic clues from syntax).

And some final thinking out loud in this area (i.e., these ideas are, I
think, somewhat half baked):

We already have some reserved uppercase ref names like HEAD, FETCH_HEAD,
ORIG_HEAD, and MERGE_HEAD.  One option would be to declare all-caps
names as reserved and allow UPSTREAM for the feature in question. I can
think of two arguments against it:

 1. The obvious one, that somebody somewhere is using all-caps and we
    are breaking their setup.

 2. It is not syntactically obvious to the user that it is not a real
    ref, but rather a magic name. Users are accustomed to punctuation
    introducing magic, so @{upstream} is probably better in that regard.

So I think that is a bad idea. But what about allowing "ref aliases"?
Obviously a static one like "f" for "foo" is kind of lame. But if you
could use the extension syntax, like:

  git config refalias.% '@{upstream}'

then we can let people set up whatever shorthand they think is sane (and
without worrying about clobbering unlikely-but-allowed setups, since
they are in control of their setup).

Like I said, I am not sure that is not half-baked. ;)

-Peff

Re: tracking branch for a rebase

From: Johannes Schindelin <hidden>
Date: 2016-06-15 22:47:22

Hi,

On Mon, 7 Sep 2009, Jeff King wrote:
On Sun, Sep 06, 2009 at 10:05:21PM -0700, Junio C Hamano wrote:
quoted
	ref@{number}	-- nth reflog entry
        ref@{time}	-- ref back then
	@{-number}	-- nth branch switching

So perhaps ref@{upstream}, or any string that is not a number and cannot
be time, can trigger the magic operation on the ref with ref@{magic}
syntax?
I think using @{} is a reasonable extension format.
Sorry to enter this thread that late, but I did not realize that it 
touches my %<branch> work.

Your proposal leads to something like "master@{upstream}@{2.days.ago}", 
which looks ugly.  And it is much more to type.

I still think that it is not too-much asked for to require the 
"refs/heads/" prefix if somebody starts her branch names with "%".

Or did I miss something (as I do not have time to read long mails these 
days, I tend to read only the short, to-the-point ones; I allowed myself 
to only skim over the rest of your mail)?

Ciao,
Dscho

Re: tracking branch for a rebase

From: Michael J Gruber <hidden>
Date: 2016-06-15 22:47:22

Johannes Schindelin venit, vidit, dixit 07.09.2009 11:29:
Hi,

On Mon, 7 Sep 2009, Jeff King wrote:
quoted
On Sun, Sep 06, 2009 at 10:05:21PM -0700, Junio C Hamano wrote:
quoted
	ref@{number}	-- nth reflog entry
        ref@{time}	-- ref back then
	@{-number}	-- nth branch switching

So perhaps ref@{upstream}, or any string that is not a number and cannot
be time, can trigger the magic operation on the ref with ref@{magic}
syntax?
I think using @{} is a reasonable extension format.
Sorry to enter this thread that late, but I did not realize that it 
touches my %<branch> work.

Your proposal leads to something like "master@{upstream}@{2.days.ago}", 
which looks ugly.  And it is much more to type.

I still think that it is not too-much asked for to require the 
"refs/heads/" prefix if somebody starts her branch names with "%".

Or did I miss something (as I do not have time to read long mails these 
days, I tend to read only the short, to-the-point ones; I allowed myself 
to only skim over the rest of your mail)?
Solution needs to be:
- practical (short, clear)
- not too brutal (on existing users of legal "exotic" refnames)
- extensible (for later uses)

Michael
152 chars for Dscho :)

Re: tracking branch for a rebase

From: Julian Phillips <hidden>
Date: 2016-06-15 22:47:22

On Mon, 7 Sep 2009, Michael J Gruber wrote:
Solution needs to be:
- practical (short, clear)
- not too brutal (on existing users of legal "exotic" refnames)
- extensible (for later uses)
How about '/^' and 'ref/^'?  Since you can't create a ref ending / ...

-- 
Julian

  ---
When you ask a question, do you truly want to know the answer, or are you
merely flaunting your power?

   -- DMITRI HARKONNEN, Notes to My Sons

Re: tracking branch for a rebase

From: Jeff King <hidden>
Date: 2016-06-15 22:47:22

On Mon, Sep 07, 2009 at 11:29:50AM +0200, Johannes Schindelin wrote:
quoted
I think using @{} is a reasonable extension format.
Sorry to enter this thread that late, but I did not realize that it 
touches my %<branch> work.

Your proposal leads to something like "master@{upstream}@{2.days.ago}", 
which looks ugly.  And it is much more to type.

I still think that it is not too-much asked for to require the 
"refs/heads/" prefix if somebody starts her branch names with "%".
I don't have a problem with restricting branch names starting with "%".
However, I do think "%.." is a bit ugly to read. And I am somewhat
concerned that we are eating the last reasonable available
meta-character for this feature, which will make things even harder next
time somebody suggests a clever feature. Which is why the discussion
turned to a generic extension syntax.

I wonder if it is worth adding @{upstream} now, which is fairly safe,
letting it cook for a while, and then adding a "%" alias later after the
concept has proved itself (and people say "I like this feature, but it
really is too much to type").

-Peff
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help