Re: Last mile for 1.0
- From
Linus Torvalds <torvalds@osdl.org>
- Date
- Jun 6, 2005, 06:13 UTC
- Message-ID
- <Pine.LNX.4.58.0506052300350.1876@ppc970.osdl.org>
- In-Reply-To
- <20050606054356.GB3669@cip.informatik.uni-erlangen.de>
On Mon, 6 Jun 2005, Thomas Glanzmann wrote:
> > I think the simplest and effectivies way to handle this is the > following: Add a flag to the current merge script which indicates that > on conflicts the user will be dropped to a shell per conflict to solve:
Well, there was actually a much more fundamental problem, which is that the merge script depended on being able to do
git-checkout-cache -f -u -a
which in turn obviously meant that _whatever_ it did, it would end up overwriting any dirty state in the working tree.
And you can't remove the git-checkout-cache, because after the merge we've lost the original state anyway, so there's no way to know whether whatever you had in the working directory was dirty or not.
So I've actually been working now to make the very low-level git-read-tree Do The Right Thing (tm), and I think I'm getting there. It basically depends on "git-read-tree" noticing when the state is dirty enough that we can't safely do the merge, and then for the safe cases it can actually update anything it merged properly. As a result, there's never any need for git-checkout-cache, and the only thing that needs updating in the working directory is the stuff that we end up merging by hand _outside_ of git-read-tree.
There's two cases: fast-forward and a real merge. And the thing is, to do even just the fast-forward safely, it actually needs to know what the base tree was (otherwise it can only tell that the file was up-to-date in the index, but it can't know whether the index actually matched the original HEAD..). So now the fast-forward case is actually a two-way merge:
git-read-tree -u -m HEAD NEW_HEAD
where "-u" stands for "update", and tells read-tree that it should check out the files it merges up.
And now git-read-tree also tries to be very careful: if one of the files that needs to be updated is already dirty, or it doesn't match the original HEAD, then git-read-tree will just exit with an error and not do anything at all.
But for a file that wasn't touched at all by the merge, we can leave it dirty in the index, since whatever dirty index state was valid before the merge is obviously valid after it too. So now you can have dirty state in your tree, and merges will complain only if it matters to them.
Same goes for the (much more complex) three-way merge, of course. There the rules are a bit more complicated, and I'll have to double-check this thing, but it all looks like even if the current state might be buggy, the basic _notion_ looks fine.
So now we have a one-way merge for "just update to this tree", a two-way merge for "update from this tree to that tree", and a three-way merge for "merge these two trees with that third tree as a base".
By now, I'd really like to have some test-cases. Things like "file dirty in working directory, removed by merge" would be good.
And the "git-merge-one-file-script" thing needs to be updated to keep the tree updated as it merges things by hand, since it can't depend on the git-checkout-cache fixing things up any more. Anybody?
Linus