apply: get rid of --index-info in favor of --build-fake-ancestor
git-am used "git apply -z --index-info" to find the original versions of the files touched by the diff, to be able to do an inexpensive three-way merge. This operation makes only sense in a repository, since the index information in the diff refers to blobs, which have to be present in the current repository. Therefore, teach "git apply" a mode to write out the result as an index file to begin with, obviating the need for scripts to do it themselves. The sole user for --index-info is "git am" is converted to use --build-fake-ancestor in this patch. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
parent
102c2338da
commit
26b2800768
@ -10,7 +10,7 @@ SYNOPSIS
|
||||
--------
|
||||
[verse]
|
||||
'git-apply' [--stat] [--numstat] [--summary] [--check] [--index]
|
||||
[--apply] [--no-add] [--index-info] [-R | --reverse]
|
||||
[--apply] [--no-add] [--build-fake-ancestor <file>] [-R | --reverse]
|
||||
[--allow-binary-replacement | --binary] [--reject] [-z]
|
||||
[-pNUM] [-CNUM] [--inaccurate-eof] [--cached]
|
||||
[--whitespace=<nowarn|warn|error|error-all|strip>]
|
||||
@ -63,12 +63,15 @@ OPTIONS
|
||||
cached data, apply the patch, and store the result in the index,
|
||||
without using the working tree. This implies '--index'.
|
||||
|
||||
--index-info::
|
||||
--build-fake-ancestor <file>::
|
||||
Newer git-diff output has embedded 'index information'
|
||||
for each blob to help identify the original version that
|
||||
the patch applies to. When this flag is given, and if
|
||||
the original version of the blob is available locally,
|
||||
outputs information about them to the standard output.
|
||||
the original versions of the blobs is available locally,
|
||||
builds a temporary index containing those blobs.
|
||||
+
|
||||
When a pure mode change is encountered (which has no index information),
|
||||
the information is read from the current index instead.
|
||||
|
||||
-R, --reverse::
|
||||
Apply the patch in reverse.
|
||||
|
@ -41,7 +41,7 @@ static int apply_in_reverse;
|
||||
static int apply_with_reject;
|
||||
static int apply_verbosely;
|
||||
static int no_add;
|
||||
static int show_index_info;
|
||||
static const char *fake_ancestor;
|
||||
static int line_termination = '\n';
|
||||
static unsigned long p_context = ULONG_MAX;
|
||||
static const char apply_usage[] =
|
||||
@ -2248,9 +2248,12 @@ static int get_current_sha1(const char *path, unsigned char *sha1)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void show_index_list(struct patch *list)
|
||||
/* Build an index that contains the just the files needed for a 3way merge */
|
||||
static void build_fake_ancestor(struct patch *list, const char *filename)
|
||||
{
|
||||
struct patch *patch;
|
||||
struct index_state result = { 0 };
|
||||
int fd;
|
||||
|
||||
/* Once we start supporting the reverse patch, it may be
|
||||
* worth showing the new sha1 prefix, but until then...
|
||||
@ -2258,11 +2261,12 @@ static void show_index_list(struct patch *list)
|
||||
for (patch = list; patch; patch = patch->next) {
|
||||
const unsigned char *sha1_ptr;
|
||||
unsigned char sha1[20];
|
||||
struct cache_entry *ce;
|
||||
const char *name;
|
||||
|
||||
name = patch->old_name ? patch->old_name : patch->new_name;
|
||||
if (0 < patch->is_new)
|
||||
sha1_ptr = null_sha1;
|
||||
continue;
|
||||
else if (get_sha1(patch->old_sha1_prefix, sha1))
|
||||
/* git diff has no index line for mode/type changes */
|
||||
if (!patch->lines_added && !patch->lines_deleted) {
|
||||
@ -2277,13 +2281,16 @@ static void show_index_list(struct patch *list)
|
||||
else
|
||||
sha1_ptr = sha1;
|
||||
|
||||
printf("%06o %s ",patch->old_mode, sha1_to_hex(sha1_ptr));
|
||||
if (line_termination && quote_c_style(name, NULL, NULL, 0))
|
||||
quote_c_style(name, NULL, stdout, 0);
|
||||
else
|
||||
fputs(name, stdout);
|
||||
putchar(line_termination);
|
||||
ce = make_cache_entry(patch->old_mode, sha1_ptr, name, 0, 0);
|
||||
if (add_index_entry(&result, ce, ADD_CACHE_OK_TO_ADD))
|
||||
die ("Could not add %s to temporary index", name);
|
||||
}
|
||||
|
||||
fd = open(filename, O_WRONLY | O_CREAT, 0666);
|
||||
if (fd < 0 || write_index(&result, fd) || close(fd))
|
||||
die ("Could not write temporary index to %s", filename);
|
||||
|
||||
discard_index(&result);
|
||||
}
|
||||
|
||||
static void stat_patch_list(struct patch *patch)
|
||||
@ -2805,8 +2812,8 @@ static int apply_patch(int fd, const char *filename, int inaccurate_eof)
|
||||
if (apply && write_out_results(list, skipped_patch))
|
||||
exit(1);
|
||||
|
||||
if (show_index_info)
|
||||
show_index_list(list);
|
||||
if (fake_ancestor)
|
||||
build_fake_ancestor(list, fake_ancestor);
|
||||
|
||||
if (diffstat)
|
||||
stat_patch_list(list);
|
||||
@ -2914,9 +2921,11 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
|
||||
apply = 1;
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(arg, "--index-info")) {
|
||||
if (!strcmp(arg, "--build-fake-ancestor")) {
|
||||
apply = 0;
|
||||
show_index_info = 1;
|
||||
if (++i >= argc)
|
||||
die ("need a filename");
|
||||
fake_ancestor = argv[i];
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(arg, "-z")) {
|
||||
|
@ -62,10 +62,8 @@ fall_back_3way () {
|
||||
mkdir "$dotest/patch-merge-tmp-dir"
|
||||
|
||||
# First see if the patch records the index info that we can use.
|
||||
git apply -z --index-info "$dotest/patch" \
|
||||
>"$dotest/patch-merge-index-info" &&
|
||||
GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \
|
||||
git update-index -z --index-info <"$dotest/patch-merge-index-info" &&
|
||||
git apply --build-fake-ancestor "$dotest/patch-merge-tmp-index" \
|
||||
"$dotest/patch" &&
|
||||
GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \
|
||||
git write-tree >"$dotest/patch-merge-base+" ||
|
||||
cannot_fallback "Repository lacks necessary blobs to fall back on 3-way merge."
|
||||
|
Loading…
Reference in New Issue
Block a user