All of lore.kernel.org
 help / color / mirror / Atom feed
* Your branch and 'origin/master' have diverged
@ 2012-08-13 19:58 Hilco Wijbenga
  2012-08-14  8:27 ` Thomas Rast
  2012-08-14 16:02 ` PJ Weisberg
  0 siblings, 2 replies; 20+ messages in thread
From: Hilco Wijbenga @ 2012-08-13 19:58 UTC (permalink / raw)
  To: Git Users

Hi all,

A colleague of mine (after a relatively long absence) noticed the
following when running "git status":

# On branch master
# Your branch and 'origin/master' have diverged,
# and have 250 and 19 different commit(s) each, respectively.
#
nothing to commit (working directory clean)

He asked me what to do and I told him to do what has always worked for
me in the past when something like this happened: gitk, "reset master
branch to here" (to a commit before the divergence and using --hard),
git pull origin master. Problem solved.

Well, not this one. This one is persistent. :-) I am at a loss what to
do. "master" and "origin/master" do *not* point at the same commit.
Even after the "git reset --hard ..." and "git pull". Running my
silver bullet solution gets us in the same situation every time.

I checked his .git/config and it looks fine.

Any ideas? What information should I provide that might make it
possible for you to help me?

Cheers,
Hilco

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

* Re: Your branch and 'origin/master' have diverged
  2012-08-13 19:58 Your branch and 'origin/master' have diverged Hilco Wijbenga
@ 2012-08-14  8:27 ` Thomas Rast
  2012-08-14 17:04   ` Hilco Wijbenga
  2012-08-14 16:02 ` PJ Weisberg
  1 sibling, 1 reply; 20+ messages in thread
From: Thomas Rast @ 2012-08-14  8:27 UTC (permalink / raw)
  To: Hilco Wijbenga; +Cc: Git Users

Hilco Wijbenga <hilco.wijbenga@gmail.com> writes:

> # On branch master
> # Your branch and 'origin/master' have diverged,
> # and have 250 and 19 different commit(s) each, respectively.
> #
> nothing to commit (working directory clean)
>
> He asked me what to do and I told him to do what has always worked for
> me in the past when something like this happened: gitk, "reset master
> branch to here" (to a commit before the divergence and using --hard),
> git pull origin master. Problem solved.

There are several layers of pitfalls and misunderstandings here.

* Is your work origin/master..master (that is, anything in master but
  not origin/master) really so worthless as to make "scrap it all!" the
  normal course of resolution?

  Or perhaps the real reason for the divergence is that upstream rewrote
  its master (eeeek!), in which case you should get them acquainted with
  the clue bat... and probably rebase instead of merge.

* pull = fetch + merge!  Repeat this a few times until it sinks in.
  Then print it on A0 and stick it up in your office or something.

  For your case this means that the pull command is roughly equivalent
  to

    git fetch origin master
    git merge FETCH_HEAD

  The two-arg form of fetch does *not* update origin/master.  Assuming
  you got the reset right, the merge will fast-forward to whatever
  origin's master points to -- but origin/master is still the old state!

* Resetting to something that you think will fast-forward, only to then
  fast-forward it to the newest state, is silly.  You can just reset to
  the newest state instead.

Taking all of this together, I think you should stop using two-arg
pull[*] or fetch, and replace your error-prone recipe with simply

  git fetch
  git reset --hard origin/master

Assuming, as before, that your local work is worthless.  Is it?
Otherwise it would be better to run something like

  git fetch
  git rebase origin/master


[*] it's ok if you use it with an URL instead of a remote nickname

-- 
Thomas Rast
trast@{inf,student}.ethz.ch

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

* Re: Your branch and 'origin/master' have diverged
  2012-08-13 19:58 Your branch and 'origin/master' have diverged Hilco Wijbenga
  2012-08-14  8:27 ` Thomas Rast
@ 2012-08-14 16:02 ` PJ Weisberg
  2012-08-14 17:07   ` Hilco Wijbenga
  1 sibling, 1 reply; 20+ messages in thread
From: PJ Weisberg @ 2012-08-14 16:02 UTC (permalink / raw)
  To: Hilco Wijbenga; +Cc: Git Users

On Mon, Aug 13, 2012 at 12:58 PM, Hilco Wijbenga
<hilco.wijbenga@gmail.com> wrote:
> Hi all,
>
> A colleague of mine (after a relatively long absence) noticed the
> following when running "git status":
>
> # On branch master
> # Your branch and 'origin/master' have diverged,
> # and have 250 and 19 different commit(s) each, respectively.
> #
> nothing to commit (working directory clean)
>
> He asked me what to do and I told him to do what has always worked for
> me in the past when something like this happened: gitk, "reset master
> branch to here" (to a commit before the divergence and using --hard),
> git pull origin master. Problem solved.
>
> Well, not this one. This one is persistent. :-) I am at a loss what to
> do. "master" and "origin/master" do *not* point at the same commit.
> Even after the "git reset --hard ..." and "git pull". Running my
> silver bullet solution gets us in the same situation every time.

I assume that the commit you reset to wasn't actually before the
divergence, then.  It sounds like what you're trying to do is just
long-hand for 'git reset --hard origin/master'.  As mentioned before,
that *does* assume that you want to throw out everything you've
committed locally.  If that's *not* the case, try 'git rebase
origin/master' or 'git pull --rebase'.  And then go slap the person
who rewrote the history of origin/master.

-PJ

Gehm's Corollary to Clark's Law: Any technology distinguishable from
magic is insufficiently advanced.

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

