Re: git pull opinion

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 




On Tue, 6 Nov 2007, Aghiles wrote:
> 
> 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
-
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html

[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux