Re: git-union-merge proposal

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

 



Joey Hess <joey@xxxxxxxxxxx> writes:

> Lately some tools are storing data in git branches or refs, that is not
> source code, and that is designed in some way to be automatically
> merged. Generally merge=union will work for it, but the problem is that
> git-merge can only operate on the checked out branch, not other
> branches.

I think linking "union" merge too tightly into this is going in a wrong
direction. We _could_ do certain merges without using the working tree at
all, and the design of "git merge" has always been to perform the merge
entirely in index. We do check out the contents of cleanly resolved paths
that are different from the merged-into branch to the working tree, but it
is perfectly fine if we made it optional. We also do write out half-merged
content to the working tree, but that is merely to ask the user to help
finishing the merge that is happening in the index (iow, the ultimate goal
is to let the user say "git add" to tell the index what the resolution is,
and is not to let the user remove <<< === >>> markers in the file in the
working tree). If there is no conflict, we should not have to touch the
working tree at all, and "union" is a very narrow special case that we
declare there is no conflict (even if there was).

In other words, I would prefer to see something like:

	$ git merge --index-only [-s <strategy>] <other_branch>

which

    (0) does work without any file checked out in the working tree;

    (1) does not update a path in the working tree even if the merge
        result for the path is different from the original index entry for
        the path;

    (2) updates the index only when everything cleanly merges (depending
        on the definition of "cleanly merges", e.g. "union" may be a lot
        more lenient than the usual "text" merge) and aborts without
        touching anything if there is a conflict (because --index-only
        does not allow us to touch working tree to ask the user to resolve
        the conflict).

"git merge" is designed to work without any file checked out in the
working tree, by considering a _missing_ file in the working tree as if
there is _no change_ to the path during a merge. IOW, we do not say "you
have an uncommitted local removal of a path, which other side tried to
modify, hence we stop the merge to protect your local change".

This is so that you can do something like this:

	$ git checkout v1.7.6-rc2^0
        $ git reset --hard
	$ rm -fr .temp-workdir
	$ mkdir .temp-workdir
        $ cd .temp-workdir
        $ export GIT_DIR=$(git rev-parse --git-dir)
	$ export GIT_WORK_TREE=$(pwd) ;# this is optional, I think.
        $ git merge -s resolve origin/jk/maint-1.7.2-status-ignored
        Trying really trivial in-index merge...
        error: Merge requires file-level merging
        Nope.
        Trying simple merge.
        Simple merge failed, trying Automatic merge.
        Auto-merging Documentation/git-status.txt
        ERROR: content conflict in Documentation/git-status.txt
        Auto-merging t/t7508-status.sh
        ERROR: content conflict in t/t7508-status.sh
        Auto-merging wt-status.c
        fatal: merge program failed
        Automatic merge failed; fix conflicts and then commit the result.
        : alter .temp-workdir/master|MERGING; ls
        ./  ../  Documentation/  t/  wt-status.c

Because .temp-workdir is empty when merge is run, we consider that your
working tree exactly matches what is in your index. We do check out the
cleanly merged result to this temporary working tree (wt-status.c is
cleanly merged and result can be seen there), but it is not strictly
necessary (IOW we could make that part optional). We do write conflicted
half-merge result, as that is the easiest way for the user to help the
index resolve it.

    Side Note: the "recursive" strategy is so broken that it may assume
    the working tree has to be populated and the above may not work as
    nicely.

In other words, we are already half-way there, I think.

--
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]