diff-files: show unmerged entries correctly
authorJunio C Hamano <gitster@pobox.com>
Fri, 22 Apr 2011 23:19:27 +0000 (16:19 -0700)
committerJunio C Hamano <gitster@pobox.com>
Sun, 24 Apr 2011 05:35:13 +0000 (22:35 -0700)
Earlier, e9c8409 (diff-index --cached --raw: show tree entry on the LHS
for unmerged entries., 2007-01-05) taught the command to show the object
name and the mode from the entry coming from the tree side when comparing
a tree with an unmerged index.

This is a belated companion patch that teaches diff-files to show the mode
from the entry coming from the working tree side, when comparing an
unmerged index and the working tree.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
diff-lib.c
t/t4046-diff-unmerged.sh [new file with mode: 0755]

index a98385538c307a9beec0087e90ca6a4d8799064d..b782476e4ee7769854d06ad0bbafd1df99ae19b4 100644 (file)
@@ -111,6 +111,8 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
 
                if (ce_stage(ce)) {
                        struct combine_diff_path *dpath;
+                       struct diff_filepair *pair;
+                       unsigned int wt_mode = 0;
                        int num_compare_stages = 0;
                        size_t path_len;
 
@@ -129,7 +131,7 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
 
                        changed = check_removed(ce, &st);
                        if (!changed)
-                               dpath->mode = ce_mode_from_stat(ce, st.st_mode);
+                               wt_mode = ce_mode_from_stat(ce, st.st_mode);
                        else {
                                if (changed < 0) {
                                        perror(ce->name);
@@ -137,7 +139,9 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
                                }
                                if (silent_on_removed)
                                        continue;
+                               wt_mode = 0;
                        }
+                       dpath->mode = wt_mode;
 
                        while (i < entries) {
                                struct cache_entry *nce = active_cache[i];
@@ -183,7 +187,9 @@ int run_diff_files(struct rev_info *revs, unsigned int option)
                         * Show the diff for the 'ce' if we found the one
                         * from the desired stage.
                         */
-                       diff_unmerge(&revs->diffopt, ce->name);
+                       pair = diff_unmerge(&revs->diffopt, ce->name);
+                       if (wt_mode)
+                               pair->two->mode = wt_mode;
                        if (ce_stage(ce) != diff_unmerged_stage)
                                continue;
                }
diff --git a/t/t4046-diff-unmerged.sh b/t/t4046-diff-unmerged.sh
new file mode 100755 (executable)
index 0000000..25d50a6
--- /dev/null
@@ -0,0 +1,87 @@
+#!/bin/sh
+
+test_description='diff with unmerged index entries'
+. ./test-lib.sh
+
+test_expect_success setup '
+       for i in 0 1 2 3
+       do
+               blob=$(echo $i | git hash-object --stdin) &&
+               eval "blob$i=$blob" &&
+               eval "m$i=\"100644 \$blob$i $i\"" || break
+       done &&
+       paths= &&
+       for b in o x
+       do
+               for o in o x
+               do
+                       for t in o x
+                       do
+                               path="$b$o$t" &&
+                               case "$path" in ooo) continue ;; esac
+                               paths="$paths$path " &&
+                               p="     $path" &&
+                               case "$b" in x) echo "$m1$p" ;; esac &&
+                               case "$o" in x) echo "$m2$p" ;; esac &&
+                               case "$t" in x) echo "$m3$p" ;; esac ||
+                               break
+                       done || break
+               done || break
+       done >ls-files-s.expect &&
+       git update-index --index-info <ls-files-s.expect &&
+       git ls-files -s >ls-files-s.actual &&
+       test_cmp ls-files-s.expect ls-files-s.actual
+'
+
+test_expect_success 'diff-files -0' '
+       for path in $paths
+       do
+               >"$path" &&
+               echo ":000000 100644 $_z40 $_z40 U      $path"
+       done >diff-files-0.expect &&
+       git diff-files -0 >diff-files-0.actual &&
+       test_cmp diff-files-0.expect diff-files-0.actual
+'
+
+test_expect_success 'diff-files -1' '
+       for path in $paths
+       do
+               >"$path" &&
+               echo ":000000 100644 $_z40 $_z40 U      $path" &&
+               case "$path" in
+               x??) echo ":100644 100644 $blob1 $_z40 M        $path"
+               esac
+       done >diff-files-1.expect &&
+       git diff-files -1 >diff-files-1.actual &&
+       test_cmp diff-files-1.expect diff-files-1.actual
+'
+
+test_expect_success 'diff-files -2' '
+       for path in $paths
+       do
+               >"$path" &&
+               echo ":000000 100644 $_z40 $_z40 U      $path" &&
+               case "$path" in
+               ?x?) echo ":100644 100644 $blob2 $_z40 M        $path"
+               esac
+       done >diff-files-2.expect &&
+       git diff-files -2 >diff-files-2.actual &&
+       test_cmp diff-files-2.expect diff-files-2.actual &&
+       git diff-files >diff-files-default-2.actual &&
+       test_cmp diff-files-2.expect diff-files-default-2.actual
+'
+
+test_expect_success 'diff-files -3' '
+       for path in $paths
+       do
+               >"$path" &&
+               echo ":000000 100644 $_z40 $_z40 U      $path" &&
+               case "$path" in
+               ??x) echo ":100644 100644 $blob3 $_z40 M        $path"
+               esac
+       done >diff-files-3.expect &&
+       git diff-files -3 >diff-files-3.actual &&
+       test_cmp diff-files-3.expect diff-files-3.actual
+'
+
+test_done