This makes "subtree" more orthogonal to the rest of recursive merge, so
that you can use subtree and ours/theirs features at the same time. For
example, you can now say:
git merge -s subtree -Xtheirs other
to merge with "other" branch while shifting it up or down to match the
shape of the tree of the current branch, and resolving conflicts favoring
the changes "other" branch made over changes made in the current branch.
It also allows the prefix used to shift the trees to be specified using
the "-Xsubtree=$prefix" option. Giving an empty prefix tells the command
to figure out how much to shift trees automatically as we have always
done. "merge -s subtree" is the same as "merge -s recursive -Xsubtree="
(or "merge -s recursive -Xsubtree").
Based on an old patch done back in the days when git-merge was a script;
Avery ported the script part to builtin-merge.c. Bugs in shift_tree()
is mine.
Signed-off-by: Avery Pennarun <apenwarr@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Teach "-X <option>" command line argument to "git merge" that is passed to
strategy implementations. "ours" and "theirs" autoresolution introduced
by the previous commit can be asked to the recursive strategy.
Signed-off-by: Avery Pennarun <apenwarr@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Usage messages (for example, from "git merge-recursive -h") are
friendlier when not preceded by "fatal".
Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
GCC 4.4.0 on Windows does not like the format %zu. It is quite unlikely,
though, that we need more merge bases than a %d can display, so replace
the %zu by a %d.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Steffen Prohaska <prohaska@zib.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
LF at the end of format strings given to die() is redundant because
die already adds one on its own.
Signed-off-by: Alexander Potashev <aspotashev@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
When merge-recursive wanted to create a new file in the work tree (either
as the final result, or a hint for reference purposes while delete/modify
conflicts), it unconditionally overwrote an untracked file in the working
tree. Be careful not to lose whatever the user has that is not tracked.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Besides, it fixes a memleak (builtin-rm.c) and accidental change of
the input const argument (builtin-merge-recursive.c).
Signed-off-by: Alex Riesen <raa.lkml@gmail.com>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
The code was actually supposed to do that, but was accidentally broken.
Noticed by Anders Melchiorsen.
Signed-off-by: Alex Riesen <raa.lkml@gmail.com>
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
This makes it possible to avoid passing the labels of branches as
arguments to merge_recursive(), merge_trees() and
merge_recursive_generic().
It also takes care of subtree merge, output buffering, verbosity, and
rename limits - these were global variables till now in
merge-recursive.c.
A new function, named init_merge_options(), is introduced as well, it
clears the struct merge_info, then initializes with default values,
finally updates the default values based on the config and environment
variables.
Signed-off-by: Miklos Vajna <vmiklos@frugalware.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
merge_recursive_generic() takes, in comparison to to merge_recursive(),
no commit ("struct commit *") arguments but SHA ids ("unsigned char *"),
and no commit list of bases but an array of refs ("const char **").
This makes it more generic in the case that it can also take the SHA
of a tree to merge trees without commits, for the bases, the head
and the remote.
merge_recursive_generic() also handles locking and updating of the
index, which is a common use case of merge_recursive().
This patch also rewrites builtin-merge-recursive.c to make use of
merge_recursive_generic(). By doing this, I stumbled over the
limitation of 20 bases and I've added a warning if this limitation
is exceeded.
This patch qualifies make_virtual_commit() as static again because
this function is not needed anymore outside merge-recursive.c.
Signed-off-by: Stephan Beyer <s-beyer@gmx.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Move most of the of code from builtin-merge-recursive.c to a new file
merge-recursive.c and introduce merge_recursive_setup() in there so that
builtin-merge-recursive and other builtins call it.
Signed-off-by: Miklos Vajna <vmiklos@frugalware.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This teaches the low-level ll_xdl_merge() routine to honor
merge.conflictstyle configuration variable, so that merge-recursive
strategy can show the conflicts in the style of user's choice.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
During a conflicting merge, you would typically see:
Auto-merged foo.txt
CONFLICT (content): Merge conflict in foo.txt
Recorded preimage for 'foo.txt'
Automatic merge failed; fix conflicts and then commit the result.
and left wondering what happened to "foo.txt". Did it succeed, and then
conflicted, and then what?
This is because historically there was a progress bar displayed before the
auto-merge is mentioned, and it was expected to take long time, before we
can say "Auto-merged foo.txt". It turns out it was not the case, and the
original wording "Auto-merging foo.txt" we used to have before 89f40be
(Convert output messages in merge-recursive to past tense., 2007-01-14) is
better.
Acked-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The name path_list was correct for the first usage of that data structure,
but it really is a general-purpose string list.
$ perl -i -pe 's/path-list/string-list/g' $(git grep -l path-list)
$ perl -i -pe 's/path_list/string_list/g' $(git grep -l path_list)
$ git mv path-list.h string-list.h
$ git mv path-list.c string-list.c
$ perl -i -pe 's/has_path/has_string/g' $(git grep -l has_path)
$ perl -i -pe 's/path/string/g' string-list.[ch]
$ git mv Documentation/technical/api-path-list.txt \
Documentation/technical/api-string-list.txt
$ perl -i -pe 's/strdup_paths/strdup_strings/g' $(git grep -l strdup_paths)
... and then fix all users of string-list to access the member "string"
instead of "path".
Documentation/technical/api-string-list.txt needed some rewrapping, too.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Add a pointer parameter to read_tree_recursive(), which is passed to the
callback function. This allows callers of read_tree_recursive() to
share data with the callback without resorting to global variables. All
current callers pass NULL.
Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This function is useful outside builtin-merge-recursive, for example in
builtin-merge.
Signed-off-by: Miklos Vajna <vmiklos@frugalware.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The shell version used to use "mkdir -p" to create the repo
path, but the C version just calls "mkdir". Let's replicate
the old behavior. We have to create the git and worktree
leading dirs separately; while most of the time, the
worktree dir contains the git dir (as .git), the user can
override this using GIT_WORK_TREE.
We can reuse safe_create_leading_directories, but we need to
make a copy of our const buffer to do so. Since
merge-recursive uses the same pattern, we can factor this
out into a global function. This has two other cleanup
advantages for merge-recursive:
1. mkdir_p wasn't a very good name. "mkdir -p foo/bar" actually
creates bar, but this function just creates the leading
directories.
2. mkdir_p took a mode argument, but it was completely
ignored.
Acked-by: Daniel Barkalow <barkalow@iabervon.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The shell version used to use "mkdir -p" to create the repo
path, but the C version just calls "mkdir". Let's replicate
the old behavior. We have to create the git and worktree
leading dirs separately; while most of the time, the
worktree dir contains the git dir (as .git), the user can
override this using GIT_WORK_TREE.
We can reuse safe_create_leading_directories, but we need to
make a copy of our const buffer to do so. Since
merge-recursive uses the same pattern, we can factor this
out into a global function. This has two other cleanup
advantages for merge-recursive:
1. mkdir_p wasn't a very good name. "mkdir -p foo/bar" actually
creates bar, but this function just creates the leading
directories.
2. mkdir_p took a mode argument, but it was completely
ignored.
Acked-by: Daniel Barkalow <barkalow@iabervon.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The code forgot to convert the blob contents into work tree
representation before writing it out. Also fixes leaks -- earlier
the updated blobs were never freed.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
git_config() only had a function parameter, but no callback data
parameter. This assumes that all callback functions only modify
global variables.
With this patch, every callback gets a void * parameter, and it is hoped
that this will help the libification effort.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
In many cases, the warning ends up as clutter, because the
diff is being done "behind the scenes" from the user (e.g.,
when generating a commit diffstat), and whether we show
renames or not is not particularly interesting to the user.
However, in the case of a merge (which is what motivated the
warning in the first place), it is a useful hint as to why a
merge with renames might have failed.
This patch makes the warning optional based on the code
calling into diffcore. We default to not showing the
warning, but turn it on for merges.
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The current rename limit default of 100 was arbitrarily
chosen. Testing[1] has shown that on modern hardware, a
limit of 200 adds about a second of computation time, and a
limit of 500 adds about 5 seconds of computation time.
This patch bumps the default limit to 200 for viewing diffs,
and to 500 for performing a merge. The limit for generating
git-status templates is set independently; we bump it up to
200 here, as well, to match the diff limit.
[1]: See <20080211113516.GB6344@coredump.intra.peff.net>
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The point of rename limiting is to bound the amount of time
we spend figuring out inexact renames. Currently we use a
single value, diff.renamelimit, for all situations. However,
it is probably the case that a user is willing to spend more
time finding renames during a merge than they are while
looking at git-log.
This patch provides a way of setting those values separately
(though for backwards compatibility, merge still falls back
on the diff renamelimit).
Signed-off-by: Jeff King <peff@peff.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
We will always unpack into our own internal index, but we will take the
source from wherever specified, and we will optionally write the result
to a specified index (optionally, because not everybody even _wants_ any
result: the index diffing really wants to just walk the tree and index
in parallel).
This ends up removing a fair number more lines than it adds, for the
simple reason that we can now skip all the crud that tried to be
oh-so-careful about maintaining our position in the index as we were
traversing and modifying it. Since we don't actually modify the source
index any more, we can just update the 'o->pos' pointer without worrying
about whether an index entry got removed or replaced or added to.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This is just a very mechanical conversion, and makes everybody set it to
'&the_index' before calling, but at least it makes it more explicit
where we work with the index.
The next stage would be to split that index usage up into a 'source' and
a 'destination' index, so that we can unpack into a different index than
we started out from.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This makes write_tree_from_memory(), which writes the active cache as
a tree and returns the struct tree for it, available to other code. It
also makes available merge_trees(), which does the internal merge of
two trees with a known base, and merge_recursive(), which does the
recursive internal merge of two commits with a list of common
ancestors.
The first two of these will be used by checkout -m, and the third is
presumably useful in general, although the implementation of checkout
-m which entirely matches the behavior of the shell version does not
use it (since it ignores the difference of ancestry between the old
branch and the new branch).
Signed-off-by: Daniel Barkalow <barkalow@iabervon.org>
This converts the index explicitly on read and write to its on-disk
format, allowing the in-core format to contain more flags, and be
simpler.
In particular, the in-core format is now host-endian (as opposed to the
on-disk one that is network endian in order to be able to be shared
across machines) and as a result we can dispense with all the
htonl/ntohl on accesses to the cache_entry fields.
This will make it easier to make use of various temporary flags that do
not exist in the on-disk format.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
When merging conflicting submodule changes from a supermodule, generate
a conflict message saying what went wrong. Also leave the tree in a state
where git status shows the conflict, and git submodule status gives the user
enough information to do the merge manally. Previously this would just fail.
Signed-off-by: Finn Arne Gangstad <finnag@pvv.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
merge-recursive did not support merging trees that have conflicting
changes in submodules they contain, and died. Support it exactly the
same way as how it handles conflicting symbolic link changes --- mark it
as a conflict, take the tentative result from the current side, and
letting the caller resolve the conflict, without dying in merge_file()
function.
Also reword the error message issued when merge_file() has to die
because it sees a tree entry of type it does not support yet.
[jc: fixed up initial draft by Finn Arne Gangstad]
Signed-off-by: Junio C Hamano <gitster@pobox.com>
reverse_diff was a bit-value in disguise, it's merged in the flags now.
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
It might be a sign of source code management gone bad, but when two branches
has diverged almost beyond recognition and time has come for the branches to
merge, the user is going to need all the help his tool can give him. Honoring
diff.renamelimit has great potential as a painkiller in such situations.
The painkiller effect could have been achieved by e.g. 'merge.renamelimit',
but the flexibility gained by a separate option is questionable: our user
would probably expect git to detect renames equally good when merging as
when diffing (I known I did).
Signed-off-by: Lars Hjemli <hjemli@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The called function merge_trees() sets its *result, to which the
address of the variable mrtree in merge() function is passed,
only when index_only is set. But that is Ok as the function
uses the value in the variable only under index_only iteration.
However, recent gcc does not realize this. Work it around by
adding a fake initializer.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
The function make_cache_entry() is too useful to be hidden away in
merge-recursive. So move it to libgit.a (exposing it via cache.h).
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
It might be a sign of source code management gone bad, but when two branches
has diverged almost beyond recognition and time has come for the branches to
merge, the user is going to need all the help his tool can give him. Honoring
diff.renamelimit has great potential as a painkiller in such situations.
The painkiller effect could have been achieved by e.g. 'merge.renamelimit',
but the flexibility gained by a separate option is questionable: our user
would probably expect git to detect renames equally good when merging as
when diffing (I known I did).
Signed-off-by: Lars Hjemli <hjemli@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
* drop nfasprintf.
* move nfvasprintf into imap-send.c back, and let it work on a 8k buffer,
and die() in case of overflow. It should be enough for imap commands, if
someone cares about imap-send, he's welcomed to fix it properly.
* replace nfvasprintf use in merge-recursive with a copy of the strbuf_addf
logic, it's one place, we'll live with it.
To ease the change, output_buffer string list is replaced with a strbuf ;)
* rework trace.c to call vsnprintf itself. It's used to format strerror()s
and git command names, it should never be more than a few octets long, let
it work on a 8k static buffer with vsnprintf or die loudly.
Signed-off-by: Pierre Habouzit <madcoder@debian.org>
The function make_cache_entry() is too useful to be hidden away in
merge-recursive. So move it to libgit.a (exposing it via cache.h).
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
xmkstemp() performs error checking and prints a standard error message when
an error occur.
Signed-off-by: Luiz Fernando N. Capitulino <lcapitulino@mandriva.com.br>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
When you try to merge a path that involves binary file-level
merge, merge-recursive died rudely without cleaning up its own
mess. A files added by the merge were left in the working tree,
but the index was not written out (because it just punted and
died), so it was cumbersome for the user to retry it by first
running "git reset --hard".
This changes merge-recursive to still warn but do the "binary"
merge for such a path; leave the "our" version in the working
tree, but still keep the path unmerged so that the user can sort
it out.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This doesn't actually change any real code, but it changes the interface
to unpack_trees() to take an array of "struct tree_desc" entries, the same
way the tree-walk.c functions do.
The reason for this is that we would be much better off if we can do the
tree-unpacking using the generic "traverse_trees()" functionality instead
of having to the special "unpack" infrastructure.
This really is a pretty minimal diff, just to change the calling
convention. It passes all the tests, and looks sane. There were only two
users of "unpack_trees()": builtin-read-tree and merge-recursive, and I
tried to keep the changes minimal.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
[jc: cherry-picked 9f30855 from 'master']
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
as it is not relevant for whether the result should be written.
Even if no real merge happened, there might be _no_ reason to
rewrite the working tree file. Maybe even more so.
Signed-off-by: Alex Riesen <raa.lkml@gmail.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
Also leave a warning for future merge-recursive explorers.
Signed-off-by: Alex Riesen <raa.lkml@gmail.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
If a file is changed in one branch, and renamed and changed to the
same content in another branch than we can skip the rewrite of this
file in the working directory, as the content does not change.
Signed-off-by: Alex Riesen <raa.lkml@gmail.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>