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:
Johannes Schindelin 2007-09-17 23:34:06 +01:00 committed by Junio C Hamano
parent 89df580d0a
commit 7a98869935
3 changed files with 31 additions and 21 deletions

View File

@ -10,7 +10,7 @@ SYNOPSIS
-------- --------
[verse] [verse]
'git-apply' [--stat] [--numstat] [--summary] [--check] [--index] '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] [--allow-binary-replacement | --binary] [--reject] [-z]
[-pNUM] [-CNUM] [--inaccurate-eof] [--cached] [-pNUM] [-CNUM] [--inaccurate-eof] [--cached]
[--whitespace=<nowarn|warn|error|error-all|strip>] [--whitespace=<nowarn|warn|error|error-all|strip>]
@ -63,12 +63,15 @@ OPTIONS
cached data, apply the patch, and store the result in the index, cached data, apply the patch, and store the result in the index,
without using the working tree. This implies '--index'. without using the working tree. This implies '--index'.
--index-info:: --build-fake-ancestor <file>::
Newer git-diff output has embedded 'index information' Newer git-diff output has embedded 'index information'
for each blob to help identify the original version that for each blob to help identify the original version that
the patch applies to. When this flag is given, and if the patch applies to. When this flag is given, and if
the original version of the blob is available locally, the original versions of the blobs is available locally,
outputs information about them to the standard output. 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:: -R, --reverse::
Apply the patch in reverse. Apply the patch in reverse.

View File

@ -41,7 +41,7 @@ static int apply_in_reverse;
static int apply_with_reject; static int apply_with_reject;
static int apply_verbosely; static int apply_verbosely;
static int no_add; static int no_add;
static int show_index_info; static const char *fake_ancestor;
static int line_termination = '\n'; static int line_termination = '\n';
static unsigned long p_context = ULONG_MAX; static unsigned long p_context = ULONG_MAX;
static const char apply_usage[] = static const char apply_usage[] =
@ -2248,9 +2248,12 @@ static int get_current_sha1(const char *path, unsigned char *sha1)
return 0; 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 patch *patch;
struct index_state result = { 0 };
int fd;
/* Once we start supporting the reverse patch, it may be /* Once we start supporting the reverse patch, it may be
* worth showing the new sha1 prefix, but until then... * 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) { for (patch = list; patch; patch = patch->next) {
const unsigned char *sha1_ptr; const unsigned char *sha1_ptr;
unsigned char sha1[20]; unsigned char sha1[20];
struct cache_entry *ce;
const char *name; const char *name;
name = patch->old_name ? patch->old_name : patch->new_name; name = patch->old_name ? patch->old_name : patch->new_name;
if (0 < patch->is_new) if (0 < patch->is_new)
sha1_ptr = null_sha1; continue;
else if (get_sha1(patch->old_sha1_prefix, sha1)) else if (get_sha1(patch->old_sha1_prefix, sha1))
/* git diff has no index line for mode/type changes */ /* git diff has no index line for mode/type changes */
if (!patch->lines_added && !patch->lines_deleted) { if (!patch->lines_added && !patch->lines_deleted) {
@ -2277,13 +2281,16 @@ static void show_index_list(struct patch *list)
else else
sha1_ptr = sha1; sha1_ptr = sha1;
printf("%06o %s ",patch->old_mode, sha1_to_hex(sha1_ptr)); ce = make_cache_entry(patch->old_mode, sha1_ptr, name, 0, 0);
if (line_termination && quote_c_style(name, NULL, NULL, 0)) if (add_index_entry(&result, ce, ADD_CACHE_OK_TO_ADD))
quote_c_style(name, NULL, stdout, 0); die ("Could not add %s to temporary index", name);
else
fputs(name, stdout);
putchar(line_termination);
} }
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) static void stat_patch_list(struct patch *patch)
@ -2803,8 +2810,8 @@ static int apply_patch(int fd, const char *filename, int inaccurate_eof)
if (apply && write_out_results(list, skipped_patch)) if (apply && write_out_results(list, skipped_patch))
exit(1); exit(1);
if (show_index_info) if (fake_ancestor)
show_index_list(list); build_fake_ancestor(list, fake_ancestor);
if (diffstat) if (diffstat)
stat_patch_list(list); stat_patch_list(list);
@ -2912,9 +2919,11 @@ int cmd_apply(int argc, const char **argv, const char *unused_prefix)
apply = 1; apply = 1;
continue; continue;
} }
if (!strcmp(arg, "--index-info")) { if (!strcmp(arg, "--build-fake-ancestor")) {
apply = 0; apply = 0;
show_index_info = 1; if (++i >= argc)
die ("need a filename");
fake_ancestor = argv[i];
continue; continue;
} }
if (!strcmp(arg, "-z")) { if (!strcmp(arg, "-z")) {

View File

@ -62,10 +62,8 @@ fall_back_3way () {
mkdir "$dotest/patch-merge-tmp-dir" mkdir "$dotest/patch-merge-tmp-dir"
# First see if the patch records the index info that we can use. # First see if the patch records the index info that we can use.
git apply -z --index-info "$dotest/patch" \ git apply --build-fake-ancestor "$dotest/patch-merge-tmp-index" \
>"$dotest/patch-merge-index-info" && "$dotest/patch" &&
GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \
git update-index -z --index-info <"$dotest/patch-merge-index-info" &&
GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \ GIT_INDEX_FILE="$dotest/patch-merge-tmp-index" \
git write-tree >"$dotest/patch-merge-base+" || git write-tree >"$dotest/patch-merge-base+" ||
cannot_fallback "Repository lacks necessary blobs to fall back on 3-way merge." cannot_fallback "Repository lacks necessary blobs to fall back on 3-way merge."