* Re: Your branch and 'origin/master' have diverged
  2012-08-14  8:27 ` Thomas Rast
@ 2012-08-14 17:04   ` Hilco Wijbenga
  2012-08-14 17:19     ` Junio C Hamano
  0 siblings, 1 reply; 20+ messages in thread
From: Hilco Wijbenga @ 2012-08-14 17:04 UTC (permalink / raw)
  To: Thomas Rast; +Cc: Git Users

On 14 August 2012 01:27, Thomas Rast <trast@student.ethz.ch> wrote:
> Hilco Wijbenga <hilco.wijbenga@gmail.com> writes:
>
>> # On branch master
>> # Your branch and 'origin/master' have diverged,
>> # and have 250 and 19 different commit(s) each, respectively.
>> #
>> nothing to commit (working directory clean)
>>
>> He asked me what to do and I told him to do what has always worked for
>> me in the past when something like this happened: gitk, "reset master
>> branch to here" (to a commit before the divergence and using --hard),
>> git pull origin master. Problem solved.
>
> There are several layers of pitfalls and misunderstandings here.
>
> * Is your work origin/master..master (that is, anything in master but
>   not origin/master) really so worthless as to make "scrap it all!" the
>   normal course of resolution?

Of course, it's master. Nobody should be working on master directly.

>   Or perhaps the real reason for the divergence is that upstream rewrote
>   its master (eeeek!), in which case you should get them acquainted with
>   the clue bat... and probably rebase instead of merge.

Upstream is fine. Nobody else is having any problems.

> * pull = fetch + merge!  Repeat this a few times until it sinks in.
>   Then print it on A0 and stick it up in your office or something.

Yes, I know.

>   For your case this means that the pull command is roughly equivalent
>   to
>
>     git fetch origin master
>     git merge FETCH_HEAD
>
>   The two-arg form of fetch does *not* update origin/master.  Assuming
>   you got the reset right, the merge will fast-forward to whatever
>   origin's master points to -- but origin/master is still the old state!

Ah, now we're getting to something I did *not* know. :-) So FETCH_HEAD
!= origin/master? I tried to find out more information about
FETCH_HEAD but there doesn't seem to be much. I have seen "FETCH_HEAD"
show up in the terminal but always just ignored it as a Git
implementation detail. When/how does origin/master get set then? I
always assumed that was part of git fetch and then git merge would
actually move master to origin/master.

> * Resetting to something that you think will fast-forward, only to then
>   fast-forward it to the newest state, is silly.  You can just reset to
>   the newest state instead.

:-) Well, yeah, now that you point it out... :-)

Still, just resetting ignores all the problems that led to the current
situation. Normally, when I reset and then FF I can be sure (if it
works) that things were not completely screwed up. At least, that has
always been my theory.

> Taking all of this together, I think you should stop using two-arg
> pull[*] or fetch, and replace your error-prone recipe with simply
>
>   git fetch
>   git reset --hard origin/master
>
> Assuming, as before, that your local work is worthless.  Is it?
> Otherwise it would be better to run something like
>
>   git fetch
>   git rebase origin/master
>
>
> [*] it's ok if you use it with an URL instead of a remote nickname

Why would that be okay? What is the difference? Isn't the nickname
just an alias for a URL?

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

* Re: Your branch and 'origin/master' have diverged
  2012-08-14 16:02 ` PJ Weisberg
@ 2012-08-14 17:07   ` Hilco Wijbenga
  0 siblings, 0 replies; 20+ messages in thread
From: Hilco Wijbenga @ 2012-08-14 17:07 UTC (permalink / raw)
  To: PJ Weisberg; +Cc: Git Users

On 14 August 2012 09:02, PJ Weisberg <pj@irregularexpressions.net> wrote:
> On Mon, Aug 13, 2012 at 12:58 PM, Hilco Wijbenga
> <hilco.wijbenga@gmail.com> wrote:
>> Hi all,
>>
>> A colleague of mine (after a relatively long absence) noticed the
>> following when running "git status":
>>
>> # On branch master
>> # Your branch and 'origin/master' have diverged,
>> # and have 250 and 19 different commit(s) each, respectively.
>> #
>> nothing to commit (working directory clean)
>>
>> He asked me what to do and I told him to do what has always worked for
>> me in the past when something like this happened: gitk, "reset master
>> branch to here" (to a commit before the divergence and using --hard),
>> git pull origin master. Problem solved.
>>
>> Well, not this one. This one is persistent. :-) I am at a loss what to
>> do. "master" and "origin/master" do *not* point at the same commit.
>> Even after the "git reset --hard ..." and "git pull". Running my
>> silver bullet solution gets us in the same situation every time.
>
> I assume that the commit you reset to wasn't actually before the
> divergence, then.

It was according to gitk.

> It sounds like what you're trying to do is just
> long-hand for 'git reset --hard origin/master'.  As mentioned before,
> that *does* assume that you want to throw out everything you've
> committed locally.  If that's *not* the case, try 'git rebase
> origin/master' or 'git pull --rebase'.  And then go slap the person
> who rewrote the history of origin/master.

I'm not convinced anything is wrong with origin/master. This
particular colleague is the only one with a problem. And not for the
first time. :-)

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

* Re: Your branch and 'origin/master' have diverged
  2012-08-14 17:04   ` Hilco Wijbenga
@ 2012-08-14 17:19     ` Junio C Hamano
  2012-08-14 18:32       ` Hilco Wijbenga
  0 siblings, 1 reply; 20+ messages in thread
From: Junio C Hamano @ 2012-08-14 17:19 UTC (permalink / raw)
  To: Hilco Wijbenga; +Cc: Thomas Rast, Git Users

Hilco Wijbenga <hilco.wijbenga@gmail.com> writes:

