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