On Tue, Jul 29, 2014 at 08:00:56AM -0400, Jeff King wrote:
> The implementation just cuts the number of parents down to 1, but
> otherwise runs through the same combined-diff code. The resulting
> pairwise combined-diff differs from a normal diff in a few ways:
>
> 1. The header line is still "diff --combined" (or "--cc") instead of
> "diff --git", and it mentions the filename only once.
>
> 2. The index lines do not contain the file mode; for combined diffs,
> we generate a separate mode line (but only when it has something
> interesting to show).
>
> 3. The hunk header for a single-line change says "-1" in the regular
> code path, but "-1,1" in the combined code path.
>
> Is there any value in keeping this as a pseudo-combined diff (i.e., with
> the combined header, but only a single parent)? It should not be too
> hard to just punt to the regular builtin_diff code path when
> "num_parents == 1".
It's not too hard; mostly we just have to massage the data into a
diff_filepair. Patch is below (I'd squash it, and the further commits
will need fixups to their tests, too).
---
combine-diff.c | 32 +++++++++++++++++++++++++++++---
diff.c | 2 +-
diff.h | 2 ++
t/t4038-diff-combined.sh | 18 +++++++++---------
4 files changed, 41 insertions(+), 13 deletions(-)
diff --git a/combine-diff.c b/combine-diff.c
index 60e54a7..0588c86 100644
--- a/combine-diff.c
+++ b/combine-diff.c
@@ -965,6 +965,28 @@ static int simplify_parents(struct combine_diff_path *p,
int nr)
return 1;
}
+static void show_single_parent_patch(struct combine_diff_path *elem,
+ int working_tree_file,
+ struct rev_info *rev)
+{
+ struct diff_filepair pair;
+
+ memset(&pair, 0, sizeof(pair));
+ pair.one = alloc_filespec(elem->path);
+ pair.two = alloc_filespec(elem->path);
+ pair.status = elem->parent[0].status;
+
+ fill_filespec(pair.one, elem->parent[0].sha1, 1, elem->parent[0].mode);
+ if (working_tree_file)
+ fill_filespec(pair.two, null_sha1, 0, elem->mode);
+ else
+ fill_filespec(pair.two, elem->sha1, 1, elem->mode);
+
+ run_diff(&pair, &rev->diffopt);
+ free_filespec(pair.one);
+ free_filespec(pair.two);
+}
+
static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
int dense, int working_tree_file,
struct rev_info *rev)
@@ -982,6 +1004,13 @@ static void show_patch_diff(struct combine_diff_path
*elem, int num_parent,
int is_binary;
const char *line_prefix = diff_line_prefix(opt);
+ if (rev->simplify_combined_diff)
+ num_parent = simplify_parents(elem, num_parent);
+ if (num_parent == 1) {
+ show_single_parent_patch(elem, working_tree_file, rev);
+ return;
+ }
+
context = opt->context;
userdiff = userdiff_find_by_path(elem->path);
if (!userdiff)
@@ -989,9 +1018,6 @@ static void show_patch_diff(struct combine_diff_path
*elem, int num_parent,
if (DIFF_OPT_TST(opt, ALLOW_TEXTCONV))
textconv = userdiff_get_textconv(userdiff);
- if (rev->simplify_combined_diff)
- num_parent = simplify_parents(elem, num_parent);
-
/* Read the result of merge first */
if (!working_tree_file)
result = grab_blob(elem->sha1, elem->mode, &result_size,
diff --git a/diff.c b/diff.c
index 867f034..558a520 100644
--- a/diff.c
+++ b/diff.c
@@ -3089,7 +3089,7 @@ static void strip_prefix(int prefix_length, const char
**namep, const char **oth
}
}
-static void run_diff(struct diff_filepair *p, struct diff_options *o)
+void run_diff(struct diff_filepair *p, struct diff_options *o)
{
const char *pgm = external_diff();
struct strbuf msg;
diff --git a/diff.h b/diff.h
index b4a624d..a669be0 100644
--- a/diff.h
+++ b/diff.h
@@ -356,4 +356,6 @@ extern int print_stat_summary(FILE *fp, int files,
int insertions, int deletions);
extern void setup_diff_pager(struct diff_options *);
+extern void run_diff(struct diff_filepair *p, struct diff_options *o);
+
#endif /* DIFF_H */
diff --git a/t/t4038-diff-combined.sh b/t/t4038-diff-combined.sh
index d522474..29cdb45 100755
--- a/t/t4038-diff-combined.sh
+++ b/t/t4038-diff-combined.sh
@@ -455,11 +455,11 @@ test_expect_success 'simplify combined --patch' '
merge=$(mkcommit new new $side1 $side2) &&
cat >expect <<-\EOF &&
- diff --combined one
- index df967b9..3e75765
+ diff --git a/one b/one
+ index df967b9..3e75765 100644
--- a/one
+++ b/one
- @@ -1,1 +1,1 @@
+ @@ -1 +1 @@
-base
+new
diff --combined two
@@ -485,11 +485,11 @@ test_expect_success 'do not simplify unless all parents
are identical' '
merge=$(mkcommit new new $side1 $side2 $side3) &&
cat >expect <<-\EOF &&
- diff --combined one
- index df967b9..3e75765
+ diff --git a/one b/one
+ index df967b9..3e75765 100644
--- a/one
+++ b/one
- @@ -1,1 +1,1 @@
+ @@ -1 +1 @@
-base
+new
diff --combined two
@@ -513,11 +513,11 @@ test_expect_success 'do not simplify away mode changes' '
merge=$(mkcommit new new $side1 $side2) &&
cat >expect <<-\EOF &&
- diff --combined one
- index df967b9..3e75765
+ diff --git a/one b/one
+ index df967b9..3e75765 100644
--- a/one
+++ b/one
- @@ -1,1 +1,1 @@
+ @@ -1 +1 @@
-base
+new
diff --combined two
--
2.1.0.rc0.286.g5c67d74
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html