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

builtin/apply.c
git-am.sh
t/t7402-submodule-rebase.sh
index 6c11e8bc73892b15f91fcb65d65e18ee05956ec8..9706ca73ab0bc2ee4c3cf7ce7ab39591830a1fab 100644 (file)
@@ -3609,7 +3609,6 @@ static void build_fake_ancestor(struct patch *list, const char *filename)
         * 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;
@@ -3617,20 +3616,23 @@ static void build_fake_ancestor(struct patch *list, const char *filename)
                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))
index b4d95f58c6f77e2b80a85be9b147351747926235..202130f888bee14e73b8cc108f39f2da8a14d23b 100755 (executable)
--- a/git-am.sh
+++ b/git-am.sh
@@ -664,7 +664,7 @@ do
                        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" ||
index f919c8d34de41b2ec3fe08c217dd2c6276cf8472..8e32f190077474274dc5046df5a64f837ee696f3 100755 (executable)
@@ -3,7 +3,7 @@
 # Copyright (c) 2008 Johannes Schindelin
 #
 
-test_description='Test rebasing and stashing with dirty submodules'
+test_description='Test rebasing, stashing, etc. with submodules'
 
 . ./test-lib.sh
 
@@ -20,7 +20,8 @@ test_expect_success setup '
        echo second line >> file &&
        (cd submodule && git pull) &&
        test_tick &&
-       git commit -m file-and-submodule -a
+       git commit -m file-and-submodule -a &&
+       git branch added-submodule
 
 '
 
@@ -89,4 +90,29 @@ test_expect_success 'stash with a dirty submodule' '
 
 '
 
+test_expect_success 'rebasing submodule that should conflict' '
+       git reset --hard &&
+       git checkout added-submodule &&
+       git add submodule &&
+       test_tick &&
+       git commit -m third &&
+       (
+               cd submodule &&
+               git commit --allow-empty -m extra
+       ) &&
+       git add submodule &&
+       test_tick &&
+       git commit -m fourth &&
+
+       test_must_fail git rebase --onto HEAD^^ HEAD^ HEAD^0 &&
+       git ls-files -s submodule >actual &&
+       (
+               cd submodule &&
+               echo "160000 $(git rev-parse HEAD^) 1   submodule" &&
+               echo "160000 $(git rev-parse HEAD^^) 2  submodule" &&
+               echo "160000 $(git rev-parse HEAD) 3    submodule"
+       ) >expect &&
+       test_cmp expect actual
+'
+
 test_done