Hello, I notice if I create a branch (and switch to it) in the linux kernel off of say version 2.6.14, then later do a git pull, things get ugly. It seems like all the upstream changes are being merged into the 2.6.14 branch (instead of the latest kernel tag). Is this a user error because the tool is still fragile? Thanks, Don -
I do not understand the question. The user wanted all the good developments from the mainline into the fork he created starting at 2.6.14, and the tool did what was asked. Why would you want to forbid that from happening, and what did you want to happen instead? -
Actually I think I do understand the question. You have a clone
of linux-2.6 repository, and your "origin" branch tracks the
bleeding edge from Linus. You also have "myhack" branch that
was forked off from 2.6.14, and wanted to see what new things
Linus has by updating "origin", and perhaps merge those changes
into your "master" which keeps track of your hacks based on
Linus tip, but unfortunately you were on "myhack" branch.
Ouch.
So what you wanted to do was probably:
$ git fetch ;# this updates "origin" to Linus tip
instead of
$ git pull ;# this updates "origin" to Linus tip *and*
# merges that into the current branch
As you may probably know, you can recover by
$ git reset --hard
While I am sympathetic, this "Oops, I said pull when I meant
fetch" sounds remotely similar to "oops, I said 'rm -r' when I
meant to say 'ls -r'". Is it that the tool is too fragile?
-Didn't bk come with some kind of (one-level) undo pull? It should not be too hard to create something similar considering that one could just leave new objects in the db orphaned. M. -
Yes, that is called "git reset". -
Well, this is one area where BK and git differ a lot. BK didn't overload many things onto the same "reset" functionality, but had specific operations for specific cases. Also BK would never leave a merge in the git kind of half-merged state, because BK refuses to have two branches open. Instead, BK had a special way of handling merges, which worked fine but quite frankly I have very little idea of how it worked (it was some kind of "shadow BK tree", it was called ".bk/RESOLVE/" or something like that - but because the tools were so nice, you never really had any reason to look into it, so I don't know what it did). BK would never change the working tree itself until the merge was done, so you would never need to do what a plain "git reset --hard" (without any arguments) does. In many ways the BK thing was very nice, although the git way is perhaps a bit more flexible (because git makes the intermediate tree visible you can easily edit the merge errors, and compile/test the result, before you decide to commit any manual merge). I really do like the way git does merges now (especially after the last round of git-diff-tree fixes that allow comparing the different stages), but the BK way is in some ways cleaner and leaves less potential for confusion since it avoids ever exposing you to any half-merged state. You may remember how I initially argued that we should always try to merge stuff outside of the normal working directory. And I still _like_ that approach, although I've since decided that I actually prefer the current git way is even better in practice. But "git reset" is a lot more than the "revert to previous state". It _also_ does - without the error checking - what "bk fix" used to do (which is to undo the last commit, so that you can re-commit it), and it also does what "bk undo" used to do. It also does "bk unpull". So "git reset" really does a whole lot of different and _mostly_ related things: - undo any half-way changes (very ...
It would be outright peachy if Documentation/git-commit.txt and Documentation/git-pull.txt mentioned these. That is certainly where I would look first to answer the "what if I screwed up?" question. Morten -
Yup. Maybe one line comment at the bottom of these manual pages pointing at git-reset manual page (which has nice examples section) would be good enough? -- >8 -- [PATCH] Examples of resetting. Morten Welinder says examples of resetting is really about recovering from botched commit/pulls. I agree that pointers from commands that cause a reset to be needed in the first place would be very helpful. Also reset examples did not mention "pull/merge" cases. Signed-off-by: Junio C Hamano <junkio@cox.net> --- diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt index b92cf48..8b91f22 100644 --- a/Documentation/git-commit.txt +++ b/Documentation/git-commit.txt @@ -66,6 +66,10 @@ OPTIONS Update specified paths in the index file before committing. +If you make a commit and then found a mistake immediately after +that, you can recover from it with gitlink:git-reset[1]. + + Author ------ Written by Linus Torvalds <torvalds@osdl.org> and diff --git a/Documentation/git-merge.txt b/Documentation/git-merge.txt index 0cac563..4ce799b 100644 --- a/Documentation/git-merge.txt +++ b/Documentation/git-merge.txt @@ -37,6 +37,11 @@ include::merge-options.txt[] include::merge-strategies.txt[] +If you tried a merge which resulted in a complex conflicts and +would want to start over, you can recover with +gitlink:git-reset[1]. + + HOW MERGE WORKS --------------- diff --git a/Documentation/git-pull.txt b/Documentation/git-pull.txt index c65ca9a..3a7d385 100644 --- a/Documentation/git-pull.txt +++ b/Documentation/git-pull.txt @@ -104,6 +104,11 @@ merge the remote `origin` head into the local `master` branch. +If you tried a pull which resulted in a complex conflicts and +would want to start over, you can recover with +gitlink:git-reset[1]. + + SEE ALSO -------- gitlink:git-fetch[1], gitlink:git-merge[1] diff --git a/Documentation/git-reset.txt b/Documentation/git-reset.txt index 0204891..c6a269b 100644 --- a...
It might be even better to have some of the "safe" versions around. Ie something that refuses to "undo" a merge (you want to "unpull" it or "unmerge" it), and refuses to "undo" when there's a ORIG_HEAD around that implies that the last commit was a "pull" (in which case again "undo" may be the wrong thing to do, since it will only undo _one_ commit, even though the pull might have fast-forwarded a _lot_ of commits). Of course, if we do that, we should also make sure that "git commit" removes ORIG_HEAD. Or maybe "git commit" should always _write_ ORIG_HEAD with the old head, so that we can always do an "undo" by doing "git reset --hard ORIG_HEAD" regardless of whether the last thing was a "git commit" or a "git pull". Hmm? Linus -
If we define "git undo" as "Revert the tree to the state one before the last successfull commit/pull", then overwriting ORIG_HEAD as you say at the commit time and always using "git reset --hard ORIG_HEAD" would make sense. I fail to see the merit of "git undo/unpull/unmerge/..."; mostly because I have never seen BK and do not benefit from the familiarity factor at all. To people without BK experience, having too many synonyms (e.g. "git undo" does something magical by feeding "git reset --hard" with ORIG_HEAD) might be just more noise and confusion. I can see them asking "why are there two ways to do identical things?". However, the reason I am maintaining git is not to make it useful for _me_, but to make it useful for the kernel people, so if these BK-like synonyms help them, I'm all for it. If we are going to do that, somebody needs to describe what should each command do in each case in detail, because I do not know BK at all. You guys were on BK for how many months, and have been on git for how many months now? Do BK-familiarity factor matter, and will it continue to matter for how long? -
I don't think it is a huge deal, I suspect that people who used BK have a much easier time with git if only because they already understand the whole distributed thing and about commits and merges. That said, I think a lot of newbies might want to have a "git undo", and not because of any BK history. Even if it just ends up being nothing but shorthand for "git reset --hard ORIG_HEAD". Linus -
I agree to this in principle, but I am afraid "git undo" is too generic and fuzzy a term. Things you might possibly want to undo depends on what you did last [*1*]. In most undoable cases, "reset --hard" is almost right but most likely would result in information loss. If we want to really newbie-proof the "undo" command, I think the hard ones are not the ones that can be approximated with reset ORIG_HEAD, but other "No way to undo" ones and "Nothing to undo" ones. Earlier on the list I gave an overview on merge for an unnamed person with only an e-mail address, and one thing struck me as quite hard to explain was that there are two kinds of "merge failures" --- ones that did not even start the merge and ones that failed in the middle due to conflicts. Somebody totally new to git, after seeing "git pull" to fail in the first kind, would get scared and type "git undo". We could prevent doing damage by making sure we remove ORIG_HEAD in "Nothing to undo" situations, but if we say "Nothing to undo" when the user types "git undo" in such a situation, we will surely hear "what do you mean? the command said failed to pull and I wanted to recover from that!". It also is not clear if it is wise to clear ORIG_HEAD for "No way to undo" ones. Doing so would rob useful undo information from people who know git and expect "No way to undo" ones do not muck with the existing ORIG_HEAD. Even for the ones that we would do "reset --hard ORIG_HEAD", many lose information, and "undo" to me implies "undo only what the last command messed up", which is not what actually happens. The word "reset" does not have that connotation -- it takes you to some defined state, which may be close to what you had before but may not be exactly the same if you had local changes in your tree. HEAD, ORIG_HEAD, and HEAD^ are such defined states you can go, and the user gives where he wants to go explicitly. "undo" does not really say where to go and hides halfway what we do, without doing exactly what ...
One observation is that ORIG_HEAD should probably be named PREV_HEAD in such context to make it more obvious what it is about. Nicolas -
I do not see much difference either way, but I suspect ORIG_HEAD is pretty much well established by now. -
ORIG suggests "origin" to me, something that was there first, or before anything else. If you want to undo something, you want its "previous" state restored relative to the current state, not the absolute previous Well, cogito for one doesn't care at all, and it even doesn't make for it to be created/updated. But still it can remain for what it is now, and PREV_HEAD added for undo purpose. Not a big deal in any case though. Nicolas -
Hmph. I always thought it was original-head before the operation happened, which is why I said it is no different from previous-head. -
OK I agree. Nicolas -
It's meant to be short for ORIGinal, not ORIGin. That's how I wrote it and have always read it ;) Linus -
Hello, Here are my two cents. I'll try my best to make a case for those poor souls who get into this sort of mess. Whenever I give a colleage an introduction to git I emphatically recommend that they start with using git fetch and git merge independantly of each other and stay away for git pull at least until they know what they're doing. This is because I have found that people are really surprised at what happens when they type git pull until it really sinks in that 'pull = fetch + merge to current branch, whatever that may be'. The difference between the words fetch and pull is much more subtle than the difference between remove and list which are the basis for the commands rm and ls. I see nothing in the English dictionary to suggest that pull means fetch + merge. This is a gitism. Even after reading documentation clearly and even using git for a while the difference really takes some time to sink in. I think a great degree of understanding should be shown toward those who dig themselves into this kind of thing. I also recommend that some extra care should be taken in the tutorials and documentation to warn about this difference up front and possibly suggest avoiding the use of pull for those new to git. Carl PS The issue was exacerbated when cogito and git were inconsistent on their respective usages of pull and fetch. I think this has gone away, hasn't it? I haven't used cogito in some time so I really don't know. -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Carl Baldwin Systems VLSI Laboratory Hewlett Packard Company MS 88 work: 970 898-1523 3404 E. Harmony Rd. work: Carl.N.Baldwin@hp.com Fort Collins, CO 80525 home: Carl@ecBaldwin.net - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
You "reduced" this sequence:
$ git symbolic-ref HEAD ;# to make sure you are on the branch
# you think you are on
$ git pull
to this sequence:
$ git fetch origin ;# would not damage the repository
$ git symbolic-ref HEAD ;# to make sure you are on the branch
# you think you are on
$ git merge "Merge from frotz branch of git://..." HEAD FETCH_HEAD
The thing is, you need to make sure where you are, in either
case, before the actual merge happens. Yours needs extra
typing, and in addition loses the merge message autogenerated by
I agree to this. I have never used BK so this is just a
speculation, but I suspect what happened is that we inherited
"pull" terminology from there, needed to name the merge-less
part something, and we ended up calling it "fetch". So the
history behind them might be expressed better by "fetch = pull -
Yup. Thanks for the comments. I am not a good writer, so a
patch is greatly appreciated.
BTW, I feel that setting Mail-Followup-To: to other people is
just plain rude.
Mail-Followup-To: Junio C Hamano <junkio@cox.net>,
Don Zickus <dzickus@gmail.com>, git@vger.kernel.org
I suspect you are trying to avoid receiving a duplicate message
because you subscribe to the list, but when I tell my MUA "I
want to say something to the author of this message in public" I
get Don Zickus on the To: line instead of you, and I had to edit
the To: line to point at you. Aren't you forcing me (and other
people who might want to follow-up to your message) to do extra
work, and making Don's life harder [*1*], just to work around
the problem on your end, when you could just filter the incoming
duplicates yourself?
Removing yourself from CC: line when the CC: line already
contains the mailing list you subscribe to would be fine, but I
find this use of Mail-Followup-To: somewhat objectionable.
[Footnote]
*1* Don could have a mail sorter that prioritize...Sorry, wrong choice of words. Didn't mean to imply anything negative. Though, I am still learning the tool and its features, I do appreciate your feedback and your last email was correct in understanding the mess I created. I'll go read up on the differences between 'fetch' and 'pull'. Cheers, Don -
| kernel module to intercept socket creation | 2 minutes ago | Linux kernel |
| Image size changing during each build | 26 minutes ago | Linux kernel |
| Creating a device from a kernel module (mknod style) | 1 hour ago | Linux kernel |
| Soft lock bug | 5 hours ago | Linux kernel |
| sysctl - dynamic registration problem | 11 hours ago | Linux kernel |
| Question on swap as ramdisk partition | 13 hours ago | Linux kernel |
| serial driver xmit problem | 18 hours ago | Linux kernel |
| Generic Netlink subsytem | 19 hours ago | Linux kernel |
| 'Report spam filter error' page broken | 20 hours ago | KernelTrap Suggestions and Feedback |
| Netfilter kernel module | 1 day ago | Linux kernel |