> On 14 August 2012 01:27, Thomas Rast <trast@student.ethz.ch> wrote:
>> Hilco Wijbenga <hilco.wijbenga@gmail.com> writes:
>>
>>> # On branch master
>>> # Your branch and 'origin/master' have diverged,
>>> # and have 250 and 19 different commit(s) each, respectively.
>>> #
>>> nothing to commit (working directory clean)
>>>
>>> He asked me what to do and I told him to do what has always worked for
>>> me in the past when something like this happened: gitk, "reset master
>>> branch to here" (to a commit before the divergence and using --hard),
>>> git pull origin master. Problem solved.
>>
>> There are several layers of pitfalls and misunderstandings here.
>>
>> * Is your work origin/master..master (that is, anything in master but
>>   not origin/master) really so worthless as to make "scrap it all!" the
>>   normal course of resolution?
>
> Of course, it's master. Nobody should be working on master directly.

What a strange thing to say.  When will 'master' ever be updated
then and how?

If you mean 'master' as the integration branch for everybody to meet
and make progress, it would be more common for everybody to be
working on his own topic branch until perfection of the topic,
concluded by merging the completed topic to master and pushing the
master out to update it, no?

>> * pull = fetch + merge!  Repeat this a few times until it sinks in.
>>   Then print it on A0 and stick it up in your office or something.
>
> Yes, I know.
>
>>   For your case this means that the pull command is roughly equivalent
>>   to
>>
>>     git fetch origin master
>>     git merge FETCH_HEAD
>>
>>   The two-arg form of fetch does *not* update origin/master.  Assuming
>>   you got the reset right, the merge will fast-forward to whatever
>>   origin's master points to -- but origin/master is still the old state!
>
> Ah, now we're getting to something I did *not* know. :-) So FETCH_HEAD
> != origin/master?
>
 I tried to find out more information about
> FETCH_HEAD but there doesn't seem to be much. I have seen "FETCH_HEAD"
> show up in the terminal but always just ignored it as a Git
> implementation detail. When/how does origin/master get set then? I
> always assumed that was part of git fetch and then git merge would
> actually move master to origin/master.

It could be "git fetch --help" is failing for you, but I am
reasonably sure most if not all of the above are answered there;
another thing something you may not have known :-).

>> Taking all of this together, I think you should stop using two-arg
>> pull[*] or fetch, and replace your error-prone recipe with simply
>>
>>   git fetch
>>   git reset --hard origin/master
>>
>> Assuming, as before, that your local work is worthless.  Is it?
>> Otherwise it would be better to run something like
>>
>>   git fetch
>>   git rebase origin/master

Yeah, the latter makes sense, and I think it is a safer superset of
the former.  If there is nothing of value on 'master', the rebase
might stop and give control back to the user, but the user can tell
it to skip the cruft that came from the old 'master'.

>> [*] it's ok if you use it with an URL instead of a remote nickname
>
> Why would that be okay? What is the difference? Isn't the nickname
> just an alias for a URL?

As long as you tell what refspecs to use on the command line, the
remote nickname behaves as "just an alias for a URL", so yes,
because Thomas is discussing "two-arg pull or fetch", one arg being
either nickname or URL and the other is an explicit refspec on the
command line, it would be okay because there is no difference in
that case.

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

* Re: Your branch and 'origin/master' have diverged
  2012-08-14 17:19     ` Junio C Hamano
@ 2012-08-14 18:32       ` Hilco Wijbenga
  2012-08-14 18:49         ` Junio C Hamano
  2012-08-14 20:12         ` Thomas Rast
  0 siblings, 2 replies; 20+ messages in thread
From: Hilco Wijbenga @ 2012-08-14 18:32 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Thomas Rast, Git Users

On 14 August 2012 10:19, Junio C Hamano <gitster@pobox.com> wrote:
> Hilco Wijbenga <hilco.wijbenga@gmail.com> writes:
>
>> On 14 August 2012 01:27, Thomas Rast <trast@student.ethz.ch> wrote:
>>> Hilco Wijbenga <hilco.wijbenga@gmail.com> writes:
>>>
>>>> # On branch master
>>>> # Your branch and 'origin/master' have diverged,
>>>> # and have 250 and 19 different commit(s) each, respectively.
>>>> #
>>>> nothing to commit (working directory clean)
>>>>
>>>> He asked me what to do and I told him to do what has always worked for
>>>> me in the past when something like this happened: gitk, "reset master
>>>> branch to here" (to a commit before the divergence and using --hard),
>>>> git pull origin master. Problem solved.
>>>
>>> There are several layers of pitfalls and misunderstandings here.
>>>
>>> * Is your work origin/master..master (that is, anything in master but
>>>   not origin/master) really so worthless as to make "scrap it all!" the
>>>   normal course of resolution?
>>
>> Of course, it's master. Nobody should be working on master directly.
>
> What a strange thing to say.  When will 'master' ever be updated
> then and how?

Well, yes, just before pushing, you'd work on master for a few
seconds. That doesn't really count. :-)

> If you mean 'master' as the integration branch for everybody to meet
> and make progress, it would be more common for everybody to be
> working on his own topic branch until perfection of the topic,
> concluded by merging the completed topic to master and pushing the
> master out to update it, no?

That's what I should have said. I assumed way too much context. I
don't think all neurons are firing yet. :-(

>>> * pull = fetch + merge!  Repeat this a few times until it sinks in.
>>>   Then print it on A0 and stick it up in your office or something.
>>
>> Yes, I know.
>>
>>>   For your case this means that the pull command is roughly equivalent
>>>   to
>>>
>>>     git fetch origin master
>>>     git merge FETCH_HEAD
>>>
>>>   The two-arg form of fetch does *not* update origin/master.  Assuming
>>>   you got the reset right, the merge will fast-forward to whatever
>>>   origin's master points to -- but origin/master is still the old state!
>>
>> Ah, now we're getting to something I did *not* know. :-) So FETCH_HEAD
>> != origin/master?
>>
>  I tried to find out more information about
>> FETCH_HEAD but there doesn't seem to be much. I have seen "FETCH_HEAD"
>> show up in the terminal but always just ignored it as a Git
>> implementation detail. When/how does origin/master get set then? I
>> always assumed that was part of git fetch and then git merge would
>> actually move master to origin/master.
>
> It could be "git fetch --help" is failing for you, but I am
> reasonably sure most if not all of the above are answered there;
> another thing something you may not have known :-).

