Merge branch 'maint-1.6.0' into maint-1.6.1
authorJunio C Hamano <gitster@pobox.com>
Wed, 29 Apr 2009 20:43:13 +0000 (13:43 -0700)
committerJunio C Hamano <gitster@pobox.com>
Wed, 29 Apr 2009 20:43:13 +0000 (13:43 -0700)
* maint-1.6.0:
diff -c -p: do not die on submodules

1  2 
combine-diff.c
t/t4027-diff-submodule.sh
diff --combined combine-diff.c
index bccc018ab2666e769e7865d3cad1d61f04443700,f617e9ded6b7ff2bb7a8d3629480c2ad22667428..0b071b6e256fa655b51f9e484f0633a7f055dd25
@@@ -6,6 -6,7 +6,7 @@@
  #include "quote.h"
  #include "xdiff-interface.h"
  #include "log-tree.h"
+ #include "refs.h"
  
  static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr, int n, int num_parent)
  {
@@@ -90,18 -91,24 +91,24 @@@ struct sline 
        unsigned long *p_lno;
  };
  
- static char *grab_blob(const unsigned char *sha1, unsigned long *size)
+ static char *grab_blob(const unsigned char *sha1, unsigned int mode, unsigned long *size)
  {
        char *blob;
        enum object_type type;
-       if (is_null_sha1(sha1)) {
+       if (S_ISGITLINK(mode)) {
+               blob = xmalloc(100);
+               *size = snprintf(blob, 100,
+                                "Subproject commit %s\n", sha1_to_hex(sha1));
+       } else if (is_null_sha1(sha1)) {
                /* deleted blob */
                *size = 0;
                return xcalloc(1, 1);
+       } else {
+               blob = read_sha1_file(sha1, &type, size);
+               if (type != OBJ_BLOB)
+                       die("object '%s' is not a blob!", sha1_to_hex(sha1));
        }
-       blob = read_sha1_file(sha1, &type, size);
-       if (type != OBJ_BLOB)
-               die("object '%s' is not a blob!", sha1_to_hex(sha1));
        return blob;
  }
  
@@@ -143,6 -150,8 +150,6 @@@ static void append_lost(struct sline *s
  }
  
  struct combine_diff_state {
 -      struct xdiff_emit_state xm;
 -
        unsigned int lno;
        int ob, on, nb, nn;
        unsigned long nmask;
@@@ -195,7 -204,8 +202,8 @@@ static void consume_line(void *state_, 
        }
  }
  
- static void combine_diff(const unsigned char *parent, mmfile_t *result_file,
+ static void combine_diff(const unsigned char *parent, unsigned int mode,
+                        mmfile_t *result_file,
                         struct sline *sline, unsigned int cnt, int n,
                         int num_parent)
  {
        if (!cnt)
                return; /* result deleted */
  
-       parent_file.ptr = grab_blob(parent, &sz);
+       parent_file.ptr = grab_blob(parent, mode, &sz);
        parent_file.size = sz;
 +      memset(&xpp, 0, sizeof(xpp));
        xpp.flags = XDF_NEED_MINIMAL;
        memset(&xecfg, 0, sizeof(xecfg));
 -      ecb.outf = xdiff_outf;
 -      ecb.priv = &state;
        memset(&state, 0, sizeof(state));
 -      state.xm.consume = consume_line;
        state.nmask = nmask;
        state.sline = sline;
        state.lno = 1;
        state.num_parent = num_parent;
        state.n = n;
  
 -      xdi_diff(&parent_file, result_file, &xpp, &xecfg, &ecb);
 +      xdi_diff_outf(&parent_file, result_file, consume_line, &state,
 +                    &xpp, &xecfg, &ecb);
        free(parent_file.ptr);
  
        /* Assign line numbers for this parent.
@@@ -684,16 -695,12 +692,16 @@@ static void show_patch_diff(struct comb
        int i, show_hunks;
        int working_tree_file = is_null_sha1(elem->sha1);
        int abbrev = DIFF_OPT_TST(opt, FULL_INDEX) ? 40 : DEFAULT_ABBREV;
 +      const char *a_prefix, *b_prefix;
        mmfile_t result_file;
  
        context = opt->context;
 +      a_prefix = opt->a_prefix ? opt->a_prefix : "a/";
 +      b_prefix = opt->b_prefix ? opt->b_prefix : "b/";
 +
        /* Read the result of merge first */
        if (!working_tree_file)
-               result = grab_blob(elem->sha1, &result_size);
+               result = grab_blob(elem->sha1, elem->mode, &result_size);
        else {
                /* Used by diff-tree to read from the working tree */
                struct stat st;
                        goto deleted_file;
  
                if (S_ISLNK(st.st_mode)) {
 -                      size_t len = xsize_t(st.st_size);
 -                      result_size = len;
 -                      result = xmalloc(len + 1);
 -                      if (result_size != readlink(elem->path, result, len)) {
 +                      struct strbuf buf = STRBUF_INIT;
 +
 +                      if (strbuf_readlink(&buf, elem->path, st.st_size) < 0) {
                                error("readlink(%s): %s", elem->path,
                                      strerror(errno));
                                return;
                        }
 -                      result[len] = 0;
 +                      result_size = buf.len;
 +                      result = strbuf_detach(&buf, NULL);
                        elem->mode = canon_mode(st.st_mode);
-               }
-               else if (0 <= (fd = open(elem->path, O_RDONLY)) &&
-                        !fstat(fd, &st)) {
+               } else if (S_ISDIR(st.st_mode)) {
+                       unsigned char sha1[20];
+                       if (resolve_gitlink_ref(elem->path, "HEAD", sha1) < 0)
+                               result = grab_blob(elem->sha1, elem->mode, &result_size);
+                       else
+                               result = grab_blob(sha1, elem->mode, &result_size);
+               } else if (0 <= (fd = open(elem->path, O_RDONLY))) {
                        size_t len = xsize_t(st.st_size);
                        ssize_t done;
                        int is_file, i;
  
                        /* If not a fake symlink, apply filters, e.g. autocrlf */
                        if (is_file) {
 -                              struct strbuf buf;
 +                              struct strbuf buf = STRBUF_INIT;
  
 -                              strbuf_init(&buf, 0);
                                if (convert_to_git(elem->path, result, len, &buf, safe_crlf)) {
                                        free(result);
                                        result = strbuf_detach(&buf, &len);
                        }
                }
                if (i <= j)
-                       combine_diff(elem->parent[i].sha1, &result_file, sline,
+                       combine_diff(elem->parent[i].sha1,
+                                    elem->parent[i].mode,
+                                    &result_file, sline,
                                     cnt, i, num_parent);
                if (elem->parent[i].mode != elem->mode)
                        mode_differs = 1;
                        dump_quoted_path("--- ", "", "/dev/null",
                                         c_meta, c_reset);
                else
 -                      dump_quoted_path("--- ", opt->a_prefix, elem->path,
 +                      dump_quoted_path("--- ", a_prefix, elem->path,
                                         c_meta, c_reset);
                if (deleted)
                        dump_quoted_path("+++ ", "", "/dev/null",
                                         c_meta, c_reset);
                else
 -                      dump_quoted_path("+++ ", opt->b_prefix, elem->path,
 +                      dump_quoted_path("+++ ", b_prefix, elem->path,
                                         c_meta, c_reset);
                dump_sline(sline, cnt, num_parent,
                           DIFF_OPT_TST(opt, COLOR_DIFF));
index 1c2edebb09bd6e1d7581365011c8500da57942c5,718efe807799b042d507969d5265e6ebb5338721..5cf8924b2163ec55328ce270911a23cdcf52634a
@@@ -3,7 -3,7 +3,7 @@@
  test_description='difference in submodules'
  
  . ./test-lib.sh
 -. ../diff-lib.sh
 +. "$TEST_DIRECTORY"/diff-lib.sh
  
  _z40=0000000000000000000000000000000000000000
  test_expect_success setup '
@@@ -57,4 -57,43 +57,43 @@@ test_expect_success 'git diff (empty su
        test_cmp empty actual.empty
  '
  
+ test_expect_success 'conflicted submodule setup' '
+       # 39 efs
+       c=fffffffffffffffffffffffffffffffffffffff
+       (
+               echo "000000 $_z40 0    sub"
+               echo "160000 1$c 1      sub"
+               echo "160000 2$c 2      sub"
+               echo "160000 3$c 3      sub"
+       ) | git update-index --index-info &&
+       echo >expect.nosub '\''diff --cc sub
+ index 2ffffff,3ffffff..0000000
+ --- a/sub
+ +++ b/sub
+ @@@ -1,1 -1,1 +1,1 @@@
+ - Subproject commit 2fffffffffffffffffffffffffffffffffffffff
+  -Subproject commit 3fffffffffffffffffffffffffffffffffffffff
+ ++Subproject commit 0000000000000000000000000000000000000000'\'' &&
+       hh=$(git rev-parse HEAD) &&
+       sed -e "s/$_z40/$hh/" expect.nosub >expect.withsub
+ '
+ test_expect_success 'combined (empty submodule)' '
+       rm -fr sub && mkdir sub &&
+       git diff >actual &&
+       test_cmp expect.nosub actual
+ '
+ test_expect_success 'combined (with submodule)' '
+       rm -fr sub &&
+       git clone --no-checkout . sub &&
+       git diff >actual &&
+       test_cmp expect.withsub actual
+ '
  test_done