{"thread":{"id":"16291","subject":"[PATCH 2/4] git-remote rename: support remotes->config migration","startedAt":"2008-11-12T17:11:00Z","lastAt":"2008-11-12T17:11:04Z","messageCount":5,"participants":["Miklos Vajna"],"isPatch":true,"patchVersion":1,"patchTotal":4},"messages":[{"id":"95585","messageId":"cover.1226508805.git.vmiklos@frugalware.org","threadId":"16291","inReplyTo":"7viqqtshdd.fsf@gitster.siamese.dyndns.org","subject":"[PATCH v2 0/4] git-remote rename: support branches->config migration","fromName":"Miklos Vajna","fromEmail":"vmiklos@frugalware.org","sentAt":"2008-11-12T17:11:00Z","receivedAt":"2008-11-12T17:11:00Z","isPatch":true,"sender":{"key":"vmiklos@frugalware.org","avatar":"https://gravatar.com/avatar/401c1cbbb3a5d13e650c691a2c71d6fd0b80df1a01bc74d9f1972675dd58f2bd?d=mp&s=160"},"body":"On Tue, Nov 11, 2008 at 08:22:38PM -0800, Junio C Hamano <gitster@pobox.com> wrote:\n> The function migrate_file() introduced by [2/4] is called for any\n> remote definition that did not come from config (by definition, it\n> either came from remotes/foo or branches/foo).  The function adds the\n> entries for the given remote definition to the config file, and then\n> removes remotes/foo file if the remote definition came from it.  So it\n> is a logically consistent change if you only called this function only\n> for remote definitions that came from remotes/foo.\n>\n> But the function is called for a remote definition that originally\n> came from branches/foo as well.  It happily adds the definition to the\n> config, even though it *fails to remove* branches/foo file.\n>\n> Do you still think 2/4 is a logically contained good change?\n\nOK, here is an updated series, which is supposed to fix this issue. 1/4\nand 4/4 is unchanged.\n\nMiklos Vajna (4):\n  remote: add a new 'origin' variable to the struct\n  git-remote rename: support remotes->config migration\n  git-remote rename: support branches->config migration\n  git-remote: document the migration feature of the rename subcommand\n\n Documentation/git-remote.txt |    4 ++++\n builtin-remote.c             |   37 +++++++++++++++++++++++++++++++++++++\n remote.c                     |    3 +++\n remote.h                     |    7 +++++++\n t/t5505-remote.sh            |   33 +++++++++++++++++++++++++++++++++\n 5 files changed, 84 insertions(+), 0 deletions(-)\n"},{"id":"95586","messageId":"95e56b46e30b41af31da86789625c93511f1faef.1226508805.git.vmiklos@frugalware.org","threadId":"16291","inReplyTo":"cover.1226508805.git.vmiklos@frugalware.org","subject":"[PATCH 1/4] remote: add a new 'origin' variable to the struct","fromName":"Miklos Vajna","fromEmail":"vmiklos@frugalware.org","sentAt":"2008-11-12T17:11:01Z","receivedAt":"2008-11-12T17:11:01Z","isPatch":true,"sender":{"key":"vmiklos@frugalware.org","avatar":"https://gravatar.com/avatar/401c1cbbb3a5d13e650c691a2c71d6fd0b80df1a01bc74d9f1972675dd58f2bd?d=mp&s=160"},"body":"This allows one to track where was the remote's original source, so that\nit's possible to decide if it makes sense to migrate it to the config\nformat or not.\n\nSigned-off-by: Miklos Vajna <vmiklos@frugalware.org>\n---\n remote.c |    3 +++\n remote.h |    7 +++++++\n 2 files changed, 10 insertions(+), 0 deletions(-)\n\ndiff --git a/remote.c b/remote.c\nindex e530a21..cbb3e48 100644\n--- a/remote.c\n+++ b/remote.c\n@@ -201,6 +201,7 @@ static void read_remotes_file(struct remote *remote)\n \n \tif (!f)\n \t\treturn;\n+\tremote->origin = REMOTE_REMOTES;\n \twhile (fgets(buffer, BUF_SIZE, f)) {\n \t\tint value_list;\n \t\tchar *s, *p;\n@@ -261,6 +262,7 @@ static void read_branches_file(struct remote *remote)\n \t\ts++;\n \tif (!*s)\n \t\treturn;\n+\tremote->origin = REMOTE_BRANCHES;\n \tp = s + strlen(s);\n \twhile (isspace(p[-1]))\n \t\t*--p = 0;\n@@ -350,6 +352,7 @@ static int handle_config(const char *key, const char *value, void *cb)\n \tif (!subkey)\n \t\treturn error(\"Config with no key for remote %s\", name);\n \tremote = make_remote(name, subkey - name);\n+\tremote->origin = REMOTE_CONFIG;\n \tif (!strcmp(subkey, \".mirror\"))\n \t\tremote->mirror = git_config_bool(key, value);\n \telse if (!strcmp(subkey, \".skipdefaultupdate\"))\ndiff --git a/remote.h b/remote.h\nindex d2e170c..a46a5be 100644\n--- a/remote.h\n+++ b/remote.h\n@@ -1,8 +1,15 @@\n #ifndef REMOTE_H\n #define REMOTE_H\n \n+enum {\n+\tREMOTE_CONFIG,\n+\tREMOTE_REMOTES,\n+\tREMOTE_BRANCHES\n+};\n+\n struct remote {\n \tconst char *name;\n+\tint origin;\n \n \tconst char **url;\n \tint url_nr;\n-- \n1.6.0.2\n"},{"id":"95583","messageId":"d99804ad3579d4882e8241d9dcaee1b7dd6508af.1226508805.git.vmiklos@frugalware.org","threadId":"16291","inReplyTo":"95e56b46e30b41af31da86789625c93511f1faef.1226508805.git.vmiklos@frugalware.org","subject":"[PATCH 2/4] git-remote rename: support remotes->config migration","fromName":"Miklos Vajna","fromEmail":"vmiklos@frugalware.org","sentAt":"2008-11-12T17:11:02Z","receivedAt":"2008-11-12T17:11:02Z","isPatch":true,"sender":{"key":"vmiklos@frugalware.org","avatar":"https://gravatar.com/avatar/401c1cbbb3a5d13e650c691a2c71d6fd0b80df1a01bc74d9f1972675dd58f2bd?d=mp&s=160"},"body":"This patch makes it possible to migrate a remote stored in a\n$GIT_DIR/remotes/nick file to the configuration file format.\n\nSigned-off-by: Miklos Vajna <vmiklos@frugalware.org>\n---\n builtin-remote.c  |   33 +++++++++++++++++++++++++++++++++\n t/t5505-remote.sh |   21 +++++++++++++++++++++\n 2 files changed, 54 insertions(+), 0 deletions(-)\n\ndiff --git a/builtin-remote.c b/builtin-remote.c\nindex 1ca6cdb..4fa64a2 100644\n--- a/builtin-remote.c\n+++ b/builtin-remote.c\n@@ -359,6 +359,36 @@ static int read_remote_branches(const char *refname,\n \treturn 0;\n }\n \n+static int migrate_file(struct remote *remote)\n+{\n+\tstruct strbuf buf = STRBUF_INIT;\n+\tint i;\n+\tchar *path = NULL;\n+\n+\tstrbuf_addf(&buf, \"remote.%s.url\", remote->name);\n+\tfor (i = 0; i < remote->url_nr; i++)\n+\t\tif (git_config_set_multivar(buf.buf, remote->url[i], \"^$\", 0))\n+\t\t\treturn error(\"Could not append '%s' to '%s'\",\n+\t\t\t\t\tremote->url[i], buf.buf);\n+\tstrbuf_reset(&buf);\n+\tstrbuf_addf(&buf, \"remote.%s.push\", remote->name);\n+\tfor (i = 0; i < remote->push_refspec_nr; i++)\n+\t\tif (git_config_set_multivar(buf.buf, remote->push_refspec[i], \"^$\", 0))\n+\t\t\treturn error(\"Could not append '%s' to '%s'\",\n+\t\t\t\t\tremote->push_refspec[i], buf.buf);\n+\tstrbuf_reset(&buf);\n+\tstrbuf_addf(&buf, \"remote.%s.fetch\", remote->name);\n+\tfor (i = 0; i < remote->fetch_refspec_nr; i++)\n+\t\tif (git_config_set_multivar(buf.buf, remote->fetch_refspec[i], \"^$\", 0))\n+\t\t\treturn error(\"Could not append '%s' to '%s'\",\n+\t\t\t\t\tremote->fetch_refspec[i], buf.buf);\n+\tif (remote->origin == REMOTE_REMOTES)\n+\t\tpath = git_path(\"remotes/%s\", remote->name);\n+\tif (path && unlink(path))\n+\t\twarning(\"failed to remove '%s'\", path);\n+\treturn 0;\n+}\n+\n static int mv(int argc, const char **argv)\n {\n \tstruct option options[] = {\n@@ -381,6 +411,9 @@ static int mv(int argc, const char **argv)\n \tif (!oldremote)\n \t\tdie(\"No such remote: %s\", rename.old);\n \n+\tif (!strcmp(rename.old, rename.new) && oldremote->origin == REMOTE_REMOTES)\n+\t\treturn migrate_file(oldremote);\n+\n \tnewremote = remote_get(rename.new);\n \tif (newremote && (newremote->url_nr > 1 || newremote->fetch_refspec_nr))\n \t\tdie(\"remote %s already exists.\", rename.new);\ndiff --git a/t/t5505-remote.sh b/t/t5505-remote.sh\nindex 0c956ba..1567631 100755\n--- a/t/t5505-remote.sh\n+++ b/t/t5505-remote.sh\n@@ -343,4 +343,25 @@ test_expect_success 'rename a remote' '\n \t test \"$(git config branch.master.remote)\" = \"upstream\")\n \n '\n+\n+cat > remotes_origin << EOF\n+URL: $(pwd)/one\n+Push: refs/heads/master:refs/heads/upstream\n+Pull: refs/heads/master:refs/heads/origin\n+EOF\n+\n+test_expect_success 'migrate a remote from named file in $GIT_DIR/remotes' '\n+\tgit clone one five &&\n+\torigin_url=$(pwd)/one &&\n+\t(cd five &&\n+\t git remote rm origin &&\n+\t mkdir -p .git/remotes &&\n+\t cat ../remotes_origin > .git/remotes/origin &&\n+\t git remote rename origin origin &&\n+\t ! test -f .git/remotes/origin &&\n+\t test \"$(git config remote.origin.url)\" = \"$origin_url\" &&\n+\t test \"$(git config remote.origin.push)\" = \"refs/heads/master:refs/heads/upstream\" &&\n+\t test \"$(git config remote.origin.fetch)\" = \"refs/heads/master:refs/heads/origin\")\n+'\n+\n test_done\n-- \n1.6.0.2\n"},{"id":"95584","messageId":"c3744d00a3d612a637cf520d2719492265e4f061.1226508805.git.vmiklos@frugalware.org","threadId":"16291","inReplyTo":"d99804ad3579d4882e8241d9dcaee1b7dd6508af.1226508805.git.vmiklos@frugalware.org","subject":"[PATCH 3/4] git-remote rename: support branches->config migration","fromName":"Miklos Vajna","fromEmail":"vmiklos@frugalware.org","sentAt":"2008-11-12T17:11:03Z","receivedAt":"2008-11-12T17:11:03Z","isPatch":true,"sender":{"key":"vmiklos@frugalware.org","avatar":"https://gravatar.com/avatar/401c1cbbb3a5d13e650c691a2c71d6fd0b80df1a01bc74d9f1972675dd58f2bd?d=mp&s=160"},"body":"This is similar to the remotes->config one, but it makes the\nbranches->config conversion possible.\n\nSigned-off-by: Miklos Vajna <vmiklos@frugalware.org>\n---\n builtin-remote.c  |    6 +++++-\n t/t5505-remote.sh |   12 ++++++++++++\n 2 files changed, 17 insertions(+), 1 deletions(-)\n\ndiff --git a/builtin-remote.c b/builtin-remote.c\nindex 4fa64a2..5b525c7 100644\n--- a/builtin-remote.c\n+++ b/builtin-remote.c\n@@ -384,6 +384,8 @@ static int migrate_file(struct remote *remote)\n \t\t\t\t\tremote->fetch_refspec[i], buf.buf);\n \tif (remote->origin == REMOTE_REMOTES)\n \t\tpath = git_path(\"remotes/%s\", remote->name);\n+\telse if (remote->origin == REMOTE_BRANCHES)\n+\t\tpath = git_path(\"branches/%s\", remote->name);\n \tif (path && unlink(path))\n \t\twarning(\"failed to remove '%s'\", path);\n \treturn 0;\n@@ -411,7 +413,9 @@ static int mv(int argc, const char **argv)\n \tif (!oldremote)\n \t\tdie(\"No such remote: %s\", rename.old);\n \n-\tif (!strcmp(rename.old, rename.new) && oldremote->origin == REMOTE_REMOTES)\n+\tif (!strcmp(rename.old, rename.new) &&\n+\t\t\t(oldremote->origin == REMOTE_REMOTES ||\n+\t\t\t oldremote->origin == REMOTE_BRANCHES))\n \t\treturn migrate_file(oldremote);\n \n \tnewremote = remote_get(rename.new);\ndiff --git a/t/t5505-remote.sh b/t/t5505-remote.sh\nindex 1567631..1f59960 100755\n--- a/t/t5505-remote.sh\n+++ b/t/t5505-remote.sh\n@@ -364,4 +364,16 @@ test_expect_success 'migrate a remote from named file in $GIT_DIR/remotes' '\n \t test \"$(git config remote.origin.fetch)\" = \"refs/heads/master:refs/heads/origin\")\n '\n \n+test_expect_success 'migrate a remote from named file in $GIT_DIR/branches' '\n+\tgit clone one six &&\n+\torigin_url=$(pwd)/one &&\n+\t(cd six &&\n+\t git remote rm origin &&\n+\t echo \"$origin_url\" > .git/branches/origin &&\n+\t git remote rename origin origin &&\n+\t ! test -f .git/branches/origin &&\n+\t test \"$(git config remote.origin.url)\" = \"$origin_url\" &&\n+\t test \"$(git config remote.origin.fetch)\" = \"refs/heads/master:refs/heads/origin\")\n+'\n+\n test_done\n-- \n1.6.0.2\n"},{"id":"95587","messageId":"a8b13b05417ca3ecc360472c7c44e824402aa6e6.1226508805.git.vmiklos@frugalware.org","threadId":"16291","inReplyTo":"c3744d00a3d612a637cf520d2719492265e4f061.1226508805.git.vmiklos@frugalware.org","subject":"[PATCH 4/4] git-remote: document the migration feature of the rename subcommand","fromName":"Miklos Vajna","fromEmail":"vmiklos@frugalware.org","sentAt":"2008-11-12T17:11:04Z","receivedAt":"2008-11-12T17:11:04Z","isPatch":true,"sender":{"key":"vmiklos@frugalware.org","avatar":"https://gravatar.com/avatar/401c1cbbb3a5d13e650c691a2c71d6fd0b80df1a01bc74d9f1972675dd58f2bd?d=mp&s=160"},"body":"Signed-off-by: Miklos Vajna <vmiklos@frugalware.org>\n---\n Documentation/git-remote.txt |    4 ++++\n 1 files changed, 4 insertions(+), 0 deletions(-)\n\ndiff --git a/Documentation/git-remote.txt b/Documentation/git-remote.txt\nindex 7b227b3..fad983e 100644\n--- a/Documentation/git-remote.txt\n+++ b/Documentation/git-remote.txt\n@@ -66,6 +66,10 @@ was passed.\n \n Rename the remote named <old> to <new>. All remote tracking branches and\n configuration settings for the remote are updated.\n++\n+In case <old> and <new> are the same, and <old> is a file under\n+`$GIT_DIR/remotes` or `$GIT_DIR/branches`, the remote is converted to\n+the configuration file format.\n \n 'rm'::\n \n-- \n1.6.0.2\n"}]}