I was actually looking at "git help merge" since "git help fetch"
would be a far too logical place for FETCH_HEAD information. ;-) As I
said, not all neurons seem to be firing yet.

Apparently, my understanding is mostly correct, though. FETCH_HEAD is
indeed origin/master (I mean the SHA1 in master's HEAD on origin) and
the "git merge" part of "git pull" eventually sets "my" origin/master.

>>> Taking all of this together, I think you should stop using two-arg
>>> pull[*] or fetch, and replace your error-prone recipe with simply
>>>
>>>   git fetch
>>>   git reset --hard origin/master
>>>
>>> Assuming, as before, that your local work is worthless.  Is it?
>>> Otherwise it would be better to run something like
>>>
>>>   git fetch
>>>   git rebase origin/master
>
> Yeah, the latter makes sense, and I think it is a safer superset of
> the former.  If there is nothing of value on 'master', the rebase
> might stop and give control back to the user, but the user can tell
> it to skip the cruft that came from the old 'master'.
>
>>> [*] it's ok if you use it with an URL instead of a remote nickname
>>
>> Why would that be okay? What is the difference? Isn't the nickname
>> just an alias for a URL?
>
> As long as you tell what refspecs to use on the command line, the
> remote nickname behaves as "just an alias for a URL", so yes,
> because Thomas is discussing "two-arg pull or fetch", one arg being
> either nickname or URL and the other is an explicit refspec on the
> command line, it would be okay because there is no difference in
> that case.

I suppose I'm not entirely clear on how this two step process is
"safer". Doing "git fetch" would seem to be harmless, right? So the
problem is with "git merge" but master should always be "behind"
origin/master so that "git merge" should just FF to origin/master
which *should* be completely safe. Does that make sense? Especially
given our use of master as an integration branch?

[Given the trouble I have with getting people to use Git properly, I
prefer things as simple as possible. :-) ]

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

* Re: Your branch and 'origin/master' have diverged
  2012-08-14 18:32       ` Hilco Wijbenga
@ 2012-08-14 18:49         ` Junio C Hamano
  2012-08-14 20:12         ` Thomas Rast
  1 sibling, 0 replies; 20+ messages in thread
From: Junio C Hamano @ 2012-08-14 18:49 UTC (permalink / raw)
  To: Hilco Wijbenga; +Cc: Thomas Rast, Git Users

Hilco Wijbenga <hilco.wijbenga@gmail.com> writes:

> I suppose I'm not entirely clear on how this two step process is
> "safer". Doing "git fetch" would seem to be harmless, right? So the
> problem is with "git merge" but master should always be "behind"
> origin/master so that "git merge" should just FF to origin/master
> which *should* be completely safe. Does that make sense? Especially
> given our use of master as an integration branch?
>
> [Given the trouble I have with getting people to use Git properly, I
> prefer things as simple as possible. :-) ]

Between the two procedures Thomas gave you, "fetch & rebase" is
safer than "fetch & reset --hard", exactly because it does not have
to rely on the validity of your "which should always be behind"
claim.

If it is behind, there won't be any difference, but if it is *not*,
the user will notice and won't lose his work on 'master' (which you
may argue that he shouldn't have done).  "rebase" will notice it.

The key for a procedure to be safe is not having to rely on the
claim of users such as "my history *should* always and already be
behind", and not silently lose information when these *should*s are
violated for whatever reason.  After all, if all these *should*s
were true, the user wouldn't have been having problems in the first
place and posting to the list asking for help in the first place ;-)

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

* Re: Your branch and 'origin/master' have diverged
  2012-08-14 18:32       ` Hilco Wijbenga
  2012-08-14 18:49         ` Junio C Hamano
@ 2012-08-14 20:12         ` Thomas Rast
  2012-08-14 20:49           ` Junio C Hamano
  2012-08-14 22:15           ` Hilco Wijbenga
  1 sibling, 2 replies; 20+ messages in thread
From: Thomas Rast @ 2012-08-14 20:12 UTC (permalink / raw)
  To: Hilco Wijbenga; +Cc: Junio C Hamano, Thomas Rast, Git Users

Hilco Wijbenga <hilco.wijbenga@gmail.com> writes:

> On 14 August 2012 10:19, Junio C Hamano <gitster@pobox.com> wrote:
>> Hilco Wijbenga <hilco.wijbenga@gmail.com> writes:
>>
>>> On 14 August 2012 01:27, Thomas Rast <trast@student.ethz.ch> wrote:
>>>> [git pull with two args] it's ok if you use it with an URL instead
>>>> of a remote nickname
>>>
>>> Why would that be okay? What is the difference? Isn't the nickname
>>> just an alias for a URL?
>>
>> As long as you tell what refspecs to use on the command line, the
>> remote nickname behaves as "just an alias for a URL", so yes,
>> because Thomas is discussing "two-arg pull or fetch", one arg being
>> either nickname or URL and the other is an explicit refspec on the
>> command line, it would be okay because there is no difference in
>> that case.
>
> I suppose I'm not entirely clear on how this two step process is
> "safer". Doing "git fetch" would seem to be harmless, right? So the
> problem is with "git merge" but master should always be "behind"
> origin/master so that "git merge" should just FF to origin/master
> which *should* be completely safe. Does that make sense? Especially
> given our use of master as an integration branch?
>
> [Given the trouble I have with getting people to use Git properly, I
> prefer things as simple as possible. :-) ]

I meant something else than Junio hinted at.  Saying

  git fetch origin master
  # or by extension
  git pull origin master

