summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohannes Schindelin <Johannes.Schindelin@gmx.de>2007-09-17 23:34:06 +0100
committerJunio C Hamano <gitster@pobox.com>2007-09-18 17:41:18 -0700
commit7a98869935a3682b5ff9679c92bf9bc12f87d8c5 (patch)
treef938e05dafa951d6f18ffb1f6f7c5ba1ffb46bd7
parent89df580d0a2e97b0c7c072d87e5e815534deed56 (diff)
downloadgit-7a98869935a3682b5ff9679c92bf9bc12f87d8c5.tar.gz
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>
-rw-r--r--Documentation/git-apply.txt11
-rw-r--r--builtin-apply.c35
-rwxr-xr-xgit-am.sh6
3 files changed, 31 insertions, 21 deletions
diff --git a/Documentation/git-apply.txt b/Documentation/git-apply.txt
index 4c7e3a2f7f..c1c54bfe0b 100644
--- a/Documentation/git-apply.txt
+++ b/Documentation/git-apply.txt
@@ -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.
diff --git a/builtin-apply.c b/builtin-apply.c
index 86d89a4a7e..6777231c66 100644
--- a/builtin-apply.c
+++ b/builtin-apply.c
@@ -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)
@@ -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);
@@ -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")) {
diff --git a/git-am.sh b/git-am.sh
index 6809aa07f6..5599b93584 100755
--- a/git-am.sh
+++ b/git-am.sh
@@ -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."