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

Re: git pull opinion

From
Linus Torvalds <torvalds@linux-foundation.org>
Date
Nov 6, 2007, 16:36 UTC
Message-ID
<alpine.LFD.0.999.0711060812170.15101@woody.linux-foundation.org>
In-Reply-To
<3abd05a90711052230y4d6151c6o3e7985a0c8e18161@mail.gmail.com>
On Tue, 6 Nov 2007, Aghiles wrote:
Show 5 quoted lines
> 
> BitKeeper, for example, does a merge with a "dirty" directory.
> I am not saying that git should behave the same way but I think
> that this argument strengthens the point that it is not a
> "centralized repository" mindset.

Git does merge with a dirty directory too, but refuses to merge if it needs to *change* any individual dirty *files*.

And that actually comes from one of the great strengths of git: in git (unlike just about any other SCM out there) you can - and are indeed expected to - resolve merges sanely in the working tree using normal filesystem accesses (ie your basic normal editors and other tools).

That means that if there is a unresolved merge, you're actually expected to edit things in the same place where they are dirty. Which means that the merge logic doesn't want to mix up your dirty state and whatever merged state, because that is then not sanely resolvable.

Now, I do think that we could relax the rule so that "files that are modified must be clean in the working tree" could instead become "files that actually don't merge _trivially_ must be clean in the working tree". But basically, if it's not a trivial merge, then since it's done in the working tree, the working tree has to be clean (or the merge would overwrite it).

Doing a four-way merge is just going to confuse everybody.

So we *could* probably make unpack-trees.c: treeway_merge() allow this. It's not totally trivial, because it requires that the CE_UPDATE be replaced with something more ("CE_THREEWAY"): instead of just writing the new result, it should do another three-way merge.

So it's within the range of possible, but it's actually pretty subtle. The reason: we cannot (and *must*not*!) actually do the three-way merge early. We need to do the full tree merge in stage 1, and then only if all files are ok can we then check out the new tree. And we currently don't save the merge information at all.

So to do this, we'd need to:
 - remove the "verify_uptodate(old, o); invalidate_ce_path(old);" in 
   "merged_entry()", and actually *leave* the index with all three stages 
   intact, but set CE_UPDATE *and* return success.
 - make check_updates() do the three-way merge of "original index, working 
   tree, new merged state" instead of just doing a "unlink_entry() + 
   checkout_entry()".

It doesn't actually look *hard*, but it's definitely subtle enough that I'd be nervous about doing it. We're probably talking less than 50 lines of actual diffs (this whole code uses good data structures, and we can fairly easily represent the problem, and we already have the ability to do a three-way merge!), but we're talking some really quite core code and stuff that absolutely must not have any chance what-so-ever of ever breaking!

To recap:
 - it's probably a fairly simple change to just two well-defined places 
   (merge_entry() and check_updates())
 - but dang, those two places are critical and absolutely must not be 
   screwed up, and while both of those functions are pretty simple, this 
   is some seriously core functionality.

If somebody wants to do it, I'll happily look over the result and test it out, but it really needs to be really clean and obvious and rock solid. And in the absense of that, I'll take the current safe code that just says: don't confuse the merge and make it any more complex than it needs to be.

		Linus
Previous: Alex RiesenNext: Aghiles
Message 21 of 43 in “git pull opinion”
  1. AghilesNov 5, 2007
  2. Jakub NarebskiNov 5, 2007
  3. Johannes SchindelinNov 6, 2007
  4. AghilesNov 6, 2007
  5. Johannes SchindelinNov 6, 2007
  6. Junio C HamanoNov 6, 2007
  7. Johannes SchindelinNov 6, 2007
  8. Alex RiesenNov 5, 2007
  9. Junio C HamanoNov 5, 2007
  10. Bill LearNov 6, 2007
  11. Pierre HabouzitNov 6, 2007
  12. Alex RiesenNov 6, 2007
  13. Pierre HabouzitNov 6, 2007
  14. Andreas EricssonNov 6, 2007
  15. Johannes SchindelinNov 6, 2007
  16. Andreas EricssonNov 6, 2007
  17. Johannes SchindelinNov 6, 2007
  18. Andreas EricssonNov 6, 2007
  19. AghilesNov 6, 2007
  20. Alex RiesenNov 6, 2007
  21. Linus TorvaldsNov 6, 2007
  22. AghilesNov 7, 2007
  23. Johannes SchindelinNov 8, 2007
  24. Linus TorvaldsNov 10, 2007
  25. Steven GrimmNov 6, 2007
  26. AghilesNov 6, 2007
  27. Miklos VajnaNov 5, 2007
  28. AghilesNov 6, 2007
  29. Benoit SigoureNov 6, 2007
  30. Ralf WildenhuesNov 6, 2007
  31. Johannes SchindelinNov 6, 2007
  32. Ralf WildenhuesNov 6, 2007
  33. AghilesNov 6, 2007
  34. Pierre HabouzitNov 6, 2007
  35. Mark 'git stash [message...]' as deprecatedBrian Downing, Nov 7, 2007
  36. Disable implicit 'save' argument for 'git stash'Brian Downing, Nov 7, 2007
  37. Johannes SixtNov 7, 2007
  38. Wincent ColaiutaNov 7, 2007
  39. Junio C HamanoNov 7, 2007
  40. Pierre HabouzitNov 7, 2007
  41. Pascal ObryNov 6, 2007
  42. Uwe Kleine-KönigNov 7, 2007
  43. Pascal ObryNov 7, 2007

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.