does not update the origin/* namespace, not even origin/master.  All
fetching happens only into FETCH_HEAD.  This leads to confusion such as
yours because origin/master and thus the upstream tracking displays will
not know about the change.

If you use it with an URL, such as one that might be sent with a pull
request:

} The following changes since commit 62bc83349d52be49b037d2c800a7f4064cfbc5b5:
} 
}   The sixth batch of topics graduated to 'master' (2012-04-27 14:12:56 -0700)
} 
} are available in the git repository at:
} 
}   https://github.com/git-l10n/git-po/ master

(I picked a random pull request from the l10n coordinator, Jiang Xin)
you would say

  git pull https://github.com/git-l10n/git-po/ master

and you would not have a reasonable expectation of git updating your
remotes/*, even if you had a remote 'l10n' that points at that exact
URL.  So you would not be confused if you pulled from there, but
l10n/master didn't move.


In some sense this is a really bad case of wrong UI design, because we
(this happens on #git a lot) have to teach users not to use the command
so they won't trip over this problem.  It would be better to fix the
real issue instead.  IIRC it was even on the 1.8.0 wishlist...

-- 
Thomas Rast
trast@{inf,student}.ethz.ch

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

* Re: Your branch and 'origin/master' have diverged
  2012-08-14 20:12         ` Thomas Rast
@ 2012-08-14 20:49           ` Junio C Hamano
  2012-08-15  6:59             ` Thomas Rast
  2012-08-14 22:15           ` Hilco Wijbenga
  1 sibling, 1 reply; 20+ messages in thread
From: Junio C Hamano @ 2012-08-14 20:49 UTC (permalink / raw)
  To: Thomas Rast; +Cc: Hilco Wijbenga, Git Users

Thomas Rast <trast@student.ethz.ch> writes:

> In some sense this is a really bad case of wrong UI design, because we
> (this happens on #git a lot) have to teach users not to use the command
> so they won't trip over this problem.  It would be better to fix the
> real issue instead.  IIRC it was even on the 1.8.0 wishlist...

Is it?

There already is a way to ask it to update the single tracking
branch while fetching; "git fetch origin master" that
unconditionally updates refs/remotes/origin/master without a way to
tell it not to do so will be a grave usability regression.

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

* Re: Your branch and 'origin/master' have diverged
  2012-08-14 20:12         ` Thomas Rast
  2012-08-14 20:49           ` Junio C Hamano
@ 2012-08-14 22:15           ` Hilco Wijbenga
  2012-08-14 22:35             ` Junio C Hamano
  1 sibling, 1 reply; 20+ messages in thread
From: Hilco Wijbenga @ 2012-08-14 22:15 UTC (permalink / raw)
  To: Thomas Rast; +Cc: Junio C Hamano, Git Users

On 14 August 2012 13:12, Thomas Rast <trast@student.ethz.ch> wrote:
> Hilco Wijbenga <hilco.wijbenga@gmail.com> writes:
>
>> On 14 August 2012 10:19, Junio C Hamano <gitster@pobox.com> wrote:
>>> Hilco Wijbenga <hilco.wijbenga@gmail.com> writes:
>>>
>>>> On 14 August 2012 01:27, Thomas Rast <trast@student.ethz.ch> wrote:
>>>>> [git pull with two args] it's ok if you use it with an URL instead
>>>>> of a remote nickname
>>>>
>>>> Why would that be okay? What is the difference? Isn't the nickname
>>>> just an alias for a URL?
>>>
>>> As long as you tell what refspecs to use on the command line, the
>>> remote nickname behaves as "just an alias for a URL", so yes,
>>> because Thomas is discussing "two-arg pull or fetch", one arg being
>>> either nickname or URL and the other is an explicit refspec on the
>>> command line, it would be okay because there is no difference in
>>> that case.
>>
>> I suppose I'm not entirely clear on how this two step process is
>> "safer". Doing "git fetch" would seem to be harmless, right? So the
>> problem is with "git merge" but master should always be "behind"
>> origin/master so that "git merge" should just FF to origin/master
>> which *should* be completely safe. Does that make sense? Especially
>> given our use of master as an integration branch?
>>
>> [Given the trouble I have with getting people to use Git properly, I
>> prefer things as simple as possible. :-) ]
>
> I meant something else than Junio hinted at.  Saying
>
>   git fetch origin master
>   # or by extension
>   git pull origin master
>
> does not update the origin/* namespace, not even origin/master.  All
> fetching happens only into FETCH_HEAD.  This leads to confusion such as
> yours because origin/master and thus the upstream tracking displays will
> not know about the change.

I'll say. Now I'm really confused.

If what you say is true then what is updating origin/master? I've been
using "git pull" daily for over a year and origin/master is definitely
getting updated (at least according to gitk).

Mmm, just to make sure we are all talking about the same
origin/master: I mean my local reference to the SHA1 of the commit
that is master's HEAD on origin. After I have run "git pull",  *my*
master and *my* origin/master point to the same commit. Or I'm
*really* confused. Or I've confused you by using incorrect
terminology. :-) Or by using the right terminology incorrectly. ;-)

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

* Re: Your branch and 'origin/master' have diverged
  2012-08-14 22:15           ` Hilco Wijbenga
@ 2012-08-14 22:35             ` Junio C Hamano
  0 siblings, 0 replies; 20+ messages in thread
From: Junio C Hamano @ 2012-08-14 22:35 UTC (permalink / raw)
  To: Hilco Wijbenga; +Cc: Thomas Rast, Git Users

Hilco Wijbenga <hilco.wijbenga@gmail.com> writes:

>> I meant something else than Junio hinted at.  Saying
>>
>>   git fetch origin master
>>   # or by extension
>>   git pull origin master
>>
>> does not update the origin/* namespace, not even origin/master.  All
>> fetching happens only into FETCH_HEAD.  This leads to confusion such as
>> yours because origin/master and thus the upstream tracking displays will
>> not know about the change.
>
> I'll say. Now I'm really confused.
>
> If what you say is true then what is updating origin/master? I've been
> using "git pull" daily for over a year and origin/master is definitely
> getting updated (at least according to gitk).

Now it is really the time for you to go back to "git fetch --help"
and read up on refspecs.

With

    $ git fetch origin

you are not telling "fetch" what to fetch, so it goes to your .git/config
and finds remote.origin section to find what refspec to use.  They
would say something like

	[remote "origin"]
        	url = ...
                fetch = refs/heads/*:refs/remotes/origin/*

meaning (see the manual) "fetch all the branches there, store them
with the corresponding name under  refs/remotes/origin".

With

    $ git fetch origin master

you are overiding the refspec in .git/config and explicitly saying
"I want to fetch the master branch, but do not want to update
anything with it".  It is a short-hand for

    $ git fetch origin refs/heads/master

which in turn is a short-hand for

    $ git fetch origin refs/heads/master:

If you wanted to update the tracking ref, you would use a refspec
with non-empty strings on the both sides of colon, i.e.

    $ git fetch origin master:refs/remotes/origin/master

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

* Re: Your branch and 'origin/master' have diverged
  2012-08-14 20:49           ` Junio C Hamano
@ 2012-08-15  6:59             ` Thomas Rast
  2012-08-15 17:30               ` Junio C Hamano
  2012-08-16 16:21               ` Jeff King
  0 siblings, 2 replies; 20+ messages in thread
From: Thomas Rast @ 2012-08-15  6:59 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Thomas Rast, Hilco Wijbenga, Git Users, Jeff King

Junio C Hamano <gitster@pobox.com> writes:

> Thomas Rast <trast@student.ethz.ch> writes:
>
>> In some sense this is a really bad case of wrong UI design, because we
>> (this happens on #git a lot) have to teach users not to use the command
>> so they won't trip over this problem.  It would be better to fix the
>> real issue instead.  IIRC it was even on the 1.8.0 wishlist...
>
> Is it?
>
> There already is a way to ask it to update the single tracking
> branch while fetching; "git fetch origin master" that
> unconditionally updates refs/remotes/origin/master without a way to
> tell it not to do so will be a grave usability regression.

Grave?  Do you have any data/use-cases to back that up with?

I have never had a need for a fetch that doesn't update the remote
namespace, nor heard anyone on IRC who has.  OTOH, I do have anecdotal
evidence in support of "the current state is confusing": this thread, or
the fact that Jan's IRC bot grew bot-quotes !fetch4/!pull4 that people
use to warn users of 'git pull origin master' (it's apparently very
common).


The 1.8.0 thread is here, and Peff even said he had a patch he uses in
his tree:

http://thread.gmane.org/gmane.comp.version-control.git/165720/focus=165758

There's even a newer thread suggesting the same:

http://thread.gmane.org/gmane.comp.version-control.git/192252

-- 
Thomas Rast
trast@{inf,student}.ethz.ch

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

* Re: Your branch and 'origin/master' have diverged
  2012-08-15  6:59             ` Thomas Rast
@ 2012-08-15 17:30               ` Junio C Hamano
  2012-08-15 18:38                 ` Holger Hellmuth (IKS)
  2012-08-15 19:22                 ` Junio C Hamano
  2012-08-16 16:21               ` Jeff King
  1 sibling, 2 replies; 20+ messages in thread
From: Junio C Hamano @ 2012-08-15 17:30 UTC (permalink / raw)
  To: Thomas Rast; +Cc: Hilco Wijbenga, Git Users, Jeff King

Thomas Rast <trast@student.ethz.ch> writes:

> Junio C Hamano <gitster@pobox.com> writes:
>
>> Thomas Rast <trast@student.ethz.ch> writes:
>>
>>> In some sense this is a really bad case of wrong UI design, because we
>>> (this happens on #git a lot) have to teach users not to use the command
>>> so they won't trip over this problem.  It would be better to fix the
>>> real issue instead.  IIRC it was even on the 1.8.0 wishlist...
>>
>> Is it?
>>
>> There already is a way to ask it to update the single tracking
>> branch while fetching; "git fetch origin master" that
>> unconditionally updates refs/remotes/origin/master without a way to
>> tell it not to do so will be a grave usability regression.
>
> Grave?  Do you have any data/use-cases to back that up with?

When I get a pull request from say Eric, I would:

	git fetch git-svn master
        git show-branch remotes/git-svn/master FETCH_HEAD

to see what happened since the last pull request on the other side.
He may have rebased (which is not necessarily a crime), or I may see
more commits in the output than what he lists in the request message
(which may indicate I may have missed an earlier pull request from
him).

Such a sanity check will stop working if the first "fetch" updated
my remotes/git-svn/master.  I would have to enable reflog for
tracking branch and do something like this:

	git show-branch remotes/git-svn/master@{1} remotes/git-svn/master

So I was correct in saying that without an easy escape hatch, such a
change would be a regression.

But I think I (and others) could just train fingers to do

	git fetch git-svn master:

as a workaround.

Updating Documentation/pull-fetch-param.txt would be a bear, though.
The documentation is stale in that it was written in the days back
when .git/remotes/ was the primary way to configure remotes, and was
not adjusted to use the termilology used in the [remote "where"]
section of the .git/config file (notice a mention of "'Pull: '
lines" there), so it needs cosmetic adjustment anyway, but the
semantics it spells is still up to date.  The current rule is very
simple and understandable.  You either say from the command line
exactly what should happen (refspec without colon is the same as the
refspec with colon at the end, meaning "do not track"; if you want
to track, you write what to update with the fetch), or we use the
configured refspec (which again spells what should happen).

The updated rule would be more complex.  If a remote nickname is
used, and a refspec given from the command line is without colon, a
new special rule overrides the current behaviour and tries to match
with a configured refspec.  You would need to desribe what happens
in that case.

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

* Re: Your branch and 'origin/master' have diverged
  2012-08-15 17:30               ` Junio C Hamano
@ 2012-08-15 18:38                 ` Holger Hellmuth (IKS)
  2012-08-15 19:07                   ` Junio C Hamano
  2012-08-15 19:22                 ` Junio C Hamano
  1 sibling, 1 reply; 20+ messages in thread
From: Holger Hellmuth (IKS) @ 2012-08-15 18:38 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Thomas Rast, Hilco Wijbenga, Git Users, Jeff King

Am 15.08.2012 19:30, schrieb Junio C Hamano:
> The current rule is very
> simple and understandable.  You either say from the command line
> exactly what should happen (refspec without colon is the same as the
> refspec with colon at the end, meaning "do not track"; if you want
> to track, you write what to update with the fetch), or we use the
> configured refspec (which again spells what should happen).

Couldn't a similar new rule just say that refspec <name> is a short for 
<name>:<name> ?

The exception would be in the case of a URL as remote, but that would 
not be surprising to anyone, as there is no obvious target for the update

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

* Re: Your branch and 'origin/master' have diverged
  2012-08-15 18:38                 ` Holger Hellmuth (IKS)
@ 2012-08-15 19:07                   ` Junio C Hamano
  0 siblings, 0 replies; 20+ messages in thread
From: Junio C Hamano @ 2012-08-15 19:07 UTC (permalink / raw)
  To: Holger Hellmuth (IKS); +Cc: Thomas Rast, Hilco Wijbenga, Git Users, Jeff King

"Holger Hellmuth (IKS)" <hellmuth@ira.uka.de> writes:

> Am 15.08.2012 19:30, schrieb Junio C Hamano:
>> The current rule is very
>> simple and understandable.  You either say from the command line
>> exactly what should happen (refspec without colon is the same as the
>> refspec with colon at the end, meaning "do not track"; if you want
>> to track, you write what to update with the fetch), or we use the
>> configured refspec (which again spells what should happen).
>
> Couldn't a similar new rule just say that refspec <name> is a short
> for <name>:<name> ?

Of course not.

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

* Re: Your branch and 'origin/master' have diverged
  2012-08-15 17:30               ` Junio C Hamano
  2012-08-15 18:38                 ` Holger Hellmuth (IKS)
@ 2012-08-15 19:22                 ` Junio C Hamano
  2012-08-16 16:24                   ` Jeff King
  1 sibling, 1 reply; 20+ messages in thread
From: Junio C Hamano @ 2012-08-15 19:22 UTC (permalink / raw)
  To: Thomas Rast; +Cc: Hilco Wijbenga, Git Users, Jeff King

Junio C Hamano <gitster@pobox.com> writes:

> Updating Documentation/pull-fetch-param.txt would be a bear, though.
> The documentation is stale in that it was written in the days back
> when .git/remotes/ was the primary way to configure remotes, and was
> not adjusted to use the termilology used in the [remote "where"]
> section of the .git/config file (notice a mention of "'Pull: '
> lines" there), so it needs cosmetic adjustment anyway, but the
> semantics it spells is still up to date.  The current rule is very
> simple and understandable.  You either say from the command line
> exactly what should happen (refspec without colon is the same as the
> refspec with colon at the end, meaning "do not track"; if you want
> to track, you write what to update with the fetch), or we use the
> configured refspec (which again spells what should happen).
>
> The updated rule would be more complex.  If a remote nickname is
> used, and a refspec given from the command line is without colon, a
> new special rule overrides the current behaviour and tries to match
> with a configured refspec.  You would need to desribe what happens
> in that case.

It would be something like this.

When you tell "git fetch" to fetch one or more refs from a
configured remote by explicitly listing them on the command line,
e.g.

    git fetch <remote> <name>...

each <name>... goes through the following process:

    - The <name> is turned into the full ref at the remote that
      starts from refs/ form by applying the usual fetch dwimmery
      (if <name> is a name of a branch, "refs/heads/<name>" would
      likely to be the one that is fetched).

    - Then, configured fetch refspecs for <remote> is looked up from
      remote.<remote>.fetch configuration variable(s), or "Pull: "
      line(s) of .git/remotes/<remote> file.

    - If the LHS of a refspec found in the previous step matches the
      full ref we computed in the first step, then the ref at the
      RHS of the refspec (i.e. remote tracking branch), if any, is
      updated.

If there is no configured refspecs that match the name given from
the command line, no remote tracking ref is updated.

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

* Re: Your branch and 'origin/master' have diverged
  2012-08-15  6:59             ` Thomas Rast
  2012-08-15 17:30               ` Junio C Hamano
@ 2012-08-16 16:21               ` Jeff King
  1 sibling, 0 replies; 20+ messages in thread
From: Jeff King @ 2012-08-16 16:21 UTC (permalink / raw)
  To: Thomas Rast; +Cc: Junio C Hamano, Hilco Wijbenga, Git Users

On Wed, Aug 15, 2012 at 08:59:02AM +0200, Thomas Rast wrote:

> I have never had a need for a fetch that doesn't update the remote
> namespace, nor heard anyone on IRC who has.  OTOH, I do have anecdotal
> evidence in support of "the current state is confusing": this thread, or
> the fact that Jan's IRC bot grew bot-quotes !fetch4/!pull4 that people
> use to warn users of 'git pull origin master' (it's apparently very
> common).
> 
> The 1.8.0 thread is here, and Peff even said he had a patch he uses in
> his tree:
> 
> http://thread.gmane.org/gmane.comp.version-control.git/165720/focus=165758
> 
> There's even a newer thread suggesting the same:
> 
> http://thread.gmane.org/gmane.comp.version-control.git/192252

Yeah, I have been running with that patch for ages, and it has never
been a problem for me. Of course, the problem cases are very specific
workflows that I do not happen to use. There are definitely regressions
for some workflows; the question is whether or not anybody is using
those workflows (and/or would be bothered to adapt to using the reflog
instead).

Also note that there are several test failures with the patch, but I
haven't investigated them (i.e., I don't know if the patch is buggy, if
it is breaking a test in a way that is different than the expected
regression, or if the test simply happens to depend on the current
behavior and should be fixed).

-Peff

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

* Re: Your branch and 'origin/master' have diverged
  2012-08-15 19:22                 ` Junio C Hamano
@ 2012-08-16 16:24                   ` Jeff King
  2012-08-16 17:57                     ` Junio C Hamano
  0 siblings, 1 reply; 20+ messages in thread
From: Jeff King @ 2012-08-16 16:24 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: Thomas Rast, Hilco Wijbenga, Git Users

On Wed, Aug 15, 2012 at 12:22:28PM -0700, Junio C Hamano wrote:

> > The updated rule would be more complex.  If a remote nickname is
> > used, and a refspec given from the command line is without colon, a
> > new special rule overrides the current behaviour and tries to match
> > with a configured refspec.  You would need to desribe what happens
> > in that case.
> 
> It would be something like this.
> 
> When you tell "git fetch" to fetch one or more refs from a
> configured remote by explicitly listing them on the command line,
> e.g.
> 
>     git fetch <remote> <name>...
> 
> each <name>... goes through the following process:
> 
>     - The <name> is turned into the full ref at the remote that
>       starts from refs/ form by applying the usual fetch dwimmery
>       (if <name> is a name of a branch, "refs/heads/<name>" would
>       likely to be the one that is fetched).
> 
>     - Then, configured fetch refspecs for <remote> is looked up from
>       remote.<remote>.fetch configuration variable(s), or "Pull: "
>       line(s) of .git/remotes/<remote> file.
> 
>     - If the LHS of a refspec found in the previous step matches the
>       full ref we computed in the first step, then the ref at the
>       RHS of the refspec (i.e. remote tracking branch), if any, is
>       updated.
> 
> If there is no configured refspecs that match the name given from
> the command line, no remote tracking ref is updated.

That is almost exactly what my patch does, except I am not sure that it
respects the "without a colon" bit from your first message. In other
words, any time it sees that we have fetched a ref from a particular
remote, it applies the mapping from the config and adds the result to
the list of refs to be updated.

-Peff

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

* Re: Your branch and 'origin/master' have diverged
  2012-08-16 16:24                   ` Jeff King
@ 2012-08-16 17:57                     ` Junio C Hamano
  0 siblings, 0 replies; 20+ messages in thread
From: Junio C Hamano @ 2012-08-16 17:57 UTC (permalink / raw)
  To: Jeff King; +Cc: Thomas Rast, Hilco Wijbenga, Git Users

Jeff King <peff@peff.net> writes:

> On Wed, Aug 15, 2012 at 12:22:28PM -0700, Junio C Hamano wrote:
>
>> > The updated rule would be more complex.  If a remote nickname is
>> > used, and a refspec given from the command line is without colon, a
>> > new special rule overrides the current behaviour and tries to match
>> > with a configured refspec.  You would need to desribe what happens
>> > in that case.
>> 
>> It would be something like this.
>> 
>> When you tell "git fetch" to fetch one or more refs from a
>> configured remote by explicitly listing them on the command line,
>> e.g.
>> 
>>     git fetch <remote> <name>...
>> 
>> each <name>... goes through the following process:
>>
>>     - The <name> is turned into the full ref at the remote that
>>       starts from refs/ form by applying the usual fetch dwimmery
>>       (if <name> is a name of a branch, "refs/heads/<name>" would
>>       likely to be the one that is fetched).
>> 
>>     - Then, configured fetch refspecs for <remote> is looked up from
>>       remote.<remote>.fetch configuration variable(s), or "Pull: "
>>       line(s) of .git/remotes/<remote> file.
>> 
>>     - If the LHS of a refspec found in the previous step matches the
>>       full ref we computed in the first step, then the ref at the
>>       RHS of the refspec (i.e. remote tracking branch), if any, is
>>       updated.
>> 
>> If there is no configured refspecs that match the name given from
>> the command line, no remote tracking ref is updated.
>
> That is almost exactly what my patch does, except I am not sure that it
> respects the "without a colon" bit from your first message.

Yeah, I forgot to repeat it in this message, but the above
three-bullet list needs the 0-th item

 - If <name> has already colon in it, following special case rules
   do not apply.

in front of it.

Even though I suspect the updated behaviour may be more useful for
casual users (while making the semantics a bit more difficult to
explain, like the above documentation update), it is a major
regression to existing users if it closes the last escape hatch, so
I guess with your patch we are almost there but not quite there yet.

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

end of thread, other threads:[~2012-08-16 17:58 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-08-13 19:58 Your branch and 'origin/master' have diverged Hilco Wijbenga
2012-08-14  8:27 ` Thomas Rast
2012-08-14 17:04   ` Hilco Wijbenga
2012-08-14 17:19     ` Junio C Hamano
2012-08-14 18:32       ` Hilco Wijbenga
2012-08-14 18:49         ` Junio C Hamano
2012-08-14 20:12         ` Thomas Rast
2012-08-14 20:49           ` Junio C Hamano
2012-08-15  6:59             ` Thomas Rast
2012-08-15 17:30               ` Junio C Hamano
2012-08-15 18:38                 ` Holger Hellmuth (IKS)
2012-08-15 19:07                   ` Junio C Hamano
2012-08-15 19:22                 ` Junio C Hamano
2012-08-16 16:24                   ` Jeff King
2012-08-16 17:57                     ` Junio C Hamano
2012-08-16 16:21               ` Jeff King
2012-08-14 22:15           ` Hilco Wijbenga
2012-08-14 22:35             ` Junio C Hamano
2012-08-14 16:02 ` PJ Weisberg
2012-08-14 17:07   ` Hilco Wijbenga

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.