Skip to content

Commit

Permalink
apply: get rid of --index-info in favor of --build-fake-ancestor
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Johannes Schindelin authored and Junio C Hamano committed Sep 19, 2007
1 parent 89df580 commit 7a98869
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 21 deletions.
11 changes: 7 additions & 4 deletions Documentation/git-apply.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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>]
Expand Down Expand Up @@ -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.
Expand Down
35 changes: 22 additions & 13 deletions builtin-apply.c
Original file line number Diff line number Diff line change
Expand Up @@ -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[] =
Expand Down Expand Up @@ -2248,21 +2248,25 @@ 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...
*/
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) {
Expand All @@ -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)
Expand Down Expand Up @@ -2803,8 +2810,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);
Expand Down Expand Up @@ -2912,9 +2919,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")) {
Expand Down
6 changes: 2 additions & 4 deletions git-am.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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."
Expand Down

0 comments on commit 7a98869

Please sign in to comment.