add git-union-merge

This is a new git subcommand, that does a generic union merge operation
between two refs, storing the result in a branch. It operates efficiently
without touching the working tree. It does need to write out a temporary
index file, and may need to write out some other temp files as well.

This could be useful for anything that stores data in a branch,
and needs to merge changes into that branch without actually checking the
branch out. Since conflict handling can't be done without a working copy,
the merge type is always a union merge, which is fine for data stored in
log format (as git-annex does), or in non-conflicting files
(as pristine-tar does).

This probably belongs in git proper, but it will live in git-annex for now.

---

Plan is to move .git-annex/ to a git-annex branch, and use git-union-merge
to handle merging changes when pulling from remotes.

Some preliminary benchmarking using real .git-annex/ data indicates
that it's quite fast, except for the "git add" call, which is as slow
as "git add" tends to be with a big index.
This commit is contained in:
Joey Hess 2011-06-20 19:44:45 -04:00
parent 91e50782ce
commit c835166a7c
7 changed files with 170 additions and 7 deletions

38
doc/git-union-merge.mdwn Normal file
View file

@ -0,0 +1,38 @@
# NAME
git-union-merge - Join branches together using a union merge
# SYNOPSIS
git union-merge branch ref ref
# DESCRIPTION
Does a union merge between two refs, storing the result in the
specified branch.
The union merge will always succeed, but assumes that files can be merged
simply by concacenating together lines from all the oldrefs, in any order.
So, this is useful only for branches containing log-type data.
That this does not touch the checked out working copy. It operates
entirely on git refs and branches.
# EXAMPLE
git union-merge git-annex git-annex origin/git-annex
Merges the current git-annex branch, and a version from origin,
storing the result in the git-annex branch.
# BUGS
File modes are not currently merged.
# AUTHOR
Joey Hess <joey@kitenet.net>
<http://git-annex.branchable.com/>
Warning: this page is automatically made into a man page via [mdwn2man](http://git.ikiwiki.info/?p=ikiwiki;a=blob;f=mdwn2man;hb=HEAD). Edit with care

View file

@ -148,10 +148,8 @@ problem generically. Something like this:
* For remotes, there are also `origin/B`, `otherremote/B`, etc.
* To merge two branches `B` and `foo/B`, construct a merge commit that
makes each file have all lines that were in either version of the file,
with duplicates removed (probably). Do this without checking out a tree,
or using a temporary directory. (One easy but expensive way is to just
check out the branch to a temp dir, union merge into it, and remove the
temp dir ... but it should be possible to do it without using a temp dir.)
with duplicates removed (probably). Do this without checking out a tree.
-- now implemented as git-union-merge
* As a `post-merge` hook, merge `*/B` into `B`. This will ensure `B`
is always up-to-date after a pull from a remote.
* When pushing to a remote, nothing need to be done, except ensure