git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: Please undo "Use git-merge instead of git-resolve in

From
Linus Torvalds <torvalds@osdl.org>
Date
Sep 22, 2005, 16:06 UTC
Message-ID
<Pine.LNX.4.58.0509220826460.2553@g5.osdl.org>
In-Reply-To
<E1EISTu-0000MI-Gz@jdl.com>
On Thu, 22 Sep 2005, Jon Loeliger wrote:
> 
>     - Where some of the Git Frustration still lies

Btw, I'd love to have more "this frustrates me" stories. I used to ask for them from the (few) people that used git early on, just to see what the problems were.

I can't really help you with documentation, and would just hope that people who figure out a problem they had would actually document it so that others don't have to figure it out the hard way.

But if there is some usage pattern that doesn't make sense, post about it, and I can try to at least say why it happens that way (and then it's back to the "please send a patch to the documentation" case above ;).

Alternatively, maybe it is something that doesn't need to happen at all, and it's just git being stupid, and we can just fix it.

So to look at your care.
Show 39 quoted lines
>     OK, so I have a git tree that looks like this:
> 
>     241 % git show-branch --more=5
>     * [jdl] Merge with rsync://www.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
>      ! [master] Merge branch 'master' of /home/src/linux-2.6/
>       ! [origin] Merge branch 'master' of /home/src/linux-2.6/
>        ! [paul] Merge with rsync://www.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
>     ----
>     +  + [jdl] Merge with rsync://www.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git
>     ++++ [master] Merge branch 'master' of /home/src/linux-2.6/
>     ++++ [master~1] NTFS: Fix ntfs_{read,write}page() to cope with concurrent truncates better.
>     ++++ [master~2] NTFS: Fix handling of compressed directories that I broke in earlier changeset.
>     ++++ [master~3] NTFS: Fix various bugs in the runlist merging code.  (Based on libntfs
>     ++++ [master~4] vc: Use correct size on buffer copy in vc_resize
>     +  + [jdl~1] Merge rsync://rsync.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc-merge
>     +  + [jdl^2] ppc32: Allow user to individual select CHRP/PMAC/PREP config
>     +  + [jdl^2~1] powerpc: Merge simplified sections.h into asm-powerpc
>     +  + [jdl^2~2] powerpc: Remove section free() and linker script bits
>     +  + [jdl^2~3] powerpc: Remove sections use from ppc64 and drivers
>     +  + [jdl^2~4] powerpc: Remove sections use from ppc
>     +  + [jdl^2~5] ppc32: Removed non-inlined versions of local_irq* functions
>     ++++ [jdl~2] Merge master.kernel.org:/home/rmk/linux-2.6-arm
> 
>     I have current, modified, non-committed files in my working tree
>     in the "jdl" branch.  I don't want to commit them now (yet).
> 
>     I now know that Linus has updated his tree with new -rc2 parts.
>     I want it.  In fact, I want it on the "origin" or "master" branch.
>     (Or both.  And I don't know which.)
> 
>     How do I get Linus' updates and merge them into the "origin" branch
>     without changing to that branch first?
> 
>     How do I get Paul's updates and merge them into the "paul" branch
>     without changing to that branch first?
> 
>     I think I can fetch the Linus updates by doing something like this:
> 
> 	git fetch origin

Yes, this works. This will fetch the new objects, and automatically update the right branch (ie it will also update the "origin" branch).

> 	git fetch rsync://....path/to/linus-2.6-git

This will _not_ work. Or rather, it will "work" in the sense that it fetches the objects, but without a place to put them into, it won't update any of the branches, so it's kind of pointless.

Show 6 quoted lines
>     That will just grab the Objects and throw them into my .git/objects.
> 
>     But how to do the merge?  I think that the merges all require
>     the "target branch" to be the "active"/checkedout branch, right?
>     I don't know how to now say "Merge-up those new Objects on the
>     origin branch".
The first one should have done that already.

You can also specify _precisely_ what branches you want to use as a source and as a destination.

Ie
	git fetch rsync:..../linus-2.6-git <src>:<dst>

will fetch the <src> branch (ie you'd usually use "master") from my tree and write it to the <dst> branch on your tree.

And it's not a "merge" - it's just an update. A merge implies that you take two trees that have had development on them and try to join them together. A "git fetch" does _not_ merge anything: it just _fetches_ the other side, and writes the objects (and top branch).

Show 6 quoted lines
>     I think what's confusing me still is that the previous
>     World View According to CVS was essentially that you have
>     this import branch into which you dragged all the external
>     updates.  Then you merged that over to your working branch.
>     And, you could easily have views of _both_ of those
>     branches simultaneously.
Hmm.. I'm not sure exactly what you want, but
	git fetch origin

will fetch my stuff without touching your changes AT ALL, and then you can do things like

	gitk --all

to see both your development series _and_ my stuff at the same time. And yes, it works fine even if you have "dirty state" in your tree.

>     However, I _could_ just stick in my "jdl" working branch and
>     directly pull-in and merge the linus changes.  I mean, my next
>     step after pulling those changes into the so-called import
>     branch was going to be to merge them to my branch anyway.
And indeed, if you just did
	git pull origin

then now you're doing a _pull_ instead of a fetch, which means that you do both the fetch _and_ the merge.

In fact, if you use the shorthand with a named branch, the above really _will_ do a "git fetch origin" first, ie it will actually _update_ the "origin" branch before merging it into your current branch. So you'll have _both_.

You can see that (again) with
	gitk --all

where you can actually see that "origin" got updated, and also merged into whatever branch you were working on.

>     OK, so let's say I did pull linus' update into the jdl branch.
>     And they merge up nicely.  How do I now propogate _just_ the
>     linus changes to the origin branch?  Again, I don't think I
>     can without first checking out the "origin" branch.
The "origin" branch was already updated automatically if you used
	git pull origin
However, if you used
	git pull rsync:..../linus-2.6.git

then git would only have fetched the objects, and _not_ updated the "origin" branch (because you didn't tell it about the "origin" branch).

But you can trivially fix that by doing
	git fetch origin
at this point, which will end up doing the equivalent of
	git fetch rsync:..../linus-2.6.git master:origin

(depending on what the contents of your .git/remotes/origin are, of course, the above is just an example).

>     Am I missing something here?  Fighting against the tool?

No, you just didn't realize how "git pull" and "git fetch" worked. Git should actually do what you want to do very naturally. Its' really how it's designed to work, you just didn't realize ;)

Show 6 quoted lines
>     So, you will all be pleased to know that I tried
>     some stuff and was not successful.  In the "jdl"
>     branch, I did a "git pull linus".  It happily went
>     out and grabbed all the new objects from his tree.
>     Spiffy.  It then announced that my branch of the
>     working tree was "dirty" and quit.
Ok, it really depends on what your ".git/remotes/linus" looks like.
For example, it _may_ just contain something like
	URL: rsync:..../linus2.6.git

in which case there is no explicit heads specified. In that case, you really should specify _which_ of the heads you want to pull, and what the target should be. For example, you can do that with

	git fetch linus master:linus

which says: "fetch the branch 'master' from the repository described by 'linus' (.git/remotes/linus) into _my_ branch 'linus'".

NOTE! This really is a _fetch_. It will fetch the objects, and _overwrite_ the old value of the branch "linus".

Now, you can specify that this is what you _always_ want to do, and actually set the branches in the ".git/remotes/linus" file explicitly. You can make your .git/remotes/linus file look like this instead:

	URL: rsync:..../linus2.6.git
	Pull: master:linus

and now you've told it that whenever you fetch (or pull) from "linus", you want to fetch the "master" branch from the remote end, and you always want to store it in the "linus" branch in the local repository.

NOTE NOTE NOTE! Your branch-name does _not_ have to match the shorthand name. So you can make the "Pull:" line say "master:linus-branch", and that will mean that when you do "git fetch linus", it will update the "linus-branch" instead.

Still with me?
Finally (or _instead_ of the "fetch"), we can do
	git pull linus

now. It will do the fetch, and since you now specify a destination in your "remotes/linus" file, it will always update the "linus" part (it a "git pull" is a _superset_ of what "git fetch" does). But in _addition_ to fetching the "linus" branch, it will then try to merge it.

Now, this is where "dirty" comes in. The merge will fail if you have changed any files that the merge wants to modify. So do a

	git diff --name-only HEAD
to see if there are any changes, and commit them - or undo them - if so.  
Then try to pull again.
	
		Linus
Previous: Petr Baudis
Message 3 of 3 in “Re: Please undo "Use git-merge instead of git-resolve in”
  1. Jon LoeligerSep 22, 2005
  2. Petr BaudisSep 22, 2005
  3. Linus TorvaldsSep 22, 2005

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.