Merge branch 'jc/fake-ancestor-with-non-blobs' into maint
authorJunio C Hamano <gitster@pobox.com>
Thu, 7 Feb 2013 23:14:22 +0000 (15:14 -0800)
committerJunio C Hamano <gitster@pobox.com>
Thu, 7 Feb 2013 23:14:22 +0000 (15:14 -0800)
Rebasing the history of superproject with change in the submodule
has been broken since v1.7.12.

* jc/fake-ancestor-with-non-blobs:
apply: diagnose incomplete submodule object name better
apply: simplify build_fake_ancestor()
git-am: record full index line in the patch used while rebasing

1  2 
builtin/apply.c
git-am.sh
diff --combined builtin/apply.c
index 6c11e8bc73892b15f91fcb65d65e18ee05956ec8,1f78e2cfab73c6600ae9414b04bb44444e1d2a64..9706ca73ab0bc2ee4c3cf7ce7ab39591830a1fab
@@@ -2095,7 -2095,7 +2095,7 @@@ static void update_pre_post_images(stru
                                   char *buf,
                                   size_t len, size_t postlen)
  {
 -      int i, ctx;
 +      int i, ctx, reduced;
        char *new, *old, *fixed;
        struct image fixed_preimage;
  
         * free "oldlines".
         */
        prepare_image(&fixed_preimage, buf, len, 1);
 -      assert(fixed_preimage.nr == preimage->nr);
 -      for (i = 0; i < preimage->nr; i++)
 +      assert(postlen
 +             ? fixed_preimage.nr == preimage->nr
 +             : fixed_preimage.nr <= preimage->nr);
 +      for (i = 0; i < fixed_preimage.nr; i++)
                fixed_preimage.line[i].flag = preimage->line[i].flag;
        free(preimage->line_allocated);
        *preimage = fixed_preimage;
        else
                new = old;
        fixed = preimage->buf;
 -      for (i = ctx = 0; i < postimage->nr; i++) {
 +
 +      for (i = reduced = ctx = 0; i < postimage->nr; i++) {
                size_t len = postimage->line[i].len;
                if (!(postimage->line[i].flag & LINE_COMMON)) {
                        /* an added line -- no counterparts in preimage */
                        fixed += preimage->line[ctx].len;
                        ctx++;
                }
 -              if (preimage->nr <= ctx)
 -                      die(_("oops"));
 +
 +              /*
 +               * preimage is expected to run out, if the caller
 +               * fixed addition of trailing blank lines.
 +               */
 +              if (preimage->nr <= ctx) {
 +                      reduced++;
 +                      continue;
 +              }
  
                /* and copy it in, while fixing the line length */
                len = preimage->line[ctx].len;
  
        /* Fix the length of the whole thing */
        postimage->len = new - postimage->buf;
 +      postimage->nr -= reduced;
  }
  
  static int match_fragment(struct image *img,
@@@ -3609,7 -3598,6 +3609,6 @@@ static void build_fake_ancestor(struct 
         * 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)
                        continue;
-               else if (get_sha1_blob(patch->old_sha1_prefix, sha1))
-                       /* git diff has no index line for mode/type changes */
-                       if (!patch->lines_added && !patch->lines_deleted) {
-                               if (get_current_sha1(patch->old_name, sha1))
-                                       die("mode change for %s, which is not "
-                                               "in current HEAD", name);
-                               sha1_ptr = sha1;
-                       } else
-                               die("sha1 information is lacking or useless "
-                                       "(%s).", name);
-               else
-                       sha1_ptr = sha1;
  
-               ce = make_cache_entry(patch->old_mode, sha1_ptr, name, 0, 0);
+               if (S_ISGITLINK(patch->old_mode)) {
+                       if (get_sha1_hex(patch->old_sha1_prefix, sha1))
+                               die("submoule change for %s without full index name",
+                                   name);
+               } else if (!get_sha1_blob(patch->old_sha1_prefix, sha1)) {
+                       ; /* ok */
+               } else if (!patch->lines_added && !patch->lines_deleted) {
+                       /* mode-only change: update the current */
+                       if (get_current_sha1(patch->old_name, sha1))
+                               die("mode change for %s, which is not "
+                                   "in current HEAD", name);
+               } else
+                       die("sha1 information is lacking or useless "
+                           "(%s).", name);
+               ce = make_cache_entry(patch->old_mode, sha1, name, 0, 0);
                if (!ce)
                        die(_("make_cache_entry failed for path '%s'"), name);
                if (add_index_entry(&result, ce, ADD_CACHE_OK_TO_ADD))
diff --combined git-am.sh
index b4d95f58c6f77e2b80a85be9b147351747926235,0e0a0966f4d2489cd944a12b9fe13db4958947d7..202130f888bee14e73b8cc108f39f2da8a14d23b
+++ b/git-am.sh
@@@ -334,7 -334,7 +334,7 @@@ split_patches () 
                        # Since we cannot guarantee that the commit message is in
                        # git-friendly format, we put no Subject: line and just consume
                        # all of the message as the body
 -                      perl -M'POSIX qw(strftime)' -ne 'BEGIN { $subject = 0 }
 +                      LANG=C LC_ALL=C perl -M'POSIX qw(strftime)' -ne 'BEGIN { $subject = 0 }
                                if ($subject) { print ; }
                                elsif (/^\# User /) { s/\# User/From:/ ; print ; }
                                elsif (/^\# Date /) {
@@@ -664,7 -664,7 +664,7 @@@ d
                        sed -e '1,/^$/d' >"$dotest/msg-clean"
                        echo "$commit" >"$dotest/original-commit"
                        get_author_ident_from_commit "$commit" >"$dotest/author-script"
-                       git diff-tree --root --binary "$commit" >"$dotest/patch"
+                       git diff-tree --root --binary --full-index "$commit" >"$dotest/patch"
                else
                        git mailinfo $keep $no_inbody_headers $scissors $utf8 "$dotest/msg" "$dotest/patch" \
                                <"$dotest/$msgnum" >"$dotest/info" ||