threads / patch / 16291

patch, 4 partsgit-remote rename: support remotes->config migration

Subject: [PATCH 2/4] git-remote rename: support remotes->config migration

## tl;dr

5 messages between Nov 12, 2008 and Nov 12, 2008. Diffs are folded; open one to read it.

replies: 4people: 1as markdown or json

Miklos Vajna· Nov 12, 2008, 17:11 UTC · lore

[PATCH v2 0/4] git-remote rename: support branches->config migration

On Tue, Nov 11, 2008 at 08:22:38PM -0800, Junio C Hamano <gitster@pobox.com> wrote:
Show 13 quoted lines
> The function migrate_file() introduced by [2/4] is called for any
> remote definition that did not come from config (by definition, it
> either came from remotes/foo or branches/foo).  The function adds the
> entries for the given remote definition to the config file, and then
> removes remotes/foo file if the remote definition came from it.  So it
> is a logically consistent change if you only called this function only
> for remote definitions that came from remotes/foo.
>
> But the function is called for a remote definition that originally
> came from branches/foo as well.  It happily adds the definition to the
> config, even though it *fails to remove* branches/foo file.
>
> Do you still think 2/4 is a logically contained good change?

OK, here is an updated series, which is supposed to fix this issue. 1/4 and 4/4 is unchanged.

Miklos Vajna (4):
  remote: add a new 'origin' variable to the struct
  git-remote rename: support remotes->config migration
  git-remote rename: support branches->config migration
  git-remote: document the migration feature of the rename subcommand
 Documentation/git-remote.txt |    4 ++++
 builtin-remote.c             |   37 +++++++++++++++++++++++++++++++++++++
 remote.c                     |    3 +++
 remote.h                     |    7 +++++++
 t/t5505-remote.sh            |   33 +++++++++++++++++++++++++++++++++
 5 files changed, 84 insertions(+), 0 deletions(-)
Miklos Vajna· Nov 12, 2008, 17:11 UTC · re: Miklos Vajna · lore

[PATCH 1/4] remote: add a new 'origin' variable to the struct

This allows one to track where was the remote's original source, so that it's possible to decide if it makes sense to migrate it to the config format or not.

Signed-off-by: Miklos Vajna <vmiklos@frugalware.org>
---
 remote.c |    3 +++
 remote.h |    7 +++++++
 2 files changed, 10 insertions(+), 0 deletions(-)
Show changes to 2 files +10 −0

remote.c, remote.h

diff --git a/remote.c b/remote.c
index e530a21..cbb3e48 100644
--- a/remote.c
+++ b/remote.c
@@ -201,6 +201,7 @@ static void read_remotes_file(struct remote *remote)
 
 	if (!f)
 		return;
