git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Luke Diamand <luke@diamand.org>
To: git@vger.kernel.org
Cc: kartic Kaartic Sivaraam <kaartic.sivaraam@gmail.com>,
	Luke Diamand <luke@diamand.org>
Subject: [PATCH 1/1] Test case for checkout of added/deleted submodules in clones
Date: Mon, 21 Sep 2020 09:15:37 +0100	[thread overview]
Message-ID: <20200921081537.15300-2-luke@diamand.org> (raw)
In-Reply-To: <20200921081537.15300-1-luke@diamand.org>

Test case for various cases of deleted submodules:

1. Clone a repo where an `old` submodule has been removed in HEAD.
Try to checkout a revision from before `old` was deleted.

This can fail in a rather ugly way depending on how the `git checkout`
and `git submodule` commands are used.

2. Clone a repo where a `new` submodule has been added. Try to
checkout a revision from before `new` was added.

This can leave `new` lying around in some circumstances, and not in
others, in a way which is confusing (at least to me).

Signed-off-by: Luke Diamand <luke@diamand.org>
---
 t/t5619-submodules-missing.sh | 104 ++++++++++++++++++++++++++++++++++
 1 file changed, 104 insertions(+)
 create mode 100755 t/t5619-submodules-missing.sh

diff --git a/t/t5619-submodules-missing.sh b/t/t5619-submodules-missing.sh
new file mode 100755
index 0000000000..d7878c52fc
--- /dev/null
+++ b/t/t5619-submodules-missing.sh
@@ -0,0 +1,104 @@
+#!/bin/sh
+
+test_description='Clone a repo containing submodules. Sync to a revision where the submodule is missing or added'
+
+. ./test-lib.sh
+
+pwd=$(pwd)
+
+# Setup a super project with a submodule called `old`, which gets deleted, and
+# a submodule `new` which is added later on.
+
+test_expect_success 'setup' '
+	mkdir super old new &&
+	git -C old init &&
+	test_commit -C old commit_old &&
+	(cd super &&
+		git init . &&
+		git submodule add ../old old &&
+		git commit -m "adding submodule old" &&
+		test_commit commit2 &&
+		git tag OLD &&
+		test_path_is_file old/commit_old.t &&
+		git rm old &&
+		git commit -m "Remove old submodule" &&
+		test_commit commit3
+	) &&
+	git -C new init &&
+	test_commit -C new commit_new &&
+	(cd super &&
+		git tag BEFORE_NEW &&
+		git submodule add ../new new &&
+		git commit -m "adding submodule new" &&
+		test_commit commit4
+	)
+'
+
+# Checkout the OLD tag inside the original repo. This works fine since all of
+# the submodules are present in .git/modules.
+test_expect_success 'checkout old inside original repo' '
+	(cd super &&
+		git config advice.detachedHead false &&
+		git tag LATEST &&
+		git checkout --recurse-submodules OLD &&
+		git submodule update --checkout --remote --force &&
+		test_path_is_file old/commit_old.t &&
+		test_path_is_missing new/commit_new.t &&
+		git checkout --recurse-submodules LATEST &&
+		test_path_is_file new/commit_new.t
+	)
+'
+
+# Clone the repo, and then checkout the OLD tag inside the clone.
+# The `old` submodule does not get updated. Instead we get:
+#
+# fatal: not a git repository: ../.git/modules/old
+# fatal: could not reset submodule index
+#
+# That's because `old` is missing from .git/modules since it
+# was not cloned originally and `checkout` does not know how to
+# fetch the remote submodules, whereas `submodule update --remote` does.
+
+test_expect_failure 'checkout old with --recurse-submodules' '
+	test_when_finished "rm -fr super-clone" &&
+	git clone --recurse-submodules super super-clone &&
+	(cd super-clone &&
+		git config advice.detachedHead false &&
+		test_path_is_file commit3.t &&
+		test_path_is_file commit2.t &&
+		test_path_is_missing old &&
+		test_path_is_file new/commit_new.t &&
+		git checkout --recurse-submodules OLD &&
+		git submodule update --checkout --remote --force &&
+		test_path_is_file commit2.t &&
+		test_path_is_missing commit3.t &&
+		test_path_is_dir old &&
+		test_path_is_file old/commit_old.t
+	)
+'
+
+# As above, but this time, instead of using "checkout --recurse-submodules" we just
+# use "checkout" to avoid the missing submodule error.
+#
+# The checkout of `old` now works fine, but instead `new` is left lying
+# around with seemingly no way to clean it up. Even a later invocation of
+# `git checkout --recurse-submodules` does not get rid of it.
+
+test_expect_failure 'checkout old without --recurse-submodules' '
+	test_when_finished "rm -fr super-clone" &&
+	git clone --recurse-submodules super super-clone &&
+	(cd super-clone &&
+		git config advice.detachedHead false &&
+		test_path_is_file new/commit_new.t &&
+		git checkout OLD &&
+		git submodule update --checkout --remote --force &&
+		git checkout --recurse-submodules OLD &&
+		test_path_is_file commit2.t &&
+		test_path_is_missing commit3.t &&
+		test_path_is_dir old &&
+		test_path_is_file old/commit_old.t &&
+		test_path_is_missing new/commit_new.t
+	)
+'
+
+test_done
-- 
2.28.0.762.g324f61785e


  reply	other threads:[~2020-09-21  8:15 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-09-21  8:15 [PATCH 0/1] " Luke Diamand
2020-09-21  8:15 ` Luke Diamand [this message]
2020-09-22  9:35   ` [PATCH 1/1] " Kaartic Sivaraam
2020-09-22 14:04   ` Philippe Blain

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200921081537.15300-2-luke@diamand.org \
    --to=luke@diamand.org \
    --cc=git@vger.kernel.org \
    --cc=kaartic.sivaraam@gmail.com \
    --subject='Re: [PATCH 1/1] Test case for checkout of added/deleted submodules in clones' \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link

This is a public inbox, see mirroring instructions
on how to clone and mirror all data and code used for this inbox