pull/fetch rename
Hi all,
While everyone is busy in two other UI threads, I figured I might as well toss up another (probably) controversial topic.
Especially on IRC, we see many people who are some combination of misunderstanding, misusing or overusing git-pull. I figure this is the result of several factors, notably
a) pull/push are not symmetric,
b) guides/tutorials recommend pull for situations where they shouldn't,
c) people blindly fire commands at git.
While the latter two are probably hopeless, I find (a) rather annoying. It breaks everyone's intuition of git-pull when they first see it. (I know that BK has a pull that also merges, but I gather from the manual [never used it] that you cannot do the equivalent of git-fetch in BK.)
As you probably guessed by now, here is an idea for a very aggressive transition plan to address (a) in four phases:
1. git-fetch gets options --merge/-m and --rebase that make it behave like (current) git-pull, but requiring explicit arguments. git-pull gets a new option --merge (-m) that only enforces presence of arguments.
2. git-pull refuses to do any work unless given either --merge or --rebase. Deprecation warnings for this start at the same time as (1.).
3. git-pull becomes a synonym for git-fetch.
4. git-fetch gives deprecation warnings that point the user to git-pull instead.
(1.) is probably harmless and could be put into any particular release. (2.) obviously breaks everyone's favourite script and needs to fall on a major release. (3.) should be delayed significantly from (2.) to allow time to expose such breakage, and similarly (4.) should be delayed after (3.) (or just ignored, but in any case git-pull would become the preferred spelling).
As you probably noticed, while 'git pull $remote $ref' only needs to be changed to 'git pull --merge $remote $ref', this leaves a gap at the current functionality of 'git pull' without arguments. Björn laid out a nice suggestion for a git-update in
http://article.gmane.org/gmane.comp.version-control.git/130679
briefly summarised as: git-update would cover what 'git pull' (without arguments) does right now. However, it could also be restricted to fast-forward updates by default (with per-branch configurability as with current git-pull).
Comments? Flames? Improvements?
Signature · 2 lines
Thomas Rast
trast@{inf,student}.ethz.chQuoted 10 lines · On Tuesday 20 October 2009 11:47:45 Thomas Rast wrote:
Especially on IRC, we see many people who are some combination of misunderstanding, misusing or overusing git-pull. I figure this is the result of several factors, notably
a) pull/push are not symmetric,
b) guides/tutorials recommend pull for situations where they shouldn't,
c) people blindly fire commands at git.
This may be minor, but also:
d) in mercurial, pull/push are symmetric, but fetch means pull+merge
Quoted 2 lines
As you probably guessed by now, here is an idea for a very aggressive transition plan to address (a) in four phases:
I would love to see this change, not because I get confused about pull/fetch (it honestly only took a few days to get used to), but because having push/pull be symmetric just is so much more conceptually pure / easier explain to co-workers / separation between orthogonal operations / satisfying to my inner perfectionist / etc.
Quoted 5 lines
1. git-fetch gets options --merge/-m and --rebase that make it behave like (current) git-pull, but requiring explicit arguments. git-pull gets a new option --merge (-m) that only enforces presence of arguments.
Quoted 8 lines
2. git-pull refuses to do any work unless given either --merge or --rebase. Deprecation warnings for this start at the same time as (1.).
3. git-pull becomes a synonym for git-fetch.
4. git-fetch gives deprecation warnings that point the user to git-pull instead.
Hmmm, maybe this would be better for easier transition; replace 2-4 above with:
2. git-pull learns --merge and gets a configuration option that allows turning auto-merging off (e.g. pull.merge = merge/yes (default), rebase, or no). This doesn't change any behavior by default, but allows individual users to essentially make pull == fetch, and is forward compatible with changes up to #4.
3. git-pull gives a deprecation warning if the configuration option is not set, but otherwise defaults to merge. To get rid of the warning, you can set it explicitly (one way or another).
4. The configuration option default changes to "no", and a helpful message is printed telling you that you can set the configuration option to merge to get the old behavior.
5. Drop deprecation messages. At this point, git fetch and git pull are identical, except git fetch never merges, regardless of the pull configuration setting.
This has a few nice properties:
* There is lots and lots of warning; this transition could happen slowly.
* Early on, it will be possible to make git pull have symmetric behavior
by default, which is the desired endgame.
* In the end, people who want "git pull" to always keep it's current
behavior can do so by setting the proper configuration variable.
* git fetch doesn't need to be deprecated (but could be).
Quoted 16 lines · Wesley J. Landaker
Quoted 10 lines · On Tuesday 20 October 2009 11:47:45 Thomas Rast wrote:
Especially on IRC, we see many people who are some combination of misunderstanding, misusing or overusing git-pull. I figure this is the result of several factors, notably
a) pull/push are not symmetric,
b) guides/tutorials recommend pull for situations where they shouldn't,
c) people blindly fire commands at git.
This may be minor, but also:
d) in mercurial, pull/push are symmetric, but fetch means pull+merge
Quoted 8 lines
Quoted 2 lines
As you probably guessed by now, here is an idea for a very aggressive transition plan to address (a) in four phases:
I would love to see this change, not because I get confused about pull/fetch (it honestly only took a few days to get used to), but because having push/pull be symmetric just is so much more conceptually pure / easier explain to co-workers / separation between orthogonal operations / satisfying to my inner perfectionist / etc.
Is making "pull" a symmetric opposite of "push" the ultimate goal?
Or is making (or rather "keeping") "pull" useful more important?
It is not even an attitude that values philosophy over utility.
Fundamentally, pull and push cannot be symmetric because nobody is sitting in front of the repository you are pushing into (that is what a "push" is; you push from outside the repository---otherwise you would be "pull"ing from inside it in the other direction), but you know you are sitting in the repository, ready to resolve potential conflicts, when you say "pull".
Your elaborate scheme to make "pull" into "fetch" and to force everybody to set a configuration variable to make it "pull" again sounds like a mindless mental masturbation to me. People who leave "pull.merge = no" will always have to say "pull --merge" or "pull --rebase", so you cannot even argue you are not forcing but giving them a choice.
And you are doing this for what gain? The only thing I can think of is "People who deliberately set 'pull.merge = yes' can no longer blame us for pull not being the opposite of push." I do not consider it as a gain.
I do not buy "People who set 'pull.merge = yes' now understand why pull touches their work tree, because they did it themselves" either. People blindly copy other people's configuration from random web pages without understanding. Besides, the next thing they will ask is "Why is there pull.merge but no push.merge? Wasn't push an opposite of pull?" and you are back to square one.
I would be much more sympathetic if the suggested approach were to make "push" more symmetric to "pull", or at least attempt to allow it to be, by giving it an option to update the associated work tree when it can [*1*].
But I do not know what to say when people say "push cannot update the work tree, so let's make pull not to update the work tree by default---it will make it much less useful so we will fix that regression with yet another configuration option". It's not even funny.
[Footnote]
*1* Obviously you cannot do this most of the time _if_ the work tree has an interactive user sitting in front of it, but in a repository that never allows a non-ff push, with a work tree that is never updated except by such a push, can reasonably be maintained to give an illusion of push being an opposite of pull by fast forwarding the work tree when the push updates HEAD.
Quoted 2 lines · Junio C Hamano
Quoted 1 line · Wesley J. Landaker
d) in mercurial, pull/push are symmetric, but fetch means pull+merge
Ugh. I can see how they arrived at hg-pull == git-fetch, but why on earth was the logical next step hg-fetch == git-pull?!
</aside>
Quoted 10 lines
Quoted 5 lines
I would love to see this change, not because I get confused about pull/fetch (it honestly only took a few days to get used to), but because having push/pull be symmetric just is so much more conceptually pure / easier explain to co-workers / separation between orthogonal operations / satisfying to my inner perfectionist / etc.
Is making "pull" a symmetric opposite of "push" the ultimate goal?
Or is making (or rather "keeping") "pull" useful more important?
Quoted 7 lines
It is not even an attitude that values philosophy over utility.
Fundamentally, pull and push cannot be symmetric because nobody is sitting in front of the repository you are pushing into (that is what a "push" is; you push from outside the repository---otherwise you would be "pull"ing from inside it in the other direction), but you know you are sitting in the repository, ready to resolve potential conflicts, when you say "pull".
Well, I'd rather not argue the little semantic details, but I think with the changes to disallow pushing into HEAD, push and fetch are as symmetric as it gets. Both are exactly and only about transmitting refs with their associated commits to the other side. Which one you pick only depends on which side you sit on.
OTOH pull is about merging. And we can repeat the "pull = fetch + merge" mantra to ourselves all we like, having pull as "the opposite of push" is conceptually much easier to understand and thus far easier to explain to new users.
Quoted 6 lines
And you are doing this for what gain? The only thing I can think of is "People who deliberately set 'pull.merge = yes' can no longer blame us for pull not being the opposite of push." I do not consider it as a gain.
I do not buy "People who set 'pull.merge = yes' now understand why pull touches their work tree, because they did it themselves" either.
[...]
Quoted 4 lines
But I do not know what to say when people say "push cannot update the work tree, so let's make pull not to update the work tree by default---it will make it much less useful so we will fix that regression with yet another configuration option".
There would not be a configuration option.
Really, the whole goal would be to make pull the opposite of push. No exceptions, and most certainly no little loopholes to escape into the merging behaviour by default. The current 'git pull' behaviour would either be obtained through a new command, or through an explicit switch.
Quoted 3 lines
I would be much more sympathetic if the suggested approach were to make "push" more symmetric to "pull", or at least attempt to allow it to be, by giving it an option to update the associated work tree when it can [*1*].
[...]
Quoted 6 lines
*1* Obviously you cannot do this most of the time _if_ the work tree has an interactive user sitting in front of it, but in a repository that never allows a non-ff push, with a work tree that is never updated except by such a push, can reasonably be maintained to give an illusion of push being an opposite of pull by fast forwarding the work tree when the push updates HEAD.
Well, that reminds me of
http://thread.gmane.org/gmane.comp.version-control.git/110251
but was not really what I was aiming at.
Quoted 1 line
It's not even funny.
It was an RFC, not a joke ;-)
Signature · 2 lines
Thomas Rast
trast@{inf,student}.ethz.chQuoted 5 lines · Thomas Rast
Well, that reminds me of
http://thread.gmane.org/gmane.comp.version-control.git/110251
but was not really what I was aiming at.
Actually, if that patch weren't marked as [DRY HUMOR PATCH], and if it did not have the detachInstead option, I would have at least queued it to 'pu', if not 'next'.
Quoted 6 lines · Thomas Rast
Quoted 1 line · Junio C Hamano
"Wesley J. Landaker" <[email protected]> writes:
...
There would not be a configuration option.
...Quoted 1 line
It's not even funny.
Re-read what you were responding to and notice that I was commenting on Wesley's proposal that _is_ about a configuration variable.
Quoted 4 lines · On Tuesday 20 October 2009 17:11:32 Junio C Hamano wrote:
Quoted 3 lines · Thomas Rast
Quoted 1 line · Junio C Hamano
"Wesley J. Landaker" <[email protected]> writes:
Quoted 8 lines
Quoted 5 lines
...
There would not be a configuration option.
...Quoted 1 line
It's not even funny.
Re-read what you were responding to and notice that I was commenting on Wesley's proposal that _is_ about a configuration variable.
Yes, I brought up the configuration variable, not Thomas.
My main goal was to try to suggest a transition plan that would be less painful, but maybe it was actually worse. After reading Junio's response I think I agree that going down that path might be the worst of both worlds, but the basic model I was proposing (even if it's a bad idea in this case) was largely basing on (my perceived impression of) how the recent changes to push behavior were staged (i.e. with deprecation, new configuration variables, etc).
I still think that, long term, making push and pull symmetric, EITHER by 1) making push also update the working tree (in some sane way that I don't have a proposal for) or 2) making pull be just about transfering objects, not also merging (in some reasonable way that doesn't break useability, like also adding "git update" or something at the same time) would be an overall benefit.
Quoting Thomas Rast <[email protected]>
Quoted 34 lines
Especially on IRC, we see many people who are some combination of misunderstanding, misusing or overusing git-pull. I figure this is the result of several factors, notably
a) pull/push are not symmetric,
b) guides/tutorials recommend pull for situations where they shouldn't,
c) people blindly fire commands at git.
While the latter two are probably hopeless, I find (a) rather annoying. It breaks everyone's intuition of git-pull when they first see it. (I know that BK has a pull that also merges, but I gather from the manual [never used it] that you cannot do the equivalent of git-fetch in BK.)
As you probably guessed by now, here is an idea for a very aggressive transition plan to address (a) in four phases:
1. git-fetch gets options --merge/-m and --rebase that make it behave like (current) git-pull, but requiring explicit arguments. git-pull gets a new option --merge (-m) that only enforces presence of arguments.
2. git-pull refuses to do any work unless given either --merge or --rebase. Deprecation warnings for this start at the same time as (1.).
3. git-pull becomes a synonym for git-fetch.
4. git-fetch gives deprecation warnings that point the user to git-pull instead.
Quoted 6 lines
(1.) is probably harmless and could be put into any particular release. (2.) obviously breaks everyone's favourite script and needs to fall on a major release. (3.) should be delayed significantly from (2.) to allow time to expose such breakage, and similarly (4.) should be delayed after (3.) (or just ignored, but in any case git-pull would become the preferred spelling).
Sorry, but I don't understand what's the improvement in the end result.
I started reading your problem description and I thought you are fixing your item 'a) pull/push are not symmetric' by deprecating pull, to advertize fetch/push. Then asymmetry of push/pull stops being an issue.
But it seems that eventually you will keep git-push and git-pull (because git-fetch gets deprecated); you have push/pull that are not symmetric.
What's the point of this change then?
Signature · 2 lines
Nanako Shiraishi http://ivory.ap.teacup.com/nanako3/
Quoted 18 lines · Nanako Shiraishi
Quoting Thomas Rast <[email protected]>
Quoted 5 lines
1. git-fetch gets options --merge/-m and --rebase that make it behave like (current) git-pull, but requiring explicit arguments. git-pull gets a new option --merge (-m) that only enforces presence of arguments.
Quoted 8 lines
2. git-pull refuses to do any work unless given either --merge or --rebase. Deprecation warnings for this start at the same time as (1.).
3. git-pull becomes a synonym for git-fetch.
4. git-fetch gives deprecation warnings that point the user to git-pull instead.
Sorry, but I don't understand what's the improvement in the end result.
Quoted 8 lines
I started reading your problem description and I thought you are fixing your item 'a) pull/push are not symmetric' by deprecating pull, to advertize fetch/push. Then asymmetry of push/pull stops being an issue.
But it seems that eventually you will keep git-push and git-pull (because git-fetch gets deprecated); you have push/pull that are not symmetric.
By the time I get to that step, new-pull is current-fetch. So by that time, push/pull *are* supposedly symmetric.
(Only deprecating pull never occurred to me, but then I really think the strong association between them makes it worth keeping pull as the opposite of push.)
Signature · 2 lines
Thomas Rast
trast@{inf,student}.ethz.chQuoted 10 lines · Thomas Rast
Hi all,
While everyone is busy in two other UI threads, I figured I might as well toss up another (probably) controversial topic.
Especially on IRC, we see many people who are some combination of misunderstanding, misusing or overusing git-pull. I figure this is the result of several factors, notably
a) pull/push are not symmetric,
In a certain sense they are; they both update the branches local to one repository with the data from the other repository. In this sense, fetch is the oddity in that it doesn't update any repository's own branches, but just the local information about other repositories' branches.
In another sense, push is unlike anything else in that it updates something that's remote; in a third sense, pull is unique in that it can generate a merge.
I suspect that what we've called "fetch" isn't what the people want when they type "pull", either. And I suspect that the fundamental issue is that the operation people are looking for is not the operation that they would do best to use, regardless of naming. I think users are looking for something that corresponds to "svn up", and they find "git pull"; this isn't going to make them happy git users, but finding "git fetch" instead is going to make them even more confused.
But I don't really know; are there IRC logs you can quote or reference with people making the mistake you're trying to help them avoid?
-Daniel
*This .sig left intentionally blank*
Quoted 2 lines · Daniel Barkalow
But I don't really know; are there IRC logs you can quote or reference with people making the mistake you're trying to help them avoid?
"git pull" is kind of a jack of all trades WRT user errors, so I'll just pick up examples of all kinds, this might get long...
[If you read this and find out that you're quoted/referenced here: I don't mean to blame or embarrass you, or to point out that you're stupid or whatever. Quite contrary, I just want to show how git's pull UI _might_ be responsible for your mistakes. The comments I made are purely my, possibly biased, reaction to what happened.]
That said, here we go:
1) Unexpected fast-forward even with --no-ff
"git pull --no-ff abc:abc" with "abc" being checked out.
As pull explicitly allows fetches into the checked out branch head, this first fast-forwards abc, and updates the working tree/index. And then the --no-ff merge is a no-op.
http://colabti.de/irclogger/irclogger_log/git?date=2009-10-20#l2080
(Should be a catchable special case, and the special --update-head-ok handling of "git pull" is from times where git didn't have remote tracking branches. I'd argue that that support should be dropped or at least disabled when you're using the modern setup, might be kept for oldtimers still using .git/remotes/*. Dunno...)
2) "git pull" taken as "reset --hard"
git checkout -b foo; git pull origin bar
The user actually just wanted to look at things and thus was ok with:
git fetch origin; git checkout origin/bar
http://colabti.de/irclogger/irclogger_log/git?date=2009-10-20#l1807
(user seemed to be so inclined to use "pull" that he initially didn't even realize that he didn't want to merge when I asked whether that's what he wants)
3) User expects "pull" to update all branch heads that have a configured upstream
08:31 dimsuz hi guys! suppose i'm currently on master. then run git
fetch. which delivers updates to master and other branches. I don't merge anything, but do checkout some branch (which is not master). Question: will these new updates get into this branch automatically after i check it out? question2: will branch master contain those updates when i ckeck it out later?
08:32 Circuitsoft dimsuz. After a fetch, no.
08:33 Circuitsoft However, if you pull, any branches that were set
up as local tracking branches will get updated.
08:33 Circuitsoft Otherwise, only remote tracking branches will be
updated.
http://colabti.de/irclogger/irclogger_log/git?date=2009-10-20#l969
(No idea about that one, have seen that once before, but it's definitely not even remotely as common as the others)
4) User expects "pull" to create branches
07:25 fynn Hey, I just pulled a branch from remote, and I don't see
it in "git branch"
07:25 doener fynn: if you "pull" that means "fetch this and merge it
to what I have checked out"
07:25 fynn doener: hm, I just did "git pull" and it showed the new
branch
07:26 fynn but I don't see it in my branches...
07:26 fynn doener: should I create that branch as a tracking branch
first?
07:26 doener fynn: you're looking at "git branch -r" or "git branch
-a", right?
07:26 fynn doener: yeah, I'm seeing it in origin/foo, but not
local.
07:26 doener fynn: the "git fetch" should have created a remote
tracking branch, as usual, not a local branch head (which would be shown by just "git branch")
07:27 fynn doener: OK, what should I do to create it locally then?
07:28 doener fynn: just the usual "git branch foo origin/foo", or to
checkout at the same time: "git checkout -b foo origin/foo" or "git checkout -t origin/foo" (shortcut)
http://colabti.de/irclogger/irclogger_log/git?date=2009-10-19#l830
(Note how my "fetch this and merge it" is actually inaccurate for just "git pull", there is no "this" and that case. I took "pulled a branch" to mean that he did "git pull <remote> <branch>", which wouldn't have created/update the remote tracking branch [or did patches for that go in? I lost track...])
4b) User expects pull to create a branch head
09:58 araujo git pull origin <new_branch>
09:58 araujo will get me the new branch from repo right?
10:00 charon araujo: no, that will fetch *and merge* that branch
10:00 araujo charon, how to just pull?
http://colabti.de/irclogger/irclogger_log/git?date=2009-10-19#l1152
(Note how he asked "how to just pull?", even after being told that pull isn't what he wants)
5) User possibly expecting "pull" to be able to act as "reset --hard"
21:01 aidan What do I do about this: html/config/core.php: needs
update
21:02 aidan git pull (gives that)
21:02 Ilari aidan: You have uncommitted changes to that file...
21:15 aidan Ilari: how can I just pull master and overwrite any
changes?
http://colabti.de/irclogger/irclogger_log/git?date=2009-10-18#l2130
(I'm not sure about that one, "overwrite any changes" might mean "drop uncommitted changes and merge" or "just get me the remote's state, dropping my commits and uncommitted changes". Most of the time I've seen similar requests, the user wanted the latter).
6) User says "pull" but probably means "fetch"
14:08 Alien_Freak once I have a clone of a repo I know you can do
a checkout tag but is there anyway to pull just the tag?
http://colabti.de/irclogger/irclogger_log/git?date=2009-10-16#l1664
(There was no answer, thus it's hard to tell, but I guess he wanted something like:
git init; git fetch --no-tags url tag <tag>; git checkout <tag> At least I'm quite sure he didn't mean "pull" as in "git pull")
7) User expecting "pull" to just do fast-forwards (or so)
13:18 ohadlevy I'm getting a merge commit message after each
time i do git pull, i didnt have it before, where should I look?
13:20 charon ohadlevy: pull merges; you may just have hit lucky so
far, and always had a fast-forward merge
13:20 ohadlevy charon: any way I could avoid these commits?
just rebasing? its a pure RO repo
http://colabti.de/irclogger/irclogger_log/git?date=2009-10-16#l1579
(Apparently, user was tricked by the fast-forward behaviour he experienced earlier. I don't see any solution to this, except for defaulting to fast-forward-only and requiring a --merge flag (which might imply --no-ff), but I'm likely influenced by the "git update" stuff here)
8) "reset --hard" again
20:10 roger_padactor i commited then did a pull how do i get back to
my commit. the pull over wrote the files
20:11 merlin83 roger_padactor: you can't, pull == fetch + hard
reset to latest commit
http://colabti.de/irclogger/irclogger_log/git?date=2009-10-14#l2306
(Someone being told that pull is fetch + reset --hard is actually new to me. Only saw that as an expectation previously.)
9) More "git pull <remote> A:A"
19:10 _hp_ another question, how do I add the remote branch to
track so I don't have to constantly do git pull origin masterA:masterA ?
19:11 Ilari _hp_: Don't use that src:dest with pull!
(discussion died)
http://colabti.de/irclogger/irclogger_log/git?date=2009-10-12#l2427
10) "pull" mistaken for "cvs update"
07:25 Avrem how do I use "git pull" to do something like what "cvs
update" does ?
07:25 Avrem which is, replaces files I've deleted
07:25 Avrem from that from the central repository
07:30 omega I'm not sure, but can't you git checkout <deleted files>
to get them back?
http://colabti.de/irclogger/irclogger_log/git?date=2009-10-11#l545
(This adds a new twist to the "scm update" stuff, although svn/hg don't seem to have "restore individual files" in their "update" command, so this might be cvs-only. But it's so long since I used cvs, I don't even know whether this is correct. But it somehow got me thinking about how "update" is actually also "downgrade" in svn/hg, something git does via "checkout" [which happens to make more sense to me]. And I think it shows how "git pull" is taken to mean "update", even when ignoring the special behaviour described here. It's not taken to mean "merge this", but just "update to upstream").
So that's ten days of #git. I left out a bunch of duplications (most were "pull == fetch", "pull == update" and "pull to update non-checked-out branch").
Björn
Quoted 3 lines · Björn Steinbrink
So that's ten days of #git. I left out a bunch of duplications (most were "pull == fetch", "pull == update" and "pull to update non-checked-out branch").
Interesting; this shows that people who do not understand what "pull" does expect different behaviour from "pull", use the word "pull" to express what they want to happen, expect other people interpret the word to mean the way they think it does. At the same time, judging from different behaviour expected by these people, push/pull asymmetry does not seem to have much to do with the confusion. If the verb used by people who know git to call this operation were "distim", these people would also say "distim" and expect different things from it. I would foresee exactly the same problem if the verb were "update" for that matter.
It is just natural, as everybody learns a new language by listening how others talk and by imitating them.
Another thing I noticed while lurning on the #git channel for the past few days is that too much flexibility actually hurts new people. They do not want flexibility, but want to follow a set recipe. It just overwhelms to get too much flexibility upfront without enough guidance.
And there are too much historical flexibility that remain merely for historical reasons. We more or less killed the concept of separate object store and $GIT_DIR (i.e.one objects/ directory shared between more than one .git/ directories) when we made receive-pack aware of alternate repository information---it used to be that objects/ directory did not belong to a single set of refs/ hierarchy, but now it does and the receiving end of "git push" uses that knowledge to tell the sender what not to send in order to minimize the transfer. We will be gradually killing other kinds of historical flexibility that do not buy much in practice anymore, and that would reduce the issue of overwhelming flexibility.
For example, I am in favor of deprecating the "pull $there $src:$dst" notation. Before we standardized on the separate remote layout, it was sometimes handy to be able to use $dst that is a local branch, but these days, especially when repository $there has remote.$there.fetch mapping configured so that we can compute from $src what remote tracking branch we should store the fetched commit, the flexibility is more confusing than it is useful. "pull $there $src" (and "pull $there $src1 $src2" to build an octopus) should stay, but even there, it probably is a good idea for these notations to start updating remote tracking branches for $src ($src1 and $src2 in the octopus case) if the repository is configured to track them anyway, to match what "pull $there" that uses the default configuration does.
I am actually even Ok, at least in the long run (like in 3 years), if we were to deprecate the refspecs with colon given on the command line to "pull" and "fetch" altogether [*1*]. The rule will become "if you are going to use tracking branches to store what you fetch, you _must_ always have the tracking mapping defined in remote.$there.fetch configuration, and the location where one particular branch from the remote is stored is always determined by that mapping." It robs us the flexibility to fetch my 'next' and store it to your 'next' branch today and to your 'mext' branch tomorrow, and instead you would need to first fetch and then do an explicit "git branch mext origin/next" if you really want to do so, but I think the flexibility outlived its usefulness --- the primary value of these kinds of flexibility is to experiment with various workflows and UI concepts they allow, but I think we have gained enough experience to start judging what works (and is useful) and what doesn't (and is Ok to make it much more cumbersome to make or even impossible to do).
[Footnote]
*1* Except perhaps when deleting branches from the remote with "push", but even there we _could_ force people to do a deleting push separate from normal push and say "push --delete $there $this $and $that".
Quoted 7 lines · Junio C Hamano
For example, I am in favor of deprecating the "pull $there $src:$dst" notation. Before we standardized on the separate remote layout, it was sometimes handy to be able to use $dst that is a local branch, but these days, especially when repository $there has remote.$there.fetch mapping configured so that we can compute from $src what remote tracking branch we should store the fetched commit, the flexibility is more confusing than it is useful.
I emphatically agree. I was always uncomfortable with the refspec syntax, because it is too flexible. Why would I ever want to access branch refs other than refs/heads/ on the remote, and why would I ever want to write directly to the local refs/heads/ namespace (in a non-bare repo), as opposed to refs/remotes/<name>? Unless he wants to do something unusual, the user should not be confronted with questions like that.
Clemens
PATCH 1/1 modernize fetch/merge/pull examples
In reply to Junio C HamanoThe "git pull" documentation has examples which follow an outdated style. Update the examples to use "git merge" where appropriate and move the examples to the corresponding manpages.
Furthermore,
o show that pull is equivalent to fetch and merge, which is still a frequently asked question,
o explain the default fetch refspec.
---
Quoted 2 lines · Junio C Hamano
For example, I am in favor of deprecating the "pull $there $src:$dst" notation.
A first step in that direction.
Clemens
Documentation/git-fetch.txt | 29 +++++++++++++++++++++++++ Documentation/git-merge.txt | 33 +++++++++++++++++++++++++++++ Documentation/git-pull.txt | 49 +++--------------------------------------- 3 files changed, 66 insertions(+), 45 deletions(-)
Documentation/git-fetch.txt +29 -0
@@ -37,6 +37,35 @@ include::pull-fetch-param.txt[] include::urls-remotes.txt[] + +EXAMPLES +-------- + +* Update the remote-tracking branches: ++ +------------------------------------------------ +$ git fetch origin +------------------------------------------------ ++ +The above command copies all branches from the remote refs/heads/ +namespace and stores them to the local refs/remotes/origin/ namespace, +unless the branch.<name>.fetch option is used to specify a non-default +refspec. + +* Using refspecs explicitly: ++ +------------------------------------------------ +$ git fetch origin +pu:pu maint:tmp +------------------------------------------------ ++ +This updates (or creates, as necessary) branches `pu` and `tmp` in +the local repository by fetching from the branches (respectively) +`pu` and `maint` from the remote repository. ++ +The `pu` branch will be updated even if it is does not fast-forward; +the others will not be. + + SEE ALSO -------- linkgit:git-pull[1]
Documentation/git-merge.txt +33 -0
@@ -212,6 +212,39 @@ You can work through the conflict with a number of tools: common ancestor, 'git show :2:filename' shows the HEAD version and 'git show :3:filename' shows the remote version. + +EXAMPLES +-------- + +* Bundle branches `fixes` and `enhancements` on top of + the current branch, making an Octopus merge: ++ +------------------------------------------------ +$ git merge fixes enhancements +------------------------------------------------ + +* Merge branch `obsolete` into the current branch, using `ours` + merge strategy: ++ +------------------------------------------------ +$ git merge -s ours obsolete +------------------------------------------------ + +* Merge branch `maint` into the current branch, but do not make + a commit automatically: ++ +------------------------------------------------ +$ git merge --no-commit maint +------------------------------------------------ ++ +This can be used when you want to include further changes to the +merge, or want to write your own merge commit message. ++ +You should refrain from abusing this option to sneak substantial +changes into a merge commit. Small fixups like bumping +release/version name would be acceptable. + + SEE ALSO -------- linkgit:git-fmt-merge-msg[1], linkgit:git-pull[1],
Documentation/git-pull.txt +4 -45
58 lines not on this page · raw message
Signature · 1 line
1.6.5.1
Re: [PATCH] modernize fetch/merge/pull examples
Quoted 3 lines · Clemens Buchacher
The "git pull" documentation has examples which follow an outdated style. Update the examples to use "git merge" where appropriate and move the examples to the corresponding manpages.
Makes sense, although I did some minor rewording.
I noticed something related while reading this (the issue does not affect the validity of this patch).
Documentation/git-merge.txt You can work through the conflict with a number of tools: · line 241
Quoted 9 lines
Documentation/git-merge.txt +9
-0+* Merge branch `maint` into the current branch, but do not make + a commit automatically: ++ +------------------------------------------------ +$ git merge --no-commit maint +------------------------------------------------ ++ +This can be used when you want to include further changes to the +merge, or want to write your own merge commit message.
When you are up to date with maint this would be a no-op, and when you are strictly behind maint it will succeed without creating a new commit.
I have two possible approaches to fix this issue.
PATCH 1/1 git-merge: imply --no-ff when --no-commit is given
Traditionally "git merge --no-commit" meant just that: do not create a new commit even when a merge succeeds. But this leads to confusion when the merged commit is a descendant of the current commit, in which case we succeed the merge by fast-forwarding and without creating a new commit.
Make --no-commit imply --no-ff; --no-commit is a request by the user to tweak the resulting merge and it is clear indication that the user wants to have a merge, even if it is an extra one, to futz with.
There is a test that relies on --no-commit silently fast forwarding; that is obviously broken by this change.
---
* This is another possibility, which I think is worse than the other one in practice but the justification sounds more respectable.
Unlike the other one, this will still make --no-commit a no-op when you are already up-to-date. As I do not think --no-ff makes much sense in my own workflow (either here or dayjob) it is not exactly my itch, but I suspect that people who wanted to have --no-ff may want to create an extra commit even in such a case; it may be a bug to allow up-to-date when --no-ff is given. Yes, it would make the --no-ff even more insane than it already is, but I suspect it would be more consistent with the original reasoning of wanting to have the option in the first place, namely, to leave the trace of the fact that a "merge" was done at that point in the history.
builtin-merge.c | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-)
builtin-merge.c +3 -0
@@ -874,6 +874,9 @@ int cmd_merge(int argc, const char **argv, const char *prefix) option_commit =0 ; } +if (!option_commit) + allow_fast_forward =0 ; +if (!argc)usage_with_options (builtin_merge_usage, builtin_merge_options);
Signature · 1 line
1.6.5.1.107.gba912
Re: [PATCH] git-merge: imply --no-ff when --no-commit is given
Quoted 3 lines · Junio C Hamano
Make --no-commit imply --no-ff; --no-commit is a request by the user to tweak the resulting merge and it is clear indication that the user wants to have a merge, even if it is an extra one, to futz with.
I think --no-commit makes sense in case of a real merge, because a 3-way diff can help fix any semantic errors. Apart from that, one can simply do a regular merge and --amend it later.
In case of a fast-forward merge, there is not going to be a 3-way diff anyways. So it's pointless to use --no-commit in this case.
I'm therefore in favor of your other proposal, even though it may be confusing to users who don't understand the difference between n-way and fast-forward merge. But that's something they will have to learn.
And --no-ff can always be used explicitly.
Clemens
[RFC/PATCH] git-merge: forbid fast-forward and up-to-date when --no-commit is given
In reply to Junio C HamanoTraditionally "git merge --no-commit" meant just that: do not create a new commit even when a merge succeeds. But this leads to confusion when the merged commit is a descendant of the current commit, in which case we succeed the merge by fast-forwarding and without creating a new commit. Also when the merged commit is already a part of the history, we succeeded without doing anything.
Error out when --no-commit is given but the merge would result in a fast-forward or an up-to-date.
---
* This is the first alternative. I think it makes more sense than the other one, but I am unsure, as I obviously do not get confused when --no-commit becomes no-op due to a fast-forward nor an up-to-date and am rather happy with the current behaviour.
builtin-merge.c | 11 +++++++++++ 1 files changed, 11 insertions(+), 0 deletions(-)
builtin-merge.c +11 -0
@@ -829,6 +829,12 @@ static int evaluate_result(void)return cnt; } +static void check_no_commit (const char *msg) +{ +if (!option_commit) +die ("The merge will %s but --no-commit was given." , msg); +} +int cmd_merge (int argc,const char **argv,const char *prefix) {unsigned char result_tree[20 ];
@@ -996,6 +1002,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)* If head can reach all the merge then we are up to date. * but first the most common case of merging one remote. */ +check_no_commit ("be a no-op because you are up-to-date" );finish_up_to_date ("Already up-to-date." );return 0 ; } else if (allow_fast_forward && !remoteheads->next &&
@@ -1006,6 +1013,9 @@ int cmd_merge(int argc, const char **argv, const char *prefix)struct object *o;char hex[41 ]; +if (allow_fast_forward) +check_no_commit ("fast forward" ); +strcpy (hex,find_unique_abbrev (head,DEFAULT_ABBREV ));if (verbosity >=0 )
@@ -1074,6 +1084,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix) } }if (up_to_date) { +check_no_commit ("fast forward" );finish_up_to_date ("Already up-to-date. Yeeah!" );return 0 ; }
Signature · 1 line
1.6.5.1.107.gba912
Re: [RFC/PATCH] git-merge: forbid fast-forward and up-to-date when --no-commit is given
Quoting Junio C Hamano <[email protected]>
Quoted 10 lines
Traditionally "git merge --no-commit" meant just that: do not create a new commit even when a merge succeeds. But this leads to confusion when the merged commit is a descendant of the current commit, in which case we succeed the merge by fast-forwarding and without creating a new commit. Also when the merged commit is already a part of the history, we succeeded without doing anything.
Error out when --no-commit is given but the merge would result in a fast-forward or an up-to-date.
Quoted 7 lines
Signed-off-by Junio C Hamano <[email protected]>---
* This is the first alternative. I think it makes more sense than the other one, but I am unsure, as I obviously do not get confused when --no-commit becomes no-op due to a fast-forward nor an up-to-date and am rather happy with the current behaviour.
I think this is good (but I am saying this only from your description without understanding the updated code), but the change breaks --squash to merge a branch, doesn't it?
% git checkout feature # from your master branch % work; git commit; work; git commit
% git checkout master # go back to your master branch % git merge --squash feature
This is a useful way to clean up changes that were built in small steps that turned out to be worth only a commit.
Signature · 2 lines
Nanako Shiraishi http://ivory.ap.teacup.com/nanako3/
Re: [RFC/PATCH] git-merge: forbid fast-forward and up-to-date when --no-commit is given
Quoted 9 lines · Nanako Shiraishi
the change breaks --squash to merge a branch, doesn't it?
% git checkout feature # from your master branch % work; git commit; work; git commit
% git checkout master # go back to your master branch % git merge --squash featureThis is a useful way to clean up changes that were built in small steps that turned out to be worth only a commit.
Incidentally we seemed to have seen an end user request for exactly this workflow.
A reroll has been queued, as below, with an update to a test script that expects --no-commit to be a no-op for fast-forward.
-- >8 --
Traditionally "git merge --no-commit" meant just that: do not create a new commit even when a merge succeeds. But this leads to confusion when the merged commit is a descendant of the current commit, in which case we succeed the merge by fast-forwarding and without creating a new commit.
Also when the merged commit is already a part of the history, we succeeded without doing anything.
Error out when --no-commit is given but the merge would result in a fast-forward or an up-to-date.
--- builtin-merge.c | 11 +++++++++++ t/t7600-merge.sh | 4 +--- 2 files changed, 12 insertions(+), 3 deletions(-)
builtin-merge.c +11 -0
@@ -829,6 +829,12 @@ static int evaluate_result(void)return cnt; } +static void check_no_commit (const char *msg) +{ +if (!option_commit) +die ("The merge will %s but --no-commit was given." , msg); +} +int cmd_merge (int argc,const char **argv,const char *prefix) {unsigned char result_tree[20 ];
@@ -996,6 +1002,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix)* If head can reach all the merge then we are up to date. * but first the most common case of merging one remote. */ +check_no_commit ("be a no-op because you are up-to-date" );finish_up_to_date ("Already up-to-date." );return 0 ; } else if (allow_fast_forward && !remoteheads->next &&
@@ -1006,6 +1013,9 @@ int cmd_merge(int argc, const char **argv, const char *prefix)struct object *o;char hex[41 ]; +if (allow_fast_forward && !squash) +check_no_commit ("fast forward" ); +strcpy (hex,find_unique_abbrev (head,DEFAULT_ABBREV ));if (verbosity >=0 )
@@ -1074,6 +1084,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix) } }if (up_to_date) { +check_no_commit ("be a no-op because you are up-to-date" );finish_up_to_date ("Already up-to-date. Yeeah!" );return 0 ; }
t/t7600-merge.sh +1 -3
@@ -265,9 +265,7 @@ test_debug 'gitk --all' test_expect_success 'merge c0 with c1 (no-commit)' ' git reset --hard c0 && - git merge --no-commit c1 && - verify_merge file result.1 && - verify_head $c1 + test_must_fail git merge --no-commit c1 ' test_debug 'gitk --all'
Signature · 1 line
1.6.5.1.124.g746fb6
Re: [PATCH] modernize fetch/merge/pull examples
In reply to Clemens BuchacherQuoted 6 lines · Clemens Buchacher
Quoted 2 lines · Junio C Hamano
For example, I am in favor of deprecating the "pull $there $src:$dst" notation.
A first step in that direction.
I think this is a good change independently of the deprecation.
Quoted 3 lines
+------------------------------------------------
+$ git fetch origin +pu:pu maint:tmp
+------------------------------------------------
[...]
Documentation/git-fetch.txt include::pull-fetch-param.txt[] · line 66
Quoted 2 lines
Documentation/git-fetch.txt +2
-0+The `pu` branch will be updated even if it is does not fast-forward; +the others will not be.
I think to a new user it is not immediately clear if this means "will not be updated, period" or "will not be updated if ...". How about
The pu branch will always be updated; the tmp branch only if it is a fast-forward update.
Signature · 2 lines
Thomas Rast
trast@{inf,student}.ethz.chQuoted 6 lines · Junio C Hamano
Quoted 3 lines · Björn Steinbrink
So that's ten days of #git. I left out a bunch of duplications (most were "pull == fetch", "pull == update" and "pull to update non-checked-out branch").
Quoted 6 lines
Interesting; this shows that people who do not understand what "pull" does expect different behaviour from "pull", use the word "pull" to express what they want to happen, expect other people interpret the word to mean the way they think it does. At the same time, judging from different behaviour expected by these people, push/pull asymmetry does not seem to have much to do with the confusion.
This of course is where our conclusions differ. I haven't counted them, but Björn (thanks again for the excellent survey) points out that most duplicates are confusion with fetch, (imagined) update or "update to not checked out branch".
Pull is none of these, but if it was (current) fetch, at least the first group of people would have had the right idea of what it does.
Quoted 3 lines
I am actually even Ok, at least in the long run (like in 3 years), if we were to deprecate the refspecs with colon given on the command line to "pull" and "fetch" altogether [*1*].
As an aside, there are actually some use-cases, e.g., to grab the git-svn refs from a freshly cloned repository you would run:
git fetch origin refs/remotes/*:refs/remotes/*
(and then 'git svn init' etc.) I've also had some weird requests on IRC that could be solved by clever (and of course dangerous) use of 'git fetch . glob:otherglob'.
Hiding that power behind an option could be a good idea though.
Signature · 2 lines
Thomas Rast
trast@{inf,student}.ethz.chQuoted 23 lines · Björn Steinbrink
Quoted 2 lines · Daniel Barkalow
But I don't really know; are there IRC logs you can quote or reference with people making the mistake you're trying to help them avoid?
"git pull" is kind of a jack of all trades WRT user errors, so I'll just pick up examples of all kinds, this might get long...
[If you read this and find out that you're quoted/referenced here: I don't mean to blame or embarrass you, or to point out that you're stupid or whatever. Quite contrary, I just want to show how git's pull UI _might_ be responsible for your mistakes. The comments I made are purely my, possibly biased, reaction to what happened.]
That said, here we go:
1) Unexpected fast-forward even with --no-ff
"git pull --no-ff abc:abc" with "abc" being checked out.
As pull explicitly allows fetches into the checked out branch head, this first fast-forwards abc, and updates the working tree/index. And then the --no-ff merge is a no-op.
Quoted 6 lines
http://colabti.de/irclogger/irclogger_log/git?date=2009-10-20#l2080
(Should be a catchable special case, and the special --update-head-ok handling of "git pull" is from times where git didn't have remote tracking branches. I'd argue that that support should be dropped or at least disabled when you're using the modern setup, might be kept for oldtimers still using .git/remotes/*. Dunno...)
Yup, I think it would be good to ditch --update-head-ok and simplify the code; I also think it would be nice to prohibit fetching into refs/heads/* entirely, but there might be advanced users who actually want to do that.
In this case, "git fetch" has already done something the user didn't want, and the pull-specific portion doesn't actually do anything at all.
Quoted 10 lines
2) "git pull" taken as "reset --hard"
git checkout -b foo; git pull origin barThe user actually just wanted to look at things and thus was ok with:
git fetch origin; git checkout origin/barhttp://colabti.de/irclogger/irclogger_log/git?date=2009-10-20#l1807
(user seemed to be so inclined to use "pull" that he initially didn't even realize that he didn't want to merge when I asked whether that's what he wants)
I think that's a case where the user has been discouraged from using detached HEAD, and is using "pull" instead of "fetch" in order to update the junk branch he doesn't actually want. If you don't know you don't need a local branch, and you branch off of a common ancestor, "pull" does actually do something you want that "fetch" doesn't.
Quoted 16 lines
3) User expects "pull" to update all branch heads that have a configured upstream
08:31 dimsuz hi guys! suppose i'm currently on master. then run git
fetch. which delivers updates to master and other branches. I don't merge anything, but do checkout some branch (which is not master). Question: will these new updates get into this branch automatically after i check it out? question2: will branch master contain those updates when i ckeck it out later?
08:32 Circuitsoft dimsuz. After a fetch, no.
08:33 Circuitsoft However, if you pull, any branches that were set
up as local tracking branches will get updated.
08:33 Circuitsoft Otherwise, only remote tracking branches will be
updated.
Quoted 3 lines
http://colabti.de/irclogger/irclogger_log/git?date=2009-10-20#l969
(No idea about that one, have seen that once before, but it's definitely not even remotely as common as the others)
I'd guess that's due to having local branches with no local changes, just to avoid detached HEAD, and therefore thinking it's normal to have a bunch of local branches that could be updated without merges. But I'm on a crazy "everybody really wants detached HEAD and is needlessly scared" kick, and I'm probably reading too much into it.
Quoted 23 lines
4) User expects "pull" to create branches
07:25 fynn Hey, I just pulled a branch from remote, and I don't see
it in "git branch"
07:25 doener fynn: if you "pull" that means "fetch this and merge it
to what I have checked out"
07:25 fynn doener: hm, I just did "git pull" and it showed the new
branch
07:26 fynn but I don't see it in my branches...
07:26 fynn doener: should I create that branch as a tracking branch
first?
07:26 doener fynn: you're looking at "git branch -r" or "git branch-a", right?07:26 fynn doener: yeah, I'm seeing it in origin/foo, but not
local.
07:26 doener fynn: the "git fetch" should have created a remote
tracking branch, as usual, not a local branch head (which would be shown by just "git branch")
07:27 fynn doener: OK, what should I do to create it locally then?
07:28 doener fynn: just the usual "git branch foo origin/foo", or to
checkout at the same time: "git checkout -b foo origin/foo" or "git checkout -t origin/foo" (shortcut)
Quoted 6 lines
http://colabti.de/irclogger/irclogger_log/git?date=2009-10-19#l830
(Note how my "fetch this and merge it" is actually inaccurate for just "git pull", there is no "this" and that case. I took "pulled a branch" to mean that he did "git pull <remote> <branch>", which wouldn't have created/update the remote tracking branch [or did patches for that go in? I lost track...])
That sounds like a real converse of "push", including creating like-named local branches. Or, perhaps, this is someone expecting that "pull" is like "clone" in creating an initial local branch with the name and value of a specified remote branch.
Quoted 10 lines
4b) User expects pull to create a branch head
09:58 araujo git pull origin <
new_branch>
09:58 araujo will get me the new branch from repo right?
10:00 charon araujo: no, that will fetch *and merge* that branch
10:00 araujo charon, how to just pull?http://colabti.de/irclogger/irclogger_log/git?date=2009-10-19#l1152
(Note how he asked "how to just pull?", even after being told that pull isn't what he wants)
That's got to be hg usage. He knows the command isn't "pull", but he's stuck with the operation it performs being pulling. Or maybe he's thinking that the operation is pulling, and the command needs different arguments to not merge.
Quoted 9 lines
5) User possibly expecting "pull" to be able to act as "reset --hard"
21:01 aidan What do I do about this: html/config/core.php: needs
update
21:02 aidan git pull (gives that)
21:02 Ilari aidan: You have uncommitted changes to that file...
21:15 aidan Ilari: how can I just pull master and overwrite any
changes?
Quoted 5 lines
http://colabti.de/irclogger/irclogger_log/git?date=2009-10-18#l2130
(I'm not sure about that one, "overwrite any changes" might mean "drop uncommitted changes and merge" or "just get me the remote's state, dropping my commits and uncommitted changes". Most of the time I've seen similar requests, the user wanted the latter).
So I think that's a desire for "git checkout ." first of all (with the assumption that the content without modifications has to come from somewhere remote). I don't know what's up with people not wanting to save their commits, though.
Quoted 11 lines
6) User says "pull" but probably means "fetch"
14:08
Alien_Freakonce I have a clone of a repo I know you can do
a checkout tag but is there anyway to pull just the tag?http://colabti.de/irclogger/irclogger_log/git?date=2009-10-16#l1664
(There was no answer, thus it's hard to tell, but I guess he wanted something like:
git init; git fetch --no-tags url tag <tag>; git checkout <tag> At least I'm quite sure he didn't mean "pull" as in "git pull")
I don't know; you can actually do:
$ git init; git pull --no-tags <url> tag <tag>
It updates the master branch and working directory from (nothing) to the fetched tag.
Quoted 10 lines
7) User expecting "pull" to just do fast-forwards (or so)
13:18 ohadlevy I'm getting a merge commit message after each
time i do git pull, i didnt have it before, where should I look?
13:20 charon ohadlevy: pull merges; you may just have hit lucky so
far, and always had a fast-forward merge
13:20 ohadlevy charon: any way I could avoid these commits?
just rebasing? its a pure RO repo
Quoted 6 lines
http://colabti.de/irclogger/irclogger_log/git?date=2009-10-16#l1579
(Apparently, user was tricked by the fast-forward behaviour he experienced earlier. I don't see any solution to this, except for defaulting to fast-forward-only and requiring a --merge flag (which might imply --no-ff), but I'm likely influenced by the "git update" stuff here)
Again, sounds like the user does want to update local branch state, if there is any. Probably doesn't want a local branch, what with being confused at the possibility of having history that's not from the remote.
Quoted 10 lines
8) "reset --hard" again
20:10
roger_padactori commited then did a pull how do i get back to
my commit. the pull over wrote the files
20:11 merlin83roger_padactor: you can't, pull == fetch + hard
reset to latest commithttp://colabti.de/irclogger/irclogger_log/git?date=2009-10-14#l2306
(Someone being told that pull is fetch + reset --hard is actually new to me. Only saw that as an expectation previously.)
That's odd. How could you not notice that it doesn't actually do that, even if you try to get it to?
Quoted 9 lines
9) More "git pull <remote> A:A"
19:10 _hp_ another question, how do I add the remote branch to
track so I don't have to constantly do git pull origin masterA:masterA ?
19:11 Ilari _hp_: Don't use that src:dest with pull!
(discussion died)http://colabti.de/irclogger/irclogger_log/git?date=2009-10-12#l2427
Yup. Oh, and it strikes me that this user must have never made any commits, because that would give an error (not fast forward) on the fetch part.
Quoted 9 lines
10) "pull" mistaken for "cvs update"
07:25 Avrem how do I use "git pull" to do something like what "cvs
update" does ?
07:25 Avrem which is, replaces files I've deleted
07:25 Avrem from that from the central repository
07:30 omega I'm not sure, but can't you git checkout <deleted files>
to get them back?
Quoted 10 lines
http://colabti.de/irclogger/irclogger_log/git?date=2009-10-11#l545
(This adds a new twist to the "scm update" stuff, although svn/hg don't seem to have "restore individual files" in their "update" command, so this might be cvs-only. But it's so long since I used cvs, I don't even know whether this is correct. But it somehow got me thinking about how "update" is actually also "downgrade" in svn/hg, something git does via "checkout" [which happens to make more sense to me]. And I think it shows how "git pull" is taken to mean "update", even when ignoring the special behaviour described here. It's not taken to mean "merge this", but just "update to upstream").
"cvs update" can definitely discard uncommitted changes, according to the --help text.
Actually, I wonder if the right formula is update = fetch + checkout. There are a lot of people (IMHO) want "git fetch origin; git checkout origin/master", and I think their first idea is "git update", but that doesn't exist, and they find "pull" as the closest thing.
Quoted 3 lines
So that's ten days of #git. I left out a bunch of duplications (most were "pull == fetch", "pull == update" and "pull to update non-checked-out branch").
Very interesting. I feel like this is a new thing since I last spent much time on IRC, when it was all people pushing into non-bare repositories. Thanks for taking the time to collect this.
-Daniel
*This .sig left intentionally blank*
Quoted 22 lines · Daniel Barkalow
Quoted 16 lines · Björn Steinbrink
3) User expects "pull" to update all branch heads that have a configured upstream
08:31 dimsuz hi guys! suppose i'm currently on master. then run git
fetch. which delivers updates to master and other branches. I don't merge anything, but do checkout some branch (which is not master). Question: will these new updates get into this branch automatically after i check it out? question2: will branch master contain those updates when i ckeck it out later?
08:32 Circuitsoft dimsuz. After a fetch, no.
08:33 Circuitsoft However, if you pull, any branches that were set
up as local tracking branches will get updated.
08:33 Circuitsoft Otherwise, only remote tracking branches will be
updated.Quoted 3 lines
http://colabti.de/irclogger/irclogger_log/git?date=2009-10-20#l969
(No idea about that one, have seen that once before, but it's definitely not even remotely as common as the others)
Quoted 5 lines
I'd guess that's due to having local branches with no local changes, just to avoid detached HEAD, and therefore thinking it's normal to have a bunch of local branches that could be updated without merges. But I'm on a crazy "everybody really wants detached HEAD and is needlessly scared" kick, and I'm probably reading too much into it.
Just to clarify: I didn't mean the question (which I didn't really understand) in this case, but the answer from Circuitsoft (second to last line). But maybe you also meant that? The question confuses me enough not to be able to follow.
Quoted 30 lines
Quoted 23 lines
4) User expects "pull" to create branches
07:25 fynn Hey, I just pulled a branch from remote, and I don't see
it in "git branch"
07:25 doener fynn: if you "pull" that means "fetch this and merge it
to what I have checked out"
07:25 fynn doener: hm, I just did "git pull" and it showed the new
branch
07:26 fynn but I don't see it in my branches...
07:26 fynn doener: should I create that branch as a tracking branch
first?
07:26 doener fynn: you're looking at "git branch -r" or "git branch-a", right?07:26 fynn doener: yeah, I'm seeing it in origin/foo, but not
local.
07:26 doener fynn: the "git fetch" should have created a remote
tracking branch, as usual, not a local branch head (which would be shown by just "git branch")
07:27 fynn doener: OK, what should I do to create it locally then?
07:28 doener fynn: just the usual "git branch foo origin/foo", or to
checkout at the same time: "git checkout -b foo origin/foo" or "git checkout -t origin/foo" (shortcut)Quoted 6 lines
http://colabti.de/irclogger/irclogger_log/git?date=2009-10-19#l830
(Note how my "fetch this and merge it" is actually inaccurate for just "git pull", there is no "this" and that case. I took "pulled a branch" to mean that he did "git pull <remote> <branch>", which wouldn't have created/update the remote tracking branch [or did patches for that go in? I lost track...])
Quoted 4 lines
That sounds like a real converse of "push", including creating like-named local branches. Or, perhaps, this is someone expecting that "pull" is like "clone" in creating an initial local branch with the name and value of a specified remote branch.
Reading that one again, I realize that I've still been confused by the "pulled a branch". What happened was that the user did "git pull", which ran "git fetch <remote>", which fetched a new branch head and has shown that. At that point, the user (and me) got confused for maybe two reasons:
a) He didn't clearly distinguish between the fetch and the merge part. The new branch wasn't pulled, but just fetched. That caused the user to think that he "pulled the branch" (wrong terminology), which in term confused me (wrong use-case assumed).
b) He expected local branch heads to be created, instead of remote tracking branches. If my memory doesn't play tricks on me, that's actually not to be expected from that specific user (I think we told him about remote tracking branches before, and the last part of the conversation actually suggests that, too). If I don't forget, I'll try to get feedback from him the next time he's around.
Quoted 15 lines
Quoted 9 lines
5) User possibly expecting "pull" to be able to act as "reset --hard"
21:01 aidan What do I do about this: html/config/core.php: needs
update
21:02 aidan git pull (gives that)
21:02 Ilari aidan: You have uncommitted changes to that file...
21:15 aidan Ilari: how can I just pull master and overwrite any
changes?Quoted 5 lines
http://colabti.de/irclogger/irclogger_log/git?date=2009-10-18#l2130
(I'm not sure about that one, "overwrite any changes" might mean "drop uncommitted changes and merge" or "just get me the remote's state, dropping my commits and uncommitted changes". Most of the time I've seen similar requests, the user wanted the latter).
Quoted 4 lines
So I think that's a desire for "git checkout ." first of all (with the assumption that the content without modifications has to come from somewhere remote). I don't know what's up with people not wanting to save their commits, though.
You haven't seen the multitude of "I have merge conflicts and just want to take theirs/mine" requests. That often gets more weird than just "drop my commits" ;-)
Quoted 12 lines
Quoted 11 lines
6) User says "pull" but probably means "fetch"
14:08
Alien_Freakonce I have a clone of a repo I know you can do
a checkout tag but is there anyway to pull just the tag?http://colabti.de/irclogger/irclogger_log/git?date=2009-10-16#l1664
(There was no answer, thus it's hard to tell, but I guess he wanted something like:
git init; git fetch --no-tags url tag <tag>; git checkout <tag> At least I'm quite sure he didn't mean "pull" as in "git pull")
Quoted 6 lines
I don't know; you can actually do:
$ git init; git pull --no-tags <url> tag <tag>It updates the master branch and working directory from (nothing) to the fetched tag.
Hm, yeah, that works (didn't think of it), but it's a rather special case. Teaching that might lead to misunderstandings about what "pull" does, I think. It would look somewhat like "fetch + reset --hard".
Quoted 7 lines
Quoted 7 lines
8) "reset --hard" again
20:10
roger_padactori commited then did a pull how do i get back to
my commit. the pull over wrote the files
20:11 merlin83roger_padactor: you can't, pull == fetch + hard
reset to latest commit
Quoted 6 lines
Quoted 3 lines
http://colabti.de/irclogger/irclogger_log/git?date=2009-10-14#l2306
(Someone being told that pull is fetch + reset --hard is actually new to me. Only saw that as an expectation previously.)That's odd. How could you not notice that it doesn't actually do that, even if you try to get it to?
Hm? roger_padactor noticed that "pull" changed his files and wants to go back. And merlin83 says that that is impossible because pull supposedly does reset --hard. There's nothing in there (I could see) that suggests that anyone tried to make "pull" do "reset --hard".
merlin83 basically made three mistakes, I think:
1) Assume that roger_padactor was talking about uncommitted changes
2) Assume that pull is fetch + reset --hard
3) Assume that you can't undo a reset --hard for committed changes
(OK, 3) isn't actually valid when you consider 1), but 1) is so invalid that I kept 3). After all, "pull" would complain about a dirty tree...)
Quoted 4 lines
Actually, I wonder if the right formula is update = fetch + checkout. There are a lot of people (IMHO) want "git fetch origin; git checkout origin/master", and I think their first idea is "git update", but that doesn't exist, and they find "pull" as the closest thing.
That has a precondition that the user is already using a detached HEAD. Otherwise that fetch + checkout would likely mean that the get baffled when they do:
git checkout master
git update
git checkout foo
git checkout master
Seeing that "master" is out of date "again".
I agree though, that users might look for "git update" and because it is missing, they just look for the closest thing. Adding Junio's statement that users seem to want recipes instead of flexibility (and seeing "update" as just "get me new stuff from upstream" without meaning any specific method of updating), I think that "git update" could be a "recipe collection" tool. I'll hack that into my proof-of-concept thing (which I hope to have ready for a RFC next week).
Björn
Quoted 29 lines · Björn Steinbrink
Quoted 22 lines · Daniel Barkalow
Quoted 16 lines · Björn Steinbrink
3) User expects "pull" to update all branch heads that have a configured upstream
08:31 dimsuz hi guys! suppose i'm currently on master. then run git
fetch. which delivers updates to master and other branches. I don't merge anything, but do checkout some branch (which is not master). Question: will these new updates get into this branch automatically after i check it out? question2: will branch master contain those updates when i ckeck it out later?
08:32 Circuitsoft dimsuz. After a fetch, no.
08:33 Circuitsoft However, if you pull, any branches that were set
up as local tracking branches will get updated.
08:33 Circuitsoft Otherwise, only remote tracking branches will be
updated.Quoted 3 lines
http://colabti.de/irclogger/irclogger_log/git?date=2009-10-20#l969
(No idea about that one, have seen that once before, but it's definitely not even remotely as common as the others)Quoted 5 lines
I'd guess that's due to having local branches with no local changes, just to avoid detached HEAD, and therefore thinking it's normal to have a bunch of local branches that could be updated without merges. But I'm on a crazy "everybody really wants detached HEAD and is needlessly scared" kick, and I'm probably reading too much into it.
Quoted 4 lines
Just to clarify: I didn't mean the question (which I didn't really understand) in this case, but the answer from Circuitsoft (second to last line). But maybe you also meant that? The question confuses me enough not to be able to follow.
Yeah. I think that Circuitsoft, and a lot of the people in these conversations, have local branches they never commit to, and only update with pull, and only use the --track feature to maintain these branches, and may not even ever use "git pull" for anything other than to maintain these branches. That would give the impression that "git pull" always leaves the current branch holding the commit that the remote branch is holding (i.e., "reset --hard") and the guess that this could apply to non-current branches.
But these local branches don't actually give the users any benefit, because they're always the same as the ref in remotes/ unless they're out-of-date.
Quoted 40 lines
Quoted 30 lines
Quoted 23 lines
4) User expects "pull" to create branches
07:25 fynn Hey, I just pulled a branch from remote, and I don't see
it in "git branch"
07:25 doener fynn: if you "pull" that means "fetch this and merge it
to what I have checked out"
07:25 fynn doener: hm, I just did "git pull" and it showed the new
branch
07:26 fynn but I don't see it in my branches...
07:26 fynn doener: should I create that branch as a tracking branch
first?
07:26 doener fynn: you're looking at "git branch -r" or "git branch-a", right?07:26 fynn doener: yeah, I'm seeing it in origin/foo, but not
local.
07:26 doener fynn: the "git fetch" should have created a remote
tracking branch, as usual, not a local branch head (which would be shown by just "git branch")
07:27 fynn doener: OK, what should I do to create it locally then?
07:28 doener fynn: just the usual "git branch foo origin/foo", or to
checkout at the same time: "git checkout -b foo origin/foo" or "git checkout -t origin/foo" (shortcut)Quoted 6 lines
http://colabti.de/irclogger/irclogger_log/git?date=2009-10-19#l830
(Note how my "fetch this and merge it" is actually inaccurate for just "git pull", there is no "this" and that case. I took "pulled a branch" to mean that he did "git pull <remote> <branch>", which wouldn't have created/update the remote tracking branch [or did patches for that go in? I lost track...])Quoted 4 lines
That sounds like a real converse of "push", including creating like-named local branches. Or, perhaps, this is someone expecting that "pull" is like "clone" in creating an initial local branch with the name and value of a specified remote branch.
Reading that one again, I realize that I've still been confused by the "pulled a branch". What happened was that the user did "git pull", which ran "git fetch <remote>", which fetched a new branch head and has shown that. At that point, the user (and me) got confused for maybe two reasons:
Quoted 4 lines
a) He didn't clearly distinguish between the fetch and the merge part. The new branch wasn't pulled, but just fetched. That caused the user to think that he "pulled the branch" (wrong terminology), which in term confused me (wrong use-case assumed).
Right; when pull shows a branch, it's the fetching step. But I think that shouldn't have been confusing to you; the merging step certainly doesn't show anything interesting.
Quoted 6 lines
b) He expected local branch heads to be created, instead of remote tracking branches. If my memory doesn't play tricks on me, that's actually not to be expected from that specific user (I think we told him about remote tracking branches before, and the last part of the conversation actually suggests that, too). If I don't forget, I'll try to get feedback from him the next time he's around.
He seems to get the thing about remote tracking branches (he says that got created); he's fine on the "pull = fetch + (X)" portion, but he's got (X) wrong, and thinks that creates a local branch.
That's why I think he may be confused by clone's behavior, because clone
does: (create a repo), fetch something, and create a co-named local branch. If clone were init + pull (wrong, but a reasonable guess), then clone - init = fetch + checkout -b; so I think he's not totally lost but rather just wrong about what compound operations "pull" is.
Quoted 15 lines
Quoted 15 lines
Quoted 14 lines
5) User possibly expecting "pull" to be able to act as "reset --hard"
21:01 aidan What do I do about this: html/config/core.php: needs
update
21:02 aidan git pull (gives that)
21:02 Ilari aidan: You have uncommitted changes to that file...
21:15 aidan Ilari: how can I just pull master and overwrite any
changes?http://colabti.de/irclogger/irclogger_log/git?date=2009-10-18#l2130
(I'm not sure about that one, "overwrite any changes" might mean "drop uncommitted changes and merge" or "just get me the remote's state, dropping my commits and uncommitted changes". Most of the time I've seen similar requests, the user wanted the latter).
Quoted 8 lines
Quoted 4 lines
So I think that's a desire for "git checkout ." first of all (with the assumption that the content without modifications has to come from somewhere remote). I don't know what's up with people not wanting to save their commits, though.
You haven't seen the multitude of "I have merge conflicts and just want to take theirs/mine" requests. That often gets more weird than just "drop my commits" ;-)
Ah, okay; I tend to think of those as content-focused, rather than history-focused. Like, I think people often run into: "I reformatted files A and B and made important changes to file A; someone else made important changes to file B; I get a awful merge conflict in file B." I bet it's common to want to keep your commit history, but throw away their conflicting changes in the resulting content.
There's also the occasional case where the right solution is to rename a branch to "things-that-seemed-like-a-good-idea-at-the-time", create a new branch from upstream with the old name, and never speak of it again.
But this is all a different topic.
Quoted 14 lines
Quoted 14 lines
Quoted 11 lines
6) User says "pull" but probably means "fetch"
14:08
Alien_Freakonce I have a clone of a repo I know you can do
a checkout tag but is there anyway to pull just the tag?http://colabti.de/irclogger/irclogger_log/git?date=2009-10-16#l1664
(There was no answer, thus it's hard to tell, but I guess he wanted something like:
git init; git fetch --no-tags url tag <tag>; git checkout <tag> At least I'm quite sure he didn't mean "pull" as in "git pull")I don't know; you can actually do:
Quoted 8 lines
Quoted 4 lines
$ git init; git pull --no-tags <url> tag <tag>It updates the master branch and working directory from (nothing) to the fetched tag.
Hm, yeah, that works (didn't think of it), but it's a rather special case. Teaching that might lead to misunderstandings about what "pull" does, I think. It would look somewhat like "fetch + reset --hard".
Well, "merge" looks like "reset --hard" any time it's a fast forward.
I don't think this is a good thing to teach, but if the answer to what the user wants to do when saying "How can I just pull a tag in a single command" is "pull tag <foo>", it's hard to say that's a misuse of the term.
Quoted 11 lines
Quoted 11 lines
Quoted 10 lines
8) "reset --hard" again
20:10
roger_padactori commited then did a pull how do i get back to
my commit. the pull over wrote the files
20:11 merlin83roger_padactor: you can't, pull == fetch + hard
reset to latest commithttp://colabti.de/irclogger/irclogger_log/git?date=2009-10-14#l2306
(Someone being told that pull is fetch + reset --hard is actually new to me. Only saw that as an expectation previously.)
Quoted 7 lines
Quoted 2 lines
That's odd. How could you not notice that it doesn't actually do that, even if you try to get it to?
Hm?
roger_padactornoticed that "pull" changed his files and wants to go back. And merlin83 says that that is impossible because pull supposedly does reset --hard. There's nothing in there (I could see) that suggests that anyone tried to make "pull" do "reset --hard".
I'm surprised that merlin83 can think that pull = fetch + reset --hard; people often seem to try to do fetch + reset --hard with pull, but it doesn't actually work for them.
Quoted 22 lines
merlin83 basically made three mistakes, I think:
1) Assume thatroger_padactorwas talking about uncommitted changes
2) Assume that pull is fetch + reset --hard
3) Assume that you can't undo a reset --hard for committed changes(OK, 3) isn't actually valid when you consider 1), but 1) is so invalid that I kept 3). After all, "pull" would complain about a dirty tree...)
Quoted 4 lines
Actually, I wonder if the right formula is update = fetch + checkout. There are a lot of people (IMHO) want "git fetch origin; git checkout origin/master", and I think their first idea is "git update", but that doesn't exist, and they find "pull" as the closest thing.
That has a precondition that the user is already using a detached HEAD. Otherwise that fetch + checkout would likely mean that the get baffled when they do:
git checkout master
git update
git checkout foo
git checkout master
Quoted 1 line
Seeing that "master" is out of date "again".
Agreed; I think:
$ git checkout master $ git update You are on a local branch. Local branches are under your complete control, so there is nowhere to get updates from. If you would like to merge remote commits into your local branch, you could use "git pull". If you would rather look at a remote branch, you could use "git checkout <some plausible remote branch>".
Of course, without this message:
$ git checkout master $ git update
would be the same as:
$ git chekcout master $ git fetch $ git checkout master
which would already not show any changes. (I'm thinking of the target of the checkout in update-with-no-target as being whatever you typed last time, and the fetch being whatever fetch normally updates that target.)
Personally, I often run:
$ git fetch; git checkout origin/next
This suggests that this is a useful combination of commands.
Quoted 7 lines
I agree though, that users might look for "git update" and because it is missing, they just look for the closest thing. Adding Junio's statement that users seem to want recipes instead of flexibility (and seeing "update" as just "get me new stuff from upstream" without meaning any specific method of updating), I think that "git update" could be a "recipe collection" tool. I'll hack that into my proof-of-concept thing (which I hope to have ready for a RFC next week).
I'll be interested to see that.
-Daniel
*This .sig left intentionally blank*
Quoted 11 lines · Daniel Barkalow
Quoted 9 lines · Thomas Rast
Hi all,
While everyone is busy in two other UI threads, I figured I might as well toss up another (probably) controversial topic.
Especially on IRC, we see many people who are some combination of misunderstanding, misusing or overusing git-pull. I figure this is the result of several factors, notably
Quoted 6 lines
Quoted 1 line
a) pull/push are not symmetric,
In a certain sense they are; they both update the branches local to one repository with the data from the other repository. In this sense, fetch is the oddity in that it doesn't update any repository's own branches, but just the local information about other repositories' branches.
BTW, shouldn't fetch be deprecated in favour of git remote update ? (this may require adding some features to git remote update, but you get the idea)
Mike
Quoted 1 line · Mike Hommey
BTW, shouldn't fetch be deprecated in favour of git remote update ?
Why? People will then be confused because half of them would expect "remote update" to somehow affect their working tree, and some others would expect their working tree reset to one of the branches from the remote, and it won't solve anything. Oh, and it will irritate people who are used to type "git fetch", too.
Quoted 8 lines · Junio C Hamano
Quoted 1 line · Mike Hommey
BTW, shouldn't fetch be deprecated in favour of git remote update ?
Why? People will then be confused because half of them would expect "remote update" to somehow affect their working tree, and some others would expect their working tree reset to one of the branches from the remote, and it won't solve anything.
I must be missing the obvious but which one of fetch and remote update does the above ? I was under the impression that none of them would.
Quoted 2 lines
Oh, and it will irritate people who
are used to type "git fetch", too.
That's another problem, but my understanding is that git fetch and git remote update are roughly doing the same thing. Having two commands for the same thing is confusing. I kind of like the idea to have one command, remote, to handle, err, remotes. Also note that I said deprecated, not remove ; that could mean keeping fetch, but pushing the use of remote update for new users.
Mike
Quoted 9 lines · Junio C Hamano
Quoted 1 line · Mike Hommey
BTW, shouldn't fetch be deprecated in favour of git remote update ?
Why? People will then be confused because half of them would expect "remote update" to somehow affect their working tree, and some others would expect their working tree reset to one of the branches from the remote, and it won't solve anything. Oh, and it will irritate people who are used to type "git fetch", too.
I think the above comment needs to be clarified, so that I will not discourage you or other people who would want to pursue the part I omitted from my quote too much, which was:
Quoted 2 lines
(this may require adding some features to git remote update, but you get the idea)
Now, I _personally_ think "git remote update" was a half-baked UI experiment that failed, but as the maintainer I'll still give it benefit of doubt for a bit longer and let interested parties resurrect and perfect it, just in case it might turn out to be a good thing. In the rest, when I say "I think", pretend as if I said _personally_ (i.e. not speaking as the maintainer who already has given up on it).
I think the original "git remote add" was a good interface, similar to "git config", as the management interface to the remote system used by the everyday commands "fetch/pull/push". The everyday commands use the remote nicknames and their associated data stored in the configuration file.
While you can edit your configuration file directly to manage the remotes, some people (and recipe book writers) prefer to have a specialized management command. "git remote add" is such a management interface that you use once and then you can forget about it. Once you get your remote configured, the everyday commands will use the data in the configuration file, and the commands you interract with your remotes will be these everyday commands, not "git remote".
Some people thought that throwing everything that does something to remote under "git remote" was a good idea, and "git remote update" was invented. It is a thin wrapper around "fetch" and does what "fetch" does. You need to understand "fetch" (i.e. downloads the history and necessary objects, and updates the remote tracking branches, without ever touching the work tree) to understand "git remote update" anyway, and more importantly, you need to understand what they do not do.
It is not even a typesaver. "git fetch" updates from the default remote, so does "git remote update". Personally I think the people who invented "git remote update" were misguided, and that is why I say it was a failed UI experiment that failed, but that is hindsight talking [*1*].
After reading Björn's excerpts, it was clear to me that the names of the commands have much less to do with the confusion [*2*] than I originally feared [*3*]. As long as the user needs the same kind of understanding of what the command does, I do not think changing the command name between "git remote update" vs "git fetch" and calling everything that has something to do with remote repositories "remote" would solve anything. The users also need to understand how to make what these commands do an integrated part in a larger workflow they use, so that they know what to do next, which is much more important issue, and at that point the name of the command is secondary---the concepts counts much more.
"git remote update" even has a slight downside in the "push moves from here to there, pull moves from there to here" sense. If you never have seen git, "git remote update $there" may look like you are asking git to update the remote called $there, presumably with what you have. That is quite opposite direction from how it actually move things.
[Footnote]
*1* The only thing "git remote update" does that "git fetch" does not is that it can serve as "fetch from everywhere" shorthand. But that is something we could have added to "git fetch". So in that sense, I think it may make even more sense to deprecate "remote update" and teach "fetch" how to do that.
*2* Granted, if our "pull" were named "push", the natural meaning of the word "push" that moves things from here to there (as opposed to there to here) may even confuse people, but both "pull" and "fetch" mean moving things from farther to closer (and nothing more in the natural meaning), and the confusion expressed in the thread were not of that kind---nobody expected us to do anything that involves moving something we have to the remote, but the confusion was about what happens _after_ something was moved from there to here.
*3* In a sense I somehow was hoping that the confusion was only about the push/pull asymmetry as some people claimed. If it were, the problem would have been very easy to fix; you just do not let pull affect the work tree. But the confused users were expecting the changes to be reflected to their work trees, and the confusion was about how that is done. Some wanted their local changes blown away, some wanted their local histories also get blown away, some wanted the changes integrated.
Quoted 8 lines · Junio C Hamano
Some people thought that throwing everything that does something to remote under "git remote" was a good idea, and "git remote update" was invented. It is a thin wrapper around "fetch" and does what "fetch" does. You need to understand "fetch" (i.e. downloads the history and necessary objects, and updates the remote tracking branches, without ever touching the work tree) to understand "git remote update" anyway, and more importantly, you need to understand what they do not do.
Quoted 4 lines
It is not even a typesaver. "git fetch" updates from the default remote, so does "git remote update". Personally I think the people who invented "git remote update" were misguided, and that is why I say it was a failed UI experiment that failed, but that is hindsight talking [*1*].
Declaring it a failure depends on what you consider the goal of "git remote update" to be. I find it very useful as a shorthand for "fetch from _all_ remotes"[1]. Which does save typing over
$ for i in `git remote`; do git fetch $i; done
And of course, there is "git remote" again, saving us a few keystrokes over:
$ git config --get-regexp 'remote..*.url' | cut -d. -f2
[1]: And I think this is a useful operation. When collaborating with developers in multiple repositories, it is nice to see an overview of what all other people are working on. We have other tools to actually compare the refs, but the first step is obviously getting those refs up to date locally.
-Peff
Quoted 4 lines · Jeff King
Declaring it a failure depends on what you consider the goal of "git remote update" to be. I find it very useful as a shorthand for "fetch from _all_ remotes"[1]. Which does save typing over
Quoted 9 lines
[...]
Quoted 5 lines · Junio C Hamano
*1* The only thing "git remote update" does that "git fetch" does not is that it can serve as "fetch from everywhere" shorthand. But that is something we could have added to "git fetch". So in that sense, I think it may make even more sense to deprecate "remote update" and teach "fetch" how to do that.
...and it would probably help if I had read your footnotes before responding.
-Peff
Quoted 7 lines · Jeff King
Quoted 4 lines · Junio C Hamano
It is not even a typesaver. "git fetch" updates from the default remote, so does "git remote update". Personally I think the people who invented "git remote update" were misguided, and that is why I say it was a failed UI experiment that failed, but that is hindsight talking [*1*].
Quoted 5 lines
Declaring it a failure depends on what you consider the goal of "git remote update" to be. I find it very useful as a shorthand for "fetch from _all_ remotes"[1]. Which does save typing over
$ for i in `git remote`; do git fetch $i; done
You've since read my footnote about "git fetch <group>", so I do not think this part is controversial anymore.
Quoted 4 lines
And of course, there is "git remote" again, saving us a few keystrokes over:
$ git config --get-regexp 'remote..*.url' | cut -d. -f2
And as you may have already realized by now, I was saying two things.
(1) "git remote" in general is a good management interface for remote nicknames and attributes attached to them, in the similar spirit as "git config" is a good management interface for the underlying configuration files.
(2) "git remote update" is a misguided UI expariment that failed.
So there is no disagreement between us on the "and of course" part, either.