+	remote->origin = REMOTE_REMOTES;
 	while (fgets(buffer, BUF_SIZE, f)) {
 		int value_list;
 		char *s, *p;
@@ -261,6 +262,7 @@ static void read_branches_file(struct remote *remote)
 		s++;
 	if (!*s)
 		return;
+	remote->origin = REMOTE_BRANCHES;
 	p = s + strlen(s);
 	while (isspace(p[-1]))
 		*--p = 0;
@@ -350,6 +352,7 @@ static int handle_config(const char *key, const char *value, void *cb)
 	if (!subkey)
 		return error("Config with no key for remote %s", name);
 	remote = make_remote(name, subkey - name);
+	remote->origin = REMOTE_CONFIG;
 	if (!strcmp(subkey, ".mirror"))
 		remote->mirror = git_config_bool(key, value);
 	else if (!strcmp(subkey, ".skipdefaultupdate"))
diff --git a/remote.h b/remote.h
index d2e170c..a46a5be 100644
--- a/remote.h
+++ b/remote.h
@@ -1,8 +1,15 @@
 #ifndef REMOTE_H
 #define REMOTE_H
 
+enum {
+	REMOTE_CONFIG,
+	REMOTE_REMOTES,
+	REMOTE_BRANCHES
+};
+
 struct remote {
 	const char *name;
+	int origin;
 
 	const char **url;
 	int url_nr;
-- 
1.6.0.2
Miklos Vajna· Nov 12, 2008, 17:11 UTC · re: Miklos Vajna · lore

This patch makes it possible to migrate a remote stored in a $GIT_DIR/remotes/nick file to the configuration file format.

Signed-off-by: Miklos Vajna <vmiklos@frugalware.org>
---
 builtin-remote.c  |   33 +++++++++++++++++++++++++++++++++
 t/t5505-remote.sh |   21 +++++++++++++++++++++
 2 files changed, 54 insertions(+), 0 deletions(-)
Show changes to 2 files +54 −0

builtin-remote.c, t/t5505-remote.sh

diff --git a/builtin-remote.c b/builtin-remote.c
index 1ca6cdb..4fa64a2 100644
--- a/builtin-remote.c
+++ b/builtin-remote.c
@@ -359,6 +359,36 @@ static int read_remote_branches(const char *refname,
 	return 0;
 }
 
+static int migrate_file(struct remote *remote)
+{
+	struct strbuf buf = STRBUF_INIT;
+	int i;
+	char *path = NULL;
+
+	strbuf_addf(&buf, "remote.%s.url", remote->name);
+	for (i = 0; i < remote->url_nr; i++)
+		if (git_config_set_multivar(buf.buf, remote->url[i], "^$", 0))
+			return error("Could not append '%s' to '%s'",
+					remote->url[i], buf.buf);
+	strbuf_reset(&buf);
+	strbuf_addf(&buf, "remote.%s.push", remote->name);
+	for (i = 0; i < remote->push_refspec_nr; i++)
+		if (git_config_set_multivar(buf.buf, remote->push_refspec[i], "^$", 0))
+			return error("Could not append '%s' to '%s'",
+					remote->push_refspec[i], buf.buf);
+	strbuf_reset(&buf);
+	strbuf_addf(&buf, "remote.%s.fetch", remote->name);
+	for (i = 0; i < remote->fetch_refspec_nr; i++)
+		if (git_config_set_multivar(buf.buf, remote->fetch_refspec[i], "^$", 0))
+			return error("Could not append '%s' to '%s'",
+					remote->fetch_refspec[i], buf.buf);
+	if (remote->origin == REMOTE_REMOTES)
+		path = git_path("remotes/%s", remote->name);
+	if (path && unlink(path))
+		warning("failed to remove '%s'", path);
+	return 0;
+}
+
 static int mv(int argc, const char **argv)
 {
 	struct option options[] = {
@@ -381,6 +411,9 @@ static int mv(int argc, const char **argv)
 	if (!oldremote)
 		die("No such remote: %s", rename.old);
 
+	if (!strcmp(rename.old, rename.new) && oldremote->origin == REMOTE_REMOTES)
+		return migrate_file(oldremote);
+
 	newremote = remote_get(rename.new);
 	if (newremote && (newremote->url_nr > 1 || newremote->fetch_refspec_nr))
 		die("remote %s already exists.", rename.new);
diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh
index 0c956ba..1567631 100755
--- a/t/t5505-remote.sh
+++ b/t/t5505-remote.sh
@@ -343,4 +343,25 @@ test_expect_success 'rename a remote' '
 	 test "$(git config branch.master.remote)" = "upstream")
 
 '
+
+cat > remotes_origin << EOF
+URL: $(pwd)/one
+Push: refs/heads/master:refs/heads/upstream
+Pull: refs/heads/master:refs/heads/origin
+EOF
+
+test_expect_success 'migrate a remote from named file in $GIT_DIR/remotes' '
+	git clone one five &&
+	origin_url=$(pwd)/one &&
+	(cd five &&
+	 git remote rm origin &&
+	 mkdir -p .git/remotes &&
+	 cat ../remotes_origin > .git/remotes/origin &&
+	 git remote rename origin origin &&
+	 ! test -f .git/remotes/origin &&
+	 test "$(git config remote.origin.url)" = "$origin_url" &&
+	 test "$(git config remote.origin.push)" = "refs/heads/master:refs/heads/upstream" &&
+	 test "$(git config remote.origin.fetch)" = "refs/heads/master:refs/heads/origin")
+'
+
 test_done
-- 
1.6.0.2
Miklos Vajna· Nov 12, 2008, 17:11 UTC · re: Miklos Vajna · lore

[PATCH 3/4] git-remote rename: support branches->config migration

This is similar to the remotes->config one, but it makes the branches->config conversion possible.

Signed-off-by: Miklos Vajna <vmiklos@frugalware.org>
---
 builtin-remote.c  |    6 +++++-
 t/t5505-remote.sh |   12 ++++++++++++
 2 files changed, 17 insertions(+), 1 deletions(-)
Show changes to 2 files +17 −1

builtin-remote.c, t/t5505-remote.sh

diff --git a/builtin-remote.c b/builtin-remote.c
index 4fa64a2..5b525c7 100644
--- a/builtin-remote.c
+++ b/builtin-remote.c
@@ -384,6 +384,8 @@ static int migrate_file(struct remote *remote)
 					remote->fetch_refspec[i], buf.buf);
 	if (remote->origin == REMOTE_REMOTES)
 		path = git_path("remotes/%s", remote->name);
+	else if (remote->origin == REMOTE_BRANCHES)
+		path = git_path("branches/%s", remote->name);
 	if (path && unlink(path))
 		warning("failed to remove '%s'", path);
 	return 0;
@@ -411,7 +413,9 @@ static int mv(int argc, const char **argv)
 	if (!oldremote)
 		die("No such remote: %s", rename.old);
 
-	if (!strcmp(rename.old, rename.new) && oldremote->origin == REMOTE_REMOTES)
+	if (!strcmp(rename.old, rename.new) &&
+			(oldremote->origin == REMOTE_REMOTES ||
+			 oldremote->origin == REMOTE_BRANCHES))
 		return migrate_file(oldremote);
 
 	newremote = remote_get(rename.new);
diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh
index 1567631..1f59960 100755
--- a/t/t5505-remote.sh
+++ b/t/t5505-remote.sh
@@ -364,4 +364,16 @@ test_expect_success 'migrate a remote from named file in $GIT_DIR/remotes' '
 	 test "$(git config remote.origin.fetch)" = "refs/heads/master:refs/heads/origin")
 '
 
+test_expect_success 'migrate a remote from named file in $GIT_DIR/branches' '
+	git clone one six &&
+	origin_url=$(pwd)/one &&
+	(cd six &&
+	 git remote rm origin &&
+	 echo "$origin_url" > .git/branches/origin &&
+	 git remote rename origin origin &&
+	 ! test -f .git/branches/origin &&
+	 test "$(git config remote.origin.url)" = "$origin_url" &&
+	 test "$(git config remote.origin.fetch)" = "refs/heads/master:refs/heads/origin")
+'
+
 test_done
-- 
1.6.0.2
Miklos Vajna· Nov 12, 2008, 17:11 UTC · re: Miklos Vajna · lore

[PATCH 4/4] git-remote: document the migration feature of the rename subcommand

Signed-off-by: Miklos Vajna <vmiklos@frugalware.org>
---
 Documentation/git-remote.txt |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)
Show changes to Documentation/git-remote.txt +4 −0
diff --git a/Documentation/git-remote.txt b/Documentation/git-remote.txt
index 7b227b3..fad983e 100644
--- a/Documentation/git-remote.txt
+++ b/Documentation/git-remote.txt
@@ -66,6 +66,10 @@ was passed.
 
 Rename the remote named <old> to <new>. All remote tracking branches and
 configuration settings for the remote are updated.
++
+In case <old> and <new> are the same, and <old> is a file under
+`$GIT_DIR/remotes` or `$GIT_DIR/branches`, the remote is converted to
+the configuration file format.
 
 'rm'::
 
-- 
1.6.0.2

← back to recent threads