From: Peter Collingbourne <peter@pcc.me.uk>
To: git@vger.kernel.org
Cc: Peter Collingbourne <peter@pcc.me.uk>
Subject: [PATCH 02/12] Implement "git mv" for submodules
Date: Fri, 26 Mar 2010 15:25:30 +0000 [thread overview]
Message-ID: <1269617140-7827-3-git-send-email-peter@pcc.me.uk> (raw)
In-Reply-To: <1269617140-7827-1-git-send-email-peter@pcc.me.uk>
This patch teaches "git mv" how to handle moving submodules, including
how to update the .gitmodules file.
The .gitmodules update is handled by an undocumented subcommand to
"git submodule" named "mvconfig".
Signed-off-by: Peter Collingbourne <peter@pcc.me.uk>
---
Documentation/git-mv.txt | 7 ++-
builtin/mv.c | 33 ++++++++++++++--
git-submodule.sh | 16 +++++++-
t/t7409-submodule-mv.sh | 94 ++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 143 insertions(+), 7 deletions(-)
create mode 100755 t/t7409-submodule-mv.sh
diff --git a/Documentation/git-mv.txt b/Documentation/git-mv.txt
index bdcb585..632a6a9 100644
--- a/Documentation/git-mv.txt
+++ b/Documentation/git-mv.txt
@@ -14,8 +14,8 @@ DESCRIPTION
-----------
This script is used to move or rename a file, directory or symlink.
- git mv [-f] [-n] <source> <destination>
- git mv [-f] [-n] [-k] <source> ... <destination directory>
+ git mv [-f] [-n] [-M] <source> <destination>
+ git mv [-f] [-n] [-k] [-M] <source> ... <destination directory>
In the first form, it renames <source>, which must exist and be either
a file, symlink or directory, to <destination>.
@@ -39,6 +39,9 @@ OPTIONS
--dry-run::
Do nothing; only show what would happen
+-M::
+ Do not try to update submodule paths in .gitmodules
+
Author
------
diff --git a/builtin/mv.c b/builtin/mv.c
index c07f53b..21fd03f 100644
--- a/builtin/mv.c
+++ b/builtin/mv.c
@@ -9,6 +9,7 @@
#include "cache-tree.h"
#include "string-list.h"
#include "parse-options.h"
+#include "run-command.h"
static const char * const builtin_mv_usage[] = {
"git mv [options] <source>... <destination>",
@@ -53,11 +54,12 @@ static struct lock_file lock_file;
int cmd_mv(int argc, const char **argv, const char *prefix)
{
int i, newfd;
- int verbose = 0, show_only = 0, force = 0, ignore_errors = 0;
+ int verbose = 0, show_only = 0, force = 0, ignore_errors = 0, skip_module_update = 0;
struct option builtin_mv_options[] = {
OPT__DRY_RUN(&show_only),
OPT_BOOLEAN('f', "force", &force, "force move/rename even if target exists"),
OPT_BOOLEAN('k', NULL, &ignore_errors, "skip move/rename errors"),
+ OPT_BOOLEAN('M', NULL, &skip_module_update, "don't update submodule entries"),
OPT_END(),
};
const char **source, **destination, **dest_path;
@@ -96,13 +98,14 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
/* Checking */
for (i = 0; i < argc; i++) {
const char *src = source[i], *dst = destination[i];
- int length, src_is_dir;
+ int length, src_is_dir, pos;
const char *bad = NULL;
if (show_only)
printf("Checking rename of '%s' to '%s'\n", src, dst);
length = strlen(src);
+ pos = cache_name_pos(src, length);
if (lstat(src, &st) < 0)
bad = "bad source";
else if (!strncmp(src, dst, length) &&
@@ -111,7 +114,9 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
} else if ((src_is_dir = S_ISDIR(st.st_mode))
&& lstat(dst, &st) == 0)
bad = "cannot move directory over file";
- else if (src_is_dir) {
+ else if (src_is_dir &&
+ !(pos >= 0 &&
+ S_ISGITLINK(active_cache[pos]->ce_mode))) {
const char *src_w_slash = add_slash(src);
int len_w_slash = length + 1;
int first, last;
@@ -162,7 +167,7 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
}
argc += last - first;
}
- } else if (cache_name_pos(src, length) < 0)
+ } else if (pos < 0)
bad = "not under version control";
else if (lstat(dst, &st) == 0) {
bad = "destination exists";
@@ -223,5 +228,25 @@ int cmd_mv(int argc, const char **argv, const char *prefix)
die("Unable to write new index file");
}
+ if (!show_only && !skip_module_update)
+ for (i = 0; i < argc; i++) {
+ const char *src = source[i], *dst = destination[i];
+ int pos;
+
+ if (modes[i] == WORKING_DIRECTORY)
+ continue;
+
+ pos = cache_name_pos(dst, strlen(dst));
+ assert(pos >= 0);
+
+ if (S_ISGITLINK(active_cache[pos]->ce_mode)) {
+ const char *argv_submodule[] = {
+ "submodule", "mvconfig", src, dst, NULL
+ };
+
+ run_command_v_opt(argv_submodule, RUN_GIT_CMD);
+ }
+ }
+
return 0;
}
diff --git a/git-submodule.sh b/git-submodule.sh
index f05ff4e..d0b7a79 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -856,6 +856,20 @@ cmd_sync()
fi
done
}
+#
+# Updates the entry in .gitmodules to move a submodule.
+# This command is called by "git mv" for each submodule it moves.
+#
+cmd_mvconfig()
+{
+ src="$1"
+ dst="$2"
+
+ name=$(module_name "$src") || exit
+ git config -f .gitmodules submodule."$name".path "$dst" ||
+ die "Could not update .gitmodules entry for $name"
+ git add .gitmodules || die "Could not add .gitmodules to index"
+}
# This loop parses the command line arguments to find the
# subcommand name to dispatch. Parsing of the subcommand specific
@@ -866,7 +880,7 @@ cmd_sync()
while test $# != 0 && test -z "$command"
do
case "$1" in
- add | foreach | init | update | status | summary | sync)
+ add | foreach | init | update | status | summary | sync | mvconfig)
command=$1
;;
-q|--quiet)
diff --git a/t/t7409-submodule-mv.sh b/t/t7409-submodule-mv.sh
new file mode 100755
index 0000000..9eb3fb1
--- /dev/null
+++ b/t/t7409-submodule-mv.sh
@@ -0,0 +1,94 @@
+#!/bin/sh
+#
+# Copyright (c) 2010 Peter Collingbourne
+#
+
+test_description='git submodule mv
+
+These tests exercise the "git mv" command for submodules.
+'
+
+. ./test-lib.sh
+
+test_expect_success setup '
+ echo file > file &&
+ git add file &&
+ test_tick &&
+ git commit -m upstream
+ git clone . super &&
+ git clone super submodule &&
+ (cd super &&
+ git submodule add -n reg ../submodule reg &&
+ git clone reg unreg &&
+ git add unreg &&
+ test_tick &&
+ git commit -m "submodules"
+ )'
+
+test_expect_success 'move registered submodule' '
+ (cd super &&
+ git mv reg reg2 &&
+ test -z "$(git ls-files reg)" &&
+ test -n "$(git ls-files reg2)" &&
+ test ! -d reg &&
+ test -d reg2 &&
+ test -d reg2/.git &&
+ test "$(git config -f .gitmodules submodule.reg.path)" = "reg2" &&
+ test_tick &&
+ git commit -a -m "move reg"
+ )
+'
+
+test_expect_success 'move unregistered submodule' '
+ (cd super &&
+ git mv unreg unreg2 &&
+ test ! -d unreg &&
+ test -d unreg2 &&
+ test -d unreg2/.git &&
+ test_tick &&
+ git commit -a -m "move unreg"
+ )
+'
+
+test_expect_success 'move unregistered uninitialised submodule' '
+ (cd super &&
+ rm -rf unreg2 &&
+ mkdir unreg2 &&
+ git mv unreg2 unreg &&
+ test -z "$(git ls-files unreg2)" &&
+ test -n "$(git ls-files unreg)" &&
+ test ! -d unreg2 &&
+ test -d unreg &&
+ test_tick &&
+ git commit -a -m "move unreg2"
+ )
+'
+
+test_expect_success 'move registered submodule without changing .gitmodules' '
+ (cd super &&
+ git mv -M reg2 reg &&
+ test ! -d reg2 &&
+ test -d reg &&
+ test -d reg/.git &&
+ test "$(git config -f .gitmodules submodule.reg.path)" = "reg2" &&
+ git mv -M reg reg2
+ )
+'
+
+test_expect_success 'move multiple submodules at once' '
+ (cd super &&
+ mkdir test\ dir &&
+ git mv unreg reg2 test\ dir/ &&
+ test ! -d unreg &&
+ test ! -d reg2 &&
+ test -d test\ dir/unreg &&
+ test -d test\ dir/reg2 &&
+ test -z "$(git ls-files unreg)" &&
+ test -n "$(git ls-files test\ dir/unreg)" &&
+ test -z "$(git ls-files reg2)" &&
+ test -n "$(git ls-files test\ dir/reg2)" &&
+ test "$(git config -f .gitmodules submodule.reg.path)" = "test dir/reg2"
+ )
+'
+
+test_done
--
1.6.5
next prev parent reply other threads:[~2010-03-26 15:26 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-03-26 15:25 [PATCH 00/12] Improve handling of moving and removing submodules Peter Collingbourne
2010-03-26 15:25 ` [PATCH 01/12] Generate unique ID for submodules created using "git submodule add" Peter Collingbourne
2010-03-27 9:44 ` Jonathan Nieder
2010-04-03 20:04 ` Peter Collingbourne
2010-04-03 20:04 ` [PATCH 1/2] Prefix submodule names with the path basename Peter Collingbourne
2010-04-03 20:04 ` [PATCH 2/2] Truncate the SHA1 part of the submodule name to 7 characters Peter Collingbourne
2010-03-26 15:25 ` Peter Collingbourne [this message]
2010-03-26 15:25 ` [PATCH 03/12] git rm: display a warning for every unremovable file Peter Collingbourne
2010-03-27 11:01 ` Jonathan Nieder
2010-03-26 15:25 ` [PATCH 04/12] Generalise the unlink_or_warn function Peter Collingbourne
2010-03-26 15:25 ` [PATCH 05/12] Implement the rmdir_or_warn function Peter Collingbourne
2010-03-26 15:25 ` [PATCH 06/12] Introduce remove_or_warn function Peter Collingbourne
2010-03-26 15:25 ` [PATCH 07/12] Remove a redundant errno test in a usage of remove_path Peter Collingbourne
2010-03-26 15:25 ` [PATCH 08/12] git rm: collect file modes Peter Collingbourne
2010-03-26 15:25 ` [PATCH 09/12] Add a mode parameter to the remove_path function Peter Collingbourne
2010-03-26 15:25 ` [PATCH 10/12] git rm: do not abort due to an initialised submodule Peter Collingbourne
2010-03-26 15:25 ` [PATCH 11/12] git submodule: infrastructure for reading .gitmodules files in arbitrary locations Peter Collingbourne
2010-03-26 15:25 ` [PATCH 12/12] git rm: remove submodule entries from .gitmodules Peter Collingbourne
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=1269617140-7827-3-git-send-email-peter@pcc.me.uk \
--to=peter@pcc.me.uk \
--cc=git@vger.kernel.org \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).