All of lore.kernel.org
 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] Test case for checkout of added/deleted submodules in clones 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 \
    /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
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.