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>
The mess known as the progress meter in merge-recursive was my own
fault; I put it in thinking that we might be spending a lot of time
resolving unmerged entries in the index that were not handled by
the simple 3-way index merge code.
Turns out we don't really spend that much time there, so the progress
meter was pretty much always jumping to "(n/n) 100%" as soon as
the program started. That isn't a very good indication of progress.
Since I don't have a great solution for how a progress meter should
work here, I'm proposing we back it out entirely.
Signed-off-by: Shawn O. Pearce <spearce@spearce.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
Alex Riesen noticed that the case where a file replaced a directory entry
in the working tree was broken on cygwin. It turns out that the code made
some Linux-specific assumptions, and also ignored errors entirely for the
case where the entry was a symlink rather than a file.
This cleans it up by separating out the common case into a function of its
own, so that both regular files and symlinks can share it, and by making
the error handling more obvious (and not depend on any Linux-specific
behaviour).
Acked-by: Alex Riesen <raa.lkml@gmail.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>
There is no need to intern the string to git_attr, as we are already
dealing with the name of the driver there.
Signed-off-by: Junio C Hamano <junkio@cox.net>
When the configuration has variables unrelated to low-level
merge drivers (e.g. merge.summary), the code failed to ignore
them but did something totally senseless.
Signed-off-by: Junio C Hamano <junkio@cox.net>
It was bothering me a lot that I abused small integer values
casted to (void *) to represent non string values in
gitattributes. This corrects it by making the type of attribute
values (const char *), and using the address of a few statically
allocated character buffer to denote true/false. Unset attributes
are represented as having NULLs as their values.
Added in-header documentation to explain how git_checkattr()
routine should be called.
Signed-off-by: Junio C Hamano <junkio@cox.net>
This allows [merge "drivername"] to have a variable "recursive"
that names a different low-level merge driver to be used when
merging common ancestors to come up with a virtual ancestor.
Signed-off-by: Junio C Hamano <junkio@cox.net>
This changes the configuration syntax for defining a low-level
merge driver to be:
[merge "<<drivername>>"]
driver = "<<command line>>"
name = "<<driver description>>"
which is much nicer to read and is extensible. Credit goes to
Martin Waitz and Linus.
In addition, when we use an external low-level merge driver, it
is reported as an extra output from merge-recursive, using the
value of merge.<<drivername>.name variable.
The demonstration in t6026 has also been updated.
Signed-off-by: Junio C Hamano <junkio@cox.net>
When no 'merge' attribute is given to a path, merge-recursive
uses the built-in xdl-merge as the low-level merge driver.
A new configuration item 'merge.default' can name a low-level
merge driver of user's choice to be used instead.
Signed-off-by: Junio C Hamano <junkio@cox.net>
This allows users to specify custom low-level merge driver per
path, using the attributes mechanism. Just like you can specify
one of built-in "text", "binary", "union" low-level merge
drivers by saying:
* merge=text
.gitignore merge=union
*.jpg merge=binary
pick a name of your favorite merge driver, and assign it as the
value of the 'merge' attribute.
A custom low-level merge driver is defined via the config
mechanism. This patch introduces 'merge.driver', a multi-valued
configuration. Its value is the name (i.e. the one you use as
the value of 'merge' attribute) followed by a command line
specification. The command line can contain %O, %A, and %B to
be interpolated with the names of temporary files that hold the
common ancestor version, the version from your branch, and the
version from the other branch, and the resulting command is
spawned.
The low-level merge driver is expected to update the temporary
file for your branch (i.e. %A) with the result and exit with
status 0 for a clean merge, and non-zero status for a conflicted
merge.
A new test in t6026 demonstrates a sample usage.
Signed-off-by: Junio C Hamano <junkio@cox.net>
This allows 'merge' attribute to control how the file-level
three-way merge is done per path.
- If you set 'merge' to true, leave it unspecified, or set it
to "text", we use the built-in 3-way xdl-merge.
- If you set 'merge' to false, or set it to "binary, the
"binary" merge is done. The merge result is the blob from
'our' tree, but this still leaves the path conflicted, so
that the mess can be sorted out by the user. This is
obviously meant to be useful for binary files.
- 'merge=union' (this is the first example of a string valued
attribute, introduced in the previous one) uses the "union"
merge. The "union" merge takes lines in conflicted hunks
from both sides, which is useful for line-oriented files such
as .gitignore.
Instead fo setting merge to 'true' or 'false' by using 'merge'
or '-merge', setting it explicitly to "text" or "binary" will
become useful once we start allowing custom per-path backends to
be added, and allow them to be activated for the default
(i.e. 'merge' attribute specified to 'true' or 'false') case,
using some other mechanisms. Setting merge attribute to "text"
or "binary" will be a way to explicitly request to override such
a custom default for selected paths.
Currently there is no way to specify random programs but it
should be trivial for motivated contributors to add later.
There is one caveat, though. ll_merge() is called for both
internal ancestor merge and the outer "final" merge. I think an
interactive custom per-path merge backend should refrain from
going interactive when performing an internal merge (you can
tell it by checking call_depth) and instead just call either
ll_xdl_merge() if the content is text, or call ll_binary_merge()
otherwise.
Signed-off-by: Junio C Hamano <junkio@cox.net>
When a path D that originally was blob in the ancestor was
modified on our branch while it was removed on the other branch,
we keep stages 1 and 2, and leave our version in the working
tree. If the other branch created a path D/F, however, that
path can cleanly be resolved in the index (after all, the
ancestor nor we do not have it and only the other side added),
but it cannot be checked out. The issue is the same when the
other branch had D and we had renamed it to D/F, or the ancestor
had D/F instead of D (so there are four combinations).
Do not stop the merge, but leave both D and D/F paths in the
index so that the user can clear things up.
Signed-off-by: Junio C Hamano <junkio@cox.net>
When update-trees::threeway_merge() decides that a path that
exists in the current index (and HEAD) is to be removed, it
leaves a stage 0 entry whose mode bits are set to 0. The code
mistook it as "this stage wants the blob here", and proceeded
to call update_file_flags() which ended up trying to put the
mode=0 entry in the index, got very confused, and ended up
barfing with "do not know what to do with 000000".
Since threeway_merge() does not handle case #10 (one side
removes while the other side does not do anything), this is not
a problem while we refuse to merge branches that have D/F
conflicts, but when we start resolving them, we would need to be
able to remove cache entries, and at that point it starts to
matter.
Signed-off-by: Junio C Hamano <junkio@cox.net>
This merge strategy largely piggy-backs on git-merge-recursive.
When merging trees A and B, if B corresponds to a subtree of A,
B is first adjusted to match the tree structure of A, instead of
reading the trees at the same level. This adjustment is also
done to the common ancestor tree.
If you are pulling updates from git-gui repository into git.git
repository, the root level of the former corresponds to git-gui/
subdirectory of the latter. The tree object of git-gui's toplevel
is wrapped in a fake tree object, whose sole entry has name 'git-gui'
and records object name of the true tree, before being used by
the 3-way merge code.
If you are merging the other way, only the git-gui/ subtree of
git.git is extracted and merged into git-gui's toplevel.
The detection of corresponding subtree is done by comparing the
pathnames and types in the toplevel of the tree.
Heuristics galore! That's the git way ;-).
Signed-off-by: Junio C Hamano <junkio@cox.net>
This error message should not usually trigger, but the function
make_cache_entry() called by add_cacheinfo() can return early
without calling into refresh_cache_entry() that sets cache_errno.
Also the error message had a wrong function name reported, and
it did not say anything about which path failed either.
Signed-off-by: Junio C Hamano <junkio@cox.net>
When defined, this allows plumbing commands that update the
index (add, apply, checkout-index, merge-recursive, mv,
read-tree, rm, update-index, and write-tree) to write their
resulting index to an alternative index file while holding a
lock to the original index file. With this, git-commit that
jumps the index does not have to make an extra copy of the index
file, and more importantly, it can do the update while holding
the lock on the index.
However, I think the interface to let an environment variable
specify the output is a mistake, as shown in the documentation.
If a curious user has the environment variable set to something
other than the file GIT_INDEX_FILE points at, almost everything
will break. This should instead be a command line parameter to
tell these plumbing commands to write the result in the named
file, to prevent stupid mistakes.
Signed-off-by: Junio C Hamano <junkio@cox.net>
This patch leaves the base name in the resulting intermediate tree, to
propagate the conflict from intermediate merges up to the top-level merge.
Signed-off-by: Alex Riesen <raa.lkml@gmail.com>
Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Junio C Hamano <junkio@cox.net>