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

Re: confusion over the new branch and merge config

From
Jeff King <peff@peff.net>
Date
Jan 9, 2007, 15:05 UTC
Message-ID
<20070109150524.GB10633@coredump.intra.peff.net>
In-Reply-To
<7v1wmdure6.fsf@assigned-by-dhcp.cox.net>

[sorry this is old, but hopefully you remember what we were talking about. :)]

On Tue, Jan 02, 2007 at 12:04:33PM -0800, Junio C Hamano wrote:
> I might have misread what you meant by mergeLocal, and you might
> be trying to introduce a default for "git merge" so that without
> anything on the command line "git merge" would merge something
> locally available depending on which branch you are on.

No, I think you read me right: I wanted a way of saying "this is the local branch from which merges should happen if no other branch is specified".

Show 13 quoted lines
> But I did not think of that, and thought you were saying "look
> at branch.*.mergelocal (if exists) in the same place we look at
> branch.*.merge in the current code, and just like the latter is
> used to match up with the remote refname we just fetched, use
> the former to match the local tracking branches, to decide what
> to merge".  And if that is what you meant by mergelocal, I do
> not see much advantage in that approach -- that is what I meant
> in the response.  The remote name is available whether you use
> tracking branches locally or not, so using that to specify the
> merge operation that happens after a 'pull' is more consistent,
> less confusing, and matches the long-hand "git pull $URL
> remote-branch" a lot better than having another configuration
> that can be used only half the time.

Let me say right now that I'm not _that_ interested in this concept, so I'm going to stop pushing for it. However, I do want to respond to a few points in this mail; feel free to ignore. :)

There are two advantages I see to putting local branches in branch.*.merge:
  1. there seems to be some newbie confusion over using the remote name.
    Pull is conceptually (to me anyway), two steps:
      1. Fetch from a remote into my local tracking branches
      2. Merge from some tracking branch into my current branch.
    whereas I have seen you explain pull as:
      1. Fetch into FETCH_HEAD, selecting some branches for merge
      2. Merge any branches marked for merge
    I know that your model is more flexible, since it supports skipping
    the tracking branches. But for newbies looking at the config, I
    think the first makes much more sense.
      1. Newbies always have tracking branches, since that's now the
         default layout.
      2. Newbies don't know about FETCH_HEAD, since we don't talk about
         it in tutorials (and really, with tracking branches, what's the
         point?).
      3. Out of the two steps (fetching and merging), I would expect the
         .merge config option to be dealth with in the latter. But
         actually, it is an intimate part of fetching. This doesn't
         matter if you're pulling, but my workflow (and many others, it
         seems, especially those who rebase regularly) is:
           git fetch
           gitk master...origin
           git rebase ;# or git-pull
  2. There has been a requested feature (which I think makes sense) to
     create an automatic "upstream" for local branches. I.e.,
       git checkout -b new old
       hack hack hack
       git pull ;# should pull from 'old'
     This should be trivial to implement as
       git-repo-config branch.$new.mergeLocal $old
     but instead is requiring some magic to treat '.' as a noop remote.

[This ends the productive portion of this mail, but read on for more philosophical wanderings.]

> Some people repeatedly argued that remote branch names do not
> matter.  I think they are wrong and are missing the point of
> distributedness of git.  You are fetching from there, so you
I think the opposite. :)

To me, the distributed part of git (and one of its strengths over other systems) is that we are all working on a giant digraph of the history, and git is very efficient at adding to, examining, and communicating about parts of that graph.

Refs are just pointers into the graph, and so the names we give them are mostly just local matters (unless we're publishing those names). For example, before I started using separate remotes, I had what by many would be considered a funny setup. I was used to working with master and origin, but I wanted to start tracking next instead. So I made my origin track your next, and I called my master what you call next (plus local commits). As a result, I called your master 'stable' so I could still access it. So the history was distributed, but the names were completely local.

Another oft-mentioned example from the big bzr debate is a fork: what if I stop pulling from you, and start pulling from somebody else? The pointers have changed, but the underlying history is inherently the same. There's no penalty for me to switch names.

That isn't to say the names of the pointers are without value. Talking about 'master' and 'next' is very useful for humans. But what we _really_ mean is "Junio's master" and "Junio's next", because you are publishing those pointers. I don't know (or care) what's on Linus' master, so he can call it whatever he wants. Or if I do care, I don't necessarily care how it relates to your master. So to me, getting hung up on remote names (that is, treating them as anything besides publishing points) misses the point of git's distributedness.

Which isn't to say branch.*.merge looking at remote refs is _wrong_, but that using local names is at least as right (conceptually). :)

> the same place.  Now how would you discuss what that common
> repository recently placed on that branch?  You would not use
> the local tracking branch name which _is_ meaningless to the
> other person.  You use the remote name.

Sure, you would. Because you're talking about that other repo. But my mental model is that all git operations are local operations, except for fetching and pushing. I really think of pull as a shorthand "git-fetch; git-merge". So to me, git-merge is a local operation that should deal with local names.

Show 8 quoted lines
> As you can see from the above, my 'ko' is the local tracking
> branch, and 'master' in that repository is what is known as
> 'todo' to the public.  But when I talk about what I have in that
> branch, I would never say 'master' nor 'ko' -- people would not
> care how I call that branch locally in my private repository.
> What's private is private and does not matter to others.
> Instead I would say something like "my 'todo' branch has drafts
> for v1.5.0 release notes these days".

Exactly. Only published names matter to other people. However, I contend that published names stop mattering once you have a mapping to local names.

> What does this all mean?  It means that remote branch names
> matter more when you are talking about external communication.
> And "git pull" (more so for "git fetch") is all about external
> communication.

I think this is where we really disagree. As I said, git-pull is really just "fetch+merge" to me. And merge isn't about external communication.

> Obviously, the local names should matter more when you are doing
> local operations.  So if you are using mergeLocal to give a
> shorthand to "git merge" that does not explicitly say what to
> merge, the above discussion does not apply.  But if that is the

What I'm suggesting is that it can be used for either (local merges or pulls, since both are git-merge.

> case, mergeLocal should also not affect the selection of
> branches to be merged when "git pull" happens from a remote
> either.

I think I am fundamentally denying the way "for-merge" branch selection works in git-pull. That is, it isn't the way I think of it conceptually, perhaps because I don't actually 'pull' very often. I _always_ fetch first.

-Peff
Previous: Jakub NarebskiNext: Jeff King
Message 40 of 45 in “confusion over the new branch and merge config”
  1. Nicolas PitreDec 21, 2006
  2. Junio C HamanoDec 21, 2006
  3. SeanDec 21, 2006
  4. Junio C HamanoDec 22, 2006
  5. Junio C HamanoDec 22, 2006
  6. SeanDec 22, 2006
  7. Andy ParkinsDec 22, 2006
  8. Alan ChandlerDec 22, 2006
  9. Junio C HamanoDec 22, 2006
  10. Andy ParkinsDec 22, 2006
  11. Alan ChandlerDec 22, 2006
  12. Nicolas PitreDec 22, 2006
  13. Jakub NarebskiDec 22, 2006
  14. Nicolas PitreDec 22, 2006
  15. Jakub NarebskiDec 22, 2006
  16. Junio C HamanoDec 22, 2006
  17. Tom PrinceDec 23, 2006
  18. Nicolas PitreDec 23, 2006
  19. Jeff KingDec 23, 2006
  20. Nicolas PitreDec 23, 2006
  21. Junio C HamanoDec 23, 2006
  22. Shawn PearceDec 23, 2006
  23. Jeff KingDec 23, 2006
  24. Junio C HamanoDec 23, 2006
  25. Jeff KingDec 23, 2006
  26. Junio C HamanoDec 23, 2006
  27. Jakub NarebskiDec 23, 2006
  28. Johannes SchindelinDec 23, 2006
  29. Jakub NarebskiDec 23, 2006
  30. Jeff KingDec 24, 2006
  31. Nicolas PitreDec 24, 2006
  32. Jeff KingDec 26, 2006
  33. Jeff KingJan 2, 2007
  34. Junio C HamanoJan 2, 2007
  35. Jeff KingJan 2, 2007
  36. Junio C HamanoJan 2, 2007
  37. Jakub NarebskiJan 2, 2007
  38. Santi BéjarJan 3, 2007
  39. Jakub NarebskiJan 3, 2007
  40. Jeff KingJan 9, 2007
  41. Jeff KingJan 9, 2007
  42. Jakub NarebskiDec 23, 2006
  43. Andy ParkinsDec 22, 2006
  44. Lars HjemliDec 22, 2006
  45. Nicolas PitreDec 22, 2006

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.