{"thread":{"id":"35320","subject":"[PATCH v6 10/10] transport-helper: add support to delete branches","startedAt":"2013-11-11T22:54:57Z","lastAt":"2014-04-24T03:55:55Z","messageCount":32,"participants":["Felipe Contreras","Junio C Hamano","Richard Hansen"],"isPatch":true,"patchVersion":6,"patchTotal":10},"messages":[{"id":"230443","messageId":"1384210507-26561-1-git-send-email-felipe.contreras@gmail.com","threadId":"35320","inReplyTo":null,"subject":"[PATCH v6 10/10] transport-helper: add support to delete branches","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-11-11T22:54:57Z","receivedAt":"2013-11-11T22:54:57Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"For remote-helpers that use 'export' to push.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n t/t5801-remote-helpers.sh |  8 ++++++++\n transport-helper.c        | 11 ++++++-----\n 2 files changed, 14 insertions(+), 5 deletions(-)\n\ndiff --git a/t/t5801-remote-helpers.sh b/t/t5801-remote-helpers.sh\nindex 454337e..c667965 100755\n--- a/t/t5801-remote-helpers.sh\n+++ b/t/t5801-remote-helpers.sh\n@@ -94,6 +94,14 @@ test_expect_success 'push new branch with old:new refspec' '\n \tcompare_refs local HEAD server refs/heads/new-refspec\n '\n \n+test_expect_success 'push delete branch' '\n+\t(cd local &&\n+\t git push origin :new-name\n+\t) &&\n+\ttest_must_fail git --git-dir=\"server/.git\" \\\n+\t rev-parse --verify refs/heads/new-name\n+'\n+\n test_expect_success 'forced push' '\n \t(cd local &&\n \tgit checkout -b force-test &&\ndiff --git a/transport-helper.c b/transport-helper.c\nindex 7411125..2257588 100644\n--- a/transport-helper.c\n+++ b/transport-helper.c\n@@ -876,9 +876,6 @@ static int push_refs_with_export(struct transport *transport,\n \t\tchar *private;\n \t\tunsigned char sha1[20];\n \n-\t\tif (ref->deletion)\n-\t\t\tdie(\"remote-helpers do not support ref deletion\");\n-\n \t\tprivate = apply_refspecs(data->refspecs, data->refspec_nr, ref->name);\n \t\tif (private && !get_sha1(private, sha1)) {\n \t\t\tstrbuf_addf(&buf, \"^%s\", private);\n@@ -890,12 +887,16 @@ static int push_refs_with_export(struct transport *transport,\n \t\tif (ref->peer_ref) {\n \t\t\tif (strcmp(ref->name, ref->peer_ref->name)) {\n \t\t\t\tstruct strbuf buf = STRBUF_INIT;\n-\t\t\t\tstrbuf_addf(&buf, \"%s:%s\", ref->peer_ref->name, ref->name);\n+\t\t\t\tif (!ref->deletion)\n+\t\t\t\t\tstrbuf_addf(&buf, \"%s:%s\", ref->peer_ref->name, ref->name);\n+\t\t\t\telse\n+\t\t\t\t\tstrbuf_addf(&buf, \":%s\", ref->name);\n \t\t\t\tstring_list_append(&revlist_args, \"--refspec\");\n \t\t\t\tstring_list_append(&revlist_args, buf.buf);\n \t\t\t\tstrbuf_release(&buf);\n \t\t\t}\n-\t\t\tstring_list_append(&revlist_args, ref->peer_ref->name);\n+\t\t\tif (!ref->deletion)\n+\t\t\t\tstring_list_append(&revlist_args, ref->peer_ref->name);\n \t\t}\n \t}\n \n-- \n1.8.4.2+fc1\n"},{"id":"230444","messageId":"1384210507-26561-2-git-send-email-felipe.contreras@gmail.com","threadId":"35320","inReplyTo":"1384210507-26561-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v6 00/10] transport-helper: updates","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-11-11T22:54:58Z","receivedAt":"2013-11-11T22:54:58Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Hi,\n\nHere are the patches that allow transport helpers to be completely transparent;\nrenaming branches, deleting them, custom refspecs, --force, --dry-run,\nreporting forced update, everything works.\n\nSmall changes since v5:\n\ndiff --git a/builtin/fast-export.c b/builtin/fast-export.c\nindex 8ed41b4..4b76222 100644\n--- a/builtin/fast-export.c\n+++ b/builtin/fast-export.c\n@@ -736,9 +736,10 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)\n \t\tusage_with_options (fast_export_usage, options);\n \n \tif (refspecs_list.nr) {\n-\t\tconst char *refspecs_str[refspecs_list.nr];\n+\t\tconst char **refspecs_str;\n \t\tint i;\n \n+\t\trefspecs_str = xmalloc(sizeof(*refspecs_str) * refspecs_list.nr);\n \t\tfor (i = 0; i < refspecs_list.nr; i++)\n \t\t\trefspecs_str[i] = refspecs_list.items[i].string;\n \n@@ -746,6 +747,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)\n \t\trefspecs = parse_fetch_refspec(refspecs_nr, refspecs_str);\n \n \t\tstring_list_clear(&refspecs_list, 1);\n+\t\tfree(refspecs_str);\n \t}\n \n \tif (use_done_feature)\ndiff --git a/git-remote-testgit.sh b/git-remote-testgit.sh\nindex 716aa4c..1c006a0 100755\n--- a/git-remote-testgit.sh\n+++ b/git-remote-testgit.sh\n@@ -15,6 +15,8 @@ test -z \"$refspec\" && prefix=\"refs\"\n \n export GIT_DIR=\"$url/.git\"\n \n+force=\n+\n mkdir -p \"$dir\"\n \n if test -z \"$GIT_REMOTE_TESTGIT_NO_MARKS\"\n\nFelipe Contreras (10):\n  transport-helper: fix extra lines\n  transport-helper: don't update refs in dry-run\n  transport-helper: add 'force' to 'export' helpers\n  transport-helper: check for 'forced update' message\n  fast-export: improve argument parsing\n  fast-export: add new --refspec option\n  transport-helper: add support for old:new refspec\n  fast-import: add support to delete refs\n  fast-export: add support to delete refs\n  transport-helper: add support to delete branches\n\n Documentation/git-fast-export.txt   |  4 +++\n Documentation/git-fast-import.txt   |  3 +++\n Documentation/gitremote-helpers.txt |  4 +++\n builtin/fast-export.c               | 49 ++++++++++++++++++++++++++++++++++++-\n fast-import.c                       | 13 +++++++---\n git-remote-testgit.sh               | 18 ++++++++++++++\n t/t5801-remote-helpers.sh           | 23 ++++++++++++++++-\n t/t9300-fast-import.sh              | 18 ++++++++++++++\n t/t9350-fast-export.sh              | 18 ++++++++++++++\n transport-helper.c                  | 47 +++++++++++++++++++++++------------\n 10 files changed, 177 insertions(+), 20 deletions(-)\n\n-- \n1.8.4.2+fc1\n"},{"id":"230445","messageId":"1384210507-26561-3-git-send-email-felipe.contreras@gmail.com","threadId":"35320","inReplyTo":"1384210507-26561-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v6 01/10] transport-helper: fix extra lines","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-11-11T22:54:59Z","receivedAt":"2013-11-11T22:54:59Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Commit 9c51558 (transport-helper: trivial code shuffle) moved these\nlines above, but 99d9ec0 (Merge branch 'fc/transport-helper-no-refspec')\nhad a wrong merge conflict and readded them.\n\nReported-by: Richard Hansen <rhansen@bbn.com>\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n transport-helper.c | 3 ---\n 1 file changed, 3 deletions(-)\n\ndiff --git a/transport-helper.c b/transport-helper.c\nindex 673b7c2..b66c7fd 100644\n--- a/transport-helper.c\n+++ b/transport-helper.c\n@@ -875,9 +875,6 @@ static int push_refs_with_export(struct transport *transport,\n \t\t}\n \t\tfree(private);\n \n-\t\tif (ref->deletion)\n-\t\t\tdie(\"remote-helpers do not support ref deletion\");\n-\n \t\tif (ref->peer_ref) {\n \t\t\tif (strcmp(ref->peer_ref->name, ref->name))\n \t\t\t\tdie(\"remote-helpers do not support old:new syntax\");\n-- \n1.8.4.2+fc1\n"},{"id":"230446","messageId":"1384210507-26561-4-git-send-email-felipe.contreras@gmail.com","threadId":"35320","inReplyTo":"1384210507-26561-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v6 08/10] fast-import: add support to delete refs","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-11-11T22:55:00Z","receivedAt":"2013-11-11T22:55:00Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n Documentation/git-fast-import.txt |  3 +++\n fast-import.c                     | 13 ++++++++++---\n t/t9300-fast-import.sh            | 18 ++++++++++++++++++\n 3 files changed, 31 insertions(+), 3 deletions(-)\n\ndiff --git a/Documentation/git-fast-import.txt b/Documentation/git-fast-import.txt\nindex 73f9806..2ffae42 100644\n--- a/Documentation/git-fast-import.txt\n+++ b/Documentation/git-fast-import.txt\n@@ -483,6 +483,9 @@ Marks must be declared (via `mark`) before they can be used.\n * Any valid Git SHA-1 expression that resolves to a commit.  See\n   ``SPECIFYING REVISIONS'' in linkgit:gitrevisions[7] for details.\n \n+* The special null SHA-1 (40 zeros) specifies that the branch is to be\n+  removed.\n+\n The special case of restarting an incremental import from the\n current branch value should be written as:\n ----\ndiff --git a/fast-import.c b/fast-import.c\nindex f4d9969..fdce0b7 100644\n--- a/fast-import.c\n+++ b/fast-import.c\n@@ -248,6 +248,7 @@ struct branch {\n \tuintmax_t last_commit;\n \tuintmax_t num_notes;\n \tunsigned active : 1;\n+\tunsigned delete : 1;\n \tunsigned pack_id : PACK_ID_BITS;\n \tunsigned char sha1[20];\n };\n@@ -1690,10 +1691,13 @@ static int update_branch(struct branch *b)\n \tstruct ref_lock *lock;\n \tunsigned char old_sha1[20];\n \n-\tif (is_null_sha1(b->sha1))\n-\t\treturn 0;\n \tif (read_ref(b->name, old_sha1))\n \t\thashclr(old_sha1);\n+\tif (is_null_sha1(b->sha1)) {\n+\t\tif (b->delete)\n+\t\t\tdelete_ref(b->name, old_sha1, 0);\n+\t\treturn 0;\n+\t}\n \tlock = lock_any_ref_for_update(b->name, old_sha1, 0, NULL);\n \tif (!lock)\n \t\treturn error(\"Unable to lock %s\", b->name);\n@@ -2620,8 +2624,11 @@ static int parse_from(struct branch *b)\n \t\t\tfree(buf);\n \t\t} else\n \t\t\tparse_from_existing(b);\n-\t} else if (!get_sha1(from, b->sha1))\n+\t} else if (!get_sha1(from, b->sha1)) {\n \t\tparse_from_existing(b);\n+\t\tif (is_null_sha1(b->sha1))\n+\t\t\tb->delete = 1;\n+\t}\n \telse\n \t\tdie(\"Invalid ref name or SHA1 expression: %s\", from);\n \ndiff --git a/t/t9300-fast-import.sh b/t/t9300-fast-import.sh\nindex 27263df..5fc9ef2 100755\n--- a/t/t9300-fast-import.sh\n+++ b/t/t9300-fast-import.sh\n@@ -2999,4 +2999,22 @@ test_expect_success 'T: ls root tree' '\n \ttest_cmp expect actual\n '\n \n+test_expect_success 'T: delete branch' '\n+\tgit branch to-delete &&\n+\tgit fast-import <<-EOF &&\n+\treset refs/heads/to-delete\n+\tfrom 0000000000000000000000000000000000000000\n+\tEOF\n+\ttest_must_fail git rev-parse --verify refs/heads/to-delete\n+'\n+\n+test_expect_success 'T: empty reset doesnt delete branch' '\n+\tgit branch not-to-delete &&\n+\tgit fast-import <<-EOF &&\n+\treset refs/heads/not-to-delete\n+\tEOF\n+\tgit show-ref &&\n+\tgit rev-parse --verify refs/heads/not-to-delete\n+'\n+\n test_done\n-- \n1.8.4.2+fc1\n"},{"id":"230447","messageId":"1384210507-26561-5-git-send-email-felipe.contreras@gmail.com","threadId":"35320","inReplyTo":"1384210507-26561-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v6 05/10] fast-export: improve argument parsing","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-11-11T22:55:01Z","receivedAt":"2013-11-11T22:55:01Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"We don't want to pass arguments specific to fast-export to\nsetup_revisions.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n builtin/fast-export.c | 3 ++-\n 1 file changed, 2 insertions(+), 1 deletion(-)\n\ndiff --git a/builtin/fast-export.c b/builtin/fast-export.c\nindex 78250ea..eea5b8c 100644\n--- a/builtin/fast-export.c\n+++ b/builtin/fast-export.c\n@@ -701,8 +701,9 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)\n \trevs.topo_order = 1;\n \trevs.show_source = 1;\n \trevs.rewrite_parents = 1;\n+\targc = parse_options(argc, argv, prefix, options, fast_export_usage,\n+\t\t\tPARSE_OPT_KEEP_ARGV0 | PARSE_OPT_KEEP_UNKNOWN);\n \targc = setup_revisions(argc, argv, &revs, NULL);\n-\targc = parse_options(argc, argv, prefix, options, fast_export_usage, 0);\n \tif (argc > 1)\n \t\tusage_with_options (fast_export_usage, options);\n \n-- \n1.8.4.2+fc1\n"},{"id":"230448","messageId":"1384210507-26561-6-git-send-email-felipe.contreras@gmail.com","threadId":"35320","inReplyTo":"1384210507-26561-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v6 06/10] fast-export: add new --refspec option","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-11-11T22:55:02Z","receivedAt":"2013-11-11T22:55:02Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"So that we can convert the exported ref names.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n Documentation/git-fast-export.txt |  4 ++++\n builtin/fast-export.c             | 32 ++++++++++++++++++++++++++++++++\n t/t9350-fast-export.sh            |  7 +++++++\n 3 files changed, 43 insertions(+)\n\ndiff --git a/Documentation/git-fast-export.txt b/Documentation/git-fast-export.txt\nindex 85f1f30..221506b 100644\n--- a/Documentation/git-fast-export.txt\n+++ b/Documentation/git-fast-export.txt\n@@ -105,6 +105,10 @@ marks the same across runs.\n \tin the commit (as opposed to just listing the files which are\n \tdifferent from the commit's first parent).\n \n+--refspec::\n+\tApply the specified refspec to each ref exported. Multiple of them can\n+\tbe specified.\n+\n [<git-rev-list-args>...]::\n \tA list of arguments, acceptable to 'git rev-parse' and\n \t'git rev-list', that specifies the specific objects and references\ndiff --git a/builtin/fast-export.c b/builtin/fast-export.c\nindex eea5b8c..cf745ec 100644\n--- a/builtin/fast-export.c\n+++ b/builtin/fast-export.c\n@@ -17,6 +17,7 @@\n #include \"utf8.h\"\n #include \"parse-options.h\"\n #include \"quote.h\"\n+#include \"remote.h\"\n \n static const char *fast_export_usage[] = {\n \tN_(\"git fast-export [rev-list-opts]\"),\n@@ -31,6 +32,8 @@ static int use_done_feature;\n static int no_data;\n static int full_tree;\n static struct string_list extra_refs = STRING_LIST_INIT_NODUP;\n+static struct refspec *refspecs;\n+static int refspecs_nr;\n \n static int parse_opt_signed_tag_mode(const struct option *opt,\n \t\t\t\t     const char *arg, int unset)\n@@ -525,6 +528,15 @@ static void get_tags_and_duplicates(struct rev_cmdline_info *info)\n \t\tif (dwim_ref(e->name, strlen(e->name), sha1, &full_name) != 1)\n \t\t\tcontinue;\n \n+\t\tif (refspecs) {\n+\t\t\tchar *private;\n+\t\t\tprivate = apply_refspecs(refspecs, refspecs_nr, full_name);\n+\t\t\tif (private) {\n+\t\t\t\tfree(full_name);\n+\t\t\t\tfull_name = private;\n+\t\t\t}\n+\t\t}\n+\n \t\tcommit = get_commit(e, full_name);\n \t\tif (!commit) {\n \t\t\twarning(\"%s: Unexpected object of type %s, skipping.\",\n@@ -668,6 +680,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)\n \tstruct commit *commit;\n \tchar *export_filename = NULL, *import_filename = NULL;\n \tuint32_t lastimportid;\n+\tstruct string_list refspecs_list = STRING_LIST_INIT_NODUP;\n \tstruct option options[] = {\n \t\tOPT_INTEGER(0, \"progress\", &progress,\n \t\t\t    N_(\"show progress after <n> objects\")),\n@@ -688,6 +701,8 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)\n \t\tOPT_BOOL(0, \"use-done-feature\", &use_done_feature,\n \t\t\t     N_(\"Use the done feature to terminate the stream\")),\n \t\tOPT_BOOL(0, \"no-data\", &no_data, N_(\"Skip output of blob data\")),\n+\t\tOPT_STRING_LIST(0, \"refspec\", &refspecs_list, N_(\"refspec\"),\n+\t\t\t     N_(\"Apply refspec to exported refs\")),\n \t\tOPT_END()\n \t};\n \n@@ -707,6 +722,21 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)\n \tif (argc > 1)\n \t\tusage_with_options (fast_export_usage, options);\n \n+\tif (refspecs_list.nr) {\n+\t\tconst char **refspecs_str;\n+\t\tint i;\n+\n+\t\trefspecs_str = xmalloc(sizeof(*refspecs_str) * refspecs_list.nr);\n+\t\tfor (i = 0; i < refspecs_list.nr; i++)\n+\t\t\trefspecs_str[i] = refspecs_list.items[i].string;\n+\n+\t\trefspecs_nr = refspecs_list.nr;\n+\t\trefspecs = parse_fetch_refspec(refspecs_nr, refspecs_str);\n+\n+\t\tstring_list_clear(&refspecs_list, 1);\n+\t\tfree(refspecs_str);\n+\t}\n+\n \tif (use_done_feature)\n \t\tprintf(\"feature done\\n\");\n \n@@ -741,5 +771,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)\n \tif (use_done_feature)\n \t\tprintf(\"done\\n\");\n \n+\tfree_refspec(refspecs_nr, refspecs);\n+\n \treturn 0;\n }\ndiff --git a/t/t9350-fast-export.sh b/t/t9350-fast-export.sh\nindex 2312dec..3d475af 100755\n--- a/t/t9350-fast-export.sh\n+++ b/t/t9350-fast-export.sh\n@@ -504,4 +504,11 @@ test_expect_success 'refs are updated even if no commits need to be exported' '\n \ttest_cmp expected actual\n '\n \n+test_expect_success 'use refspec' '\n+\tgit fast-export --refspec refs/heads/master:refs/heads/foobar master | \\\n+\t\tgrep \"^commit \" | sort | uniq > actual &&\n+\techo \"commit refs/heads/foobar\" > expected &&\n+\ttest_cmp expected actual\n+'\n+\n test_done\n-- \n1.8.4.2+fc1\n"},{"id":"230449","messageId":"1384210507-26561-7-git-send-email-felipe.contreras@gmail.com","threadId":"35320","inReplyTo":"1384210507-26561-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v6 03/10] transport-helper: add 'force' to 'export' helpers","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-11-11T22:55:03Z","receivedAt":"2013-11-11T22:55:03Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Otherwise they cannot know when to force the push or not (other than\nhacks).\n\nTests-by: Richard Hansen <rhansen@bbn.com>\nDocumentation-by: Richard Hansen <rhansen@bbn.com>\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n Documentation/gitremote-helpers.txt |  4 ++++\n git-remote-testgit.sh               | 18 ++++++++++++++++++\n t/t5801-remote-helpers.sh           | 13 +++++++++++++\n transport-helper.c                  |  5 +++++\n 4 files changed, 40 insertions(+)\n\ndiff --git a/Documentation/gitremote-helpers.txt b/Documentation/gitremote-helpers.txt\nindex f1f4ca9..e75699c 100644\n--- a/Documentation/gitremote-helpers.txt\n+++ b/Documentation/gitremote-helpers.txt\n@@ -437,6 +437,10 @@ set by Git if the remote helper has the 'option' capability.\n 'option check-connectivity' \\{'true'|'false'\\}::\n \tRequest the helper to check connectivity of a clone.\n \n+'option force' \\{'true'|'false'\\}::\n+\tRequest the helper to perform a force update.  Defaults to\n+\t'false'.\n+\n SEE ALSO\n --------\n linkgit:git-remote[1]\ndiff --git a/git-remote-testgit.sh b/git-remote-testgit.sh\nindex 6d2f282..1c006a0 100755\n--- a/git-remote-testgit.sh\n+++ b/git-remote-testgit.sh\n@@ -15,6 +15,8 @@ test -z \"$refspec\" && prefix=\"refs\"\n \n export GIT_DIR=\"$url/.git\"\n \n+force=\n+\n mkdir -p \"$dir\"\n \n if test -z \"$GIT_REMOTE_TESTGIT_NO_MARKS\"\n@@ -39,6 +41,7 @@ do\n \t\tfi\n \t\ttest -n \"$GIT_REMOTE_TESTGIT_SIGNED_TAGS\" && echo \"signed-tags\"\n \t\ttest -n \"$GIT_REMOTE_TESTGIT_NO_PRIVATE_UPDATE\" && echo \"no-private-update\"\n+\t\techo 'option'\n \t\techo\n \t\t;;\n \tlist)\n@@ -93,6 +96,7 @@ do\n \t\tbefore=$(git for-each-ref --format=' %(refname) %(objectname) ')\n \n \t\tgit fast-import \\\n+\t\t\t${force:+--force} \\\n \t\t\t${testgitmarks:+\"--import-marks=$testgitmarks\"} \\\n \t\t\t${testgitmarks:+\"--export-marks=$testgitmarks\"} \\\n \t\t\t--quiet\n@@ -115,6 +119,20 @@ do\n \n \t\techo\n \t\t;;\n+\toption\\ *)\n+\t\tread cmd opt val <<-EOF\n+\t\t$line\n+\t\tEOF\n+\t\tcase $opt in\n+\t\tforce)\n+\t\t\ttest $val = \"true\" && force=\"true\" || force=\n+\t\t\techo \"ok\"\n+\t\t\t;;\n+\t\t*)\n+\t\t\techo \"unsupported\"\n+\t\t\t;;\n+\t\tesac\n+\t\t;;\n \t'')\n \t\texit\n \t\t;;\ndiff --git a/t/t5801-remote-helpers.sh b/t/t5801-remote-helpers.sh\nindex 613f69a..c33cc25 100755\n--- a/t/t5801-remote-helpers.sh\n+++ b/t/t5801-remote-helpers.sh\n@@ -94,6 +94,19 @@ test_expect_failure 'push new branch with old:new refspec' '\n \tcompare_refs local HEAD server refs/heads/new-refspec\n '\n \n+test_expect_success 'forced push' '\n+\t(cd local &&\n+\tgit checkout -b force-test &&\n+\techo content >> file &&\n+\tgit commit -a -m eight &&\n+\tgit push origin force-test &&\n+\techo content >> file &&\n+\tgit commit -a --amend -m eight-modified &&\n+\tgit push --force origin force-test\n+\t) &&\n+\tcompare_refs local refs/heads/force-test server refs/heads/force-test\n+'\n+\n test_expect_success 'cloning without refspec' '\n \tGIT_REMOTE_TESTGIT_REFSPEC=\"\" \\\n \tgit clone \"testgit::${PWD}/server\" local2 2>error &&\ndiff --git a/transport-helper.c b/transport-helper.c\nindex 9558a0d..bead9b9 100644\n--- a/transport-helper.c\n+++ b/transport-helper.c\n@@ -855,6 +855,11 @@ static int push_refs_with_export(struct transport *transport,\n \t\t\tdie(\"helper %s does not support dry-run\", data->name);\n \t}\n \n+\tif (flags & TRANSPORT_PUSH_FORCE) {\n+\t\tif (set_helper_option(transport, \"force\", \"true\") != 0)\n+\t\t\tdie(\"helper %s does not support 'force'\", data->name);\n+\t}\n+\n \thelper = get_helper(transport);\n \n \twrite_constant(helper->in, \"export\\n\");\n-- \n1.8.4.2+fc1\n"},{"id":"230450","messageId":"1384210507-26561-8-git-send-email-felipe.contreras@gmail.com","threadId":"35320","inReplyTo":"1384210507-26561-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v6 09/10] fast-export: add support to delete refs","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-11-11T22:55:04Z","receivedAt":"2013-11-11T22:55:04Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n builtin/fast-export.c  | 14 ++++++++++++++\n t/t9350-fast-export.sh | 11 +++++++++++\n 2 files changed, 25 insertions(+)\n\ndiff --git a/builtin/fast-export.c b/builtin/fast-export.c\nindex cf745ec..4b76222 100644\n--- a/builtin/fast-export.c\n+++ b/builtin/fast-export.c\n@@ -673,6 +673,19 @@ static void import_marks(char *input_file)\n \tfclose(f);\n }\n \n+static void handle_deletes(void)\n+{\n+\tint i;\n+\tfor (i = 0; i < refspecs_nr; i++) {\n+\t\tstruct refspec *refspec = &refspecs[i];\n+\t\tif (*refspec->src)\n+\t\t\tcontinue;\n+\n+\t\tprintf(\"reset %s\\nfrom %s\\n\\n\",\n+\t\t\t\trefspec->dst, sha1_to_hex(null_sha1));\n+\t}\n+}\n+\n int cmd_fast_export(int argc, const char **argv, const char *prefix)\n {\n \tstruct rev_info revs;\n@@ -764,6 +777,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)\n \t}\n \n \thandle_tags_and_duplicates();\n+\thandle_deletes();\n \n \tif (export_filename && lastimportid != last_idnum)\n \t\texport_marks(export_filename);\ndiff --git a/t/t9350-fast-export.sh b/t/t9350-fast-export.sh\nindex 3d475af..66c8b0a 100755\n--- a/t/t9350-fast-export.sh\n+++ b/t/t9350-fast-export.sh\n@@ -511,4 +511,15 @@ test_expect_success 'use refspec' '\n \ttest_cmp expected actual\n '\n \n+test_expect_success 'delete refspec' '\n+\tgit branch to-delete &&\n+\tgit fast-export --refspec :refs/heads/to-delete to-delete ^to-delete > actual &&\n+\tcat > expected <<-EOF &&\n+\treset refs/heads/to-delete\n+\tfrom 0000000000000000000000000000000000000000\n+\n+\tEOF\n+\ttest_cmp expected actual\n+'\n+\n test_done\n-- \n1.8.4.2+fc1\n"},{"id":"230451","messageId":"1384210507-26561-9-git-send-email-felipe.contreras@gmail.com","threadId":"35320","inReplyTo":"1384210507-26561-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v6 07/10] transport-helper: add support for old:new refspec","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-11-11T22:55:05Z","receivedAt":"2013-11-11T22:55:05Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"By using fast-export's new --refspec option.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n t/t5801-remote-helpers.sh |  2 +-\n transport-helper.c        | 13 ++++++++++---\n 2 files changed, 11 insertions(+), 4 deletions(-)\n\ndiff --git a/t/t5801-remote-helpers.sh b/t/t5801-remote-helpers.sh\nindex c33cc25..454337e 100755\n--- a/t/t5801-remote-helpers.sh\n+++ b/t/t5801-remote-helpers.sh\n@@ -87,7 +87,7 @@ test_expect_success 'push new branch by name' '\n \tcompare_refs local HEAD server refs/heads/new-name\n '\n \n-test_expect_failure 'push new branch with old:new refspec' '\n+test_expect_success 'push new branch with old:new refspec' '\n \t(cd local &&\n \t git push origin new-name:new-refspec\n \t) &&\ndiff --git a/transport-helper.c b/transport-helper.c\nindex 9a5814d..7411125 100644\n--- a/transport-helper.c\n+++ b/transport-helper.c\n@@ -850,7 +850,7 @@ static int push_refs_with_export(struct transport *transport,\n \tstruct ref *ref;\n \tstruct child_process *helper, exporter;\n \tstruct helper_data *data = transport->data;\n-\tstruct string_list revlist_args = STRING_LIST_INIT_NODUP;\n+\tstruct string_list revlist_args = STRING_LIST_INIT_DUP;\n \tstruct strbuf buf = STRBUF_INIT;\n \n \tif (!data->refspecs)\n@@ -888,8 +888,13 @@ static int push_refs_with_export(struct transport *transport,\n \t\tfree(private);\n \n \t\tif (ref->peer_ref) {\n-\t\t\tif (strcmp(ref->peer_ref->name, ref->name))\n-\t\t\t\tdie(\"remote-helpers do not support old:new syntax\");\n+\t\t\tif (strcmp(ref->name, ref->peer_ref->name)) {\n+\t\t\t\tstruct strbuf buf = STRBUF_INIT;\n+\t\t\t\tstrbuf_addf(&buf, \"%s:%s\", ref->peer_ref->name, ref->name);\n+\t\t\t\tstring_list_append(&revlist_args, \"--refspec\");\n+\t\t\t\tstring_list_append(&revlist_args, buf.buf);\n+\t\t\t\tstrbuf_release(&buf);\n+\t\t\t}\n \t\t\tstring_list_append(&revlist_args, ref->peer_ref->name);\n \t\t}\n \t}\n@@ -897,6 +902,8 @@ static int push_refs_with_export(struct transport *transport,\n \tif (get_exporter(transport, &exporter, &revlist_args))\n \t\tdie(\"Couldn't run fast-export\");\n \n+\tstring_list_clear(&revlist_args, 1);\n+\n \tif (finish_command(&exporter))\n \t\tdie(\"Error while running fast-export\");\n \tpush_update_refs_status(data, remote_refs, flags);\n-- \n1.8.4.2+fc1\n"},{"id":"230452","messageId":"1384210507-26561-10-git-send-email-felipe.contreras@gmail.com","threadId":"35320","inReplyTo":"1384210507-26561-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v6 04/10] transport-helper: check for 'forced update' message","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-11-11T22:55:06Z","receivedAt":"2013-11-11T22:55:06Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"So the remote-helpers can tell us when a forced push was needed.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n transport-helper.c | 8 +++++++-\n 1 file changed, 7 insertions(+), 1 deletion(-)\n\ndiff --git a/transport-helper.c b/transport-helper.c\nindex bead9b9..9a5814d 100644\n--- a/transport-helper.c\n+++ b/transport-helper.c\n@@ -644,7 +644,7 @@ static int push_update_ref_status(struct strbuf *buf,\n \t\t\t\t   struct ref *remote_refs)\n {\n \tchar *refname, *msg;\n-\tint status;\n+\tint status, forced = 0;\n \n \tif (!prefixcmp(buf->buf, \"ok \")) {\n \t\tstatus = REF_STATUS_OK;\n@@ -702,6 +702,11 @@ static int push_update_ref_status(struct strbuf *buf,\n \t\t\tfree(msg);\n \t\t\tmsg = NULL;\n \t\t}\n+\t\telse if (!strcmp(msg, \"forced update\")) {\n+\t\t\tforced = 1;\n+\t\t\tfree(msg);\n+\t\t\tmsg = NULL;\n+\t\t}\n \t}\n \n \tif (*ref)\n@@ -723,6 +728,7 @@ static int push_update_ref_status(struct strbuf *buf,\n \t}\n \n \t(*ref)->status = status;\n+\t(*ref)->forced_update = forced;\n \t(*ref)->remote_status = msg;\n \treturn !(status == REF_STATUS_OK);\n }\n-- \n1.8.4.2+fc1\n"},{"id":"230453","messageId":"1384210507-26561-11-git-send-email-felipe.contreras@gmail.com","threadId":"35320","inReplyTo":"1384210507-26561-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v6 02/10] transport-helper: don't update refs in dry-run","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-11-11T22:55:07Z","receivedAt":"2013-11-11T22:55:07Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"The remote helper namespace should not be updated.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n transport-helper.c | 9 +++++----\n 1 file changed, 5 insertions(+), 4 deletions(-)\n\ndiff --git a/transport-helper.c b/transport-helper.c\nindex b66c7fd..9558a0d 100644\n--- a/transport-helper.c\n+++ b/transport-helper.c\n@@ -728,7 +728,8 @@ static int push_update_ref_status(struct strbuf *buf,\n }\n \n static void push_update_refs_status(struct helper_data *data,\n-\t\t\t\t    struct ref *remote_refs)\n+\t\t\t\t    struct ref *remote_refs,\n+\t\t\t\t    int flags)\n {\n \tstruct strbuf buf = STRBUF_INIT;\n \tstruct ref *ref = remote_refs;\n@@ -742,7 +743,7 @@ static void push_update_refs_status(struct helper_data *data,\n \t\tif (push_update_ref_status(&buf, &ref, remote_refs))\n \t\t\tcontinue;\n \n-\t\tif (!data->refspecs || data->no_private_update)\n+\t\tif (flags & TRANSPORT_PUSH_DRY_RUN || !data->refspecs || data->no_private_update)\n \t\t\tcontinue;\n \n \t\t/* propagate back the update to the remote namespace */\n@@ -833,7 +834,7 @@ static int push_refs_with_push(struct transport *transport,\n \tsendline(data, &buf);\n \tstrbuf_release(&buf);\n \n-\tpush_update_refs_status(data, remote_refs);\n+\tpush_update_refs_status(data, remote_refs, flags);\n \treturn 0;\n }\n \n@@ -887,7 +888,7 @@ static int push_refs_with_export(struct transport *transport,\n \n \tif (finish_command(&exporter))\n \t\tdie(\"Error while running fast-export\");\n-\tpush_update_refs_status(data, remote_refs);\n+\tpush_update_refs_status(data, remote_refs, flags);\n \treturn 0;\n }\n \n-- \n1.8.4.2+fc1\n"},{"id":"230457","messageId":"xmqqd2m6jyue.fsf@gitster.dls.corp.google.com","threadId":"35320","inReplyTo":"1384210507-26561-6-git-send-email-felipe.contreras@gmail.com","subject":"Re: [PATCH v6 06/10] fast-export: add new --refspec option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-11-11T23:25:45Z","receivedAt":"2013-11-11T23:25:45Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Felipe Contreras <felipe.contreras@gmail.com> writes:\n\n> So that we can convert the exported ref names.\n>\n> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n> ---\n\nI thought that the discussion agreed this option should not be\ncalled --refspec but something like --refmap?\n"},{"id":"230458","messageId":"xmqq7gcejyuc.fsf@gitster.dls.corp.google.com","threadId":"35320","inReplyTo":"1384210507-26561-7-git-send-email-felipe.contreras@gmail.com","subject":"Re: [PATCH v6 03/10] transport-helper: add 'force' to 'export' helpers","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-11-11T23:28:26Z","receivedAt":"2013-11-11T23:28:26Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Felipe Contreras <felipe.contreras@gmail.com> writes:\n\n> Otherwise they cannot know when to force the push or not (other than\n> hacks).\n>\n> Tests-by: Richard Hansen <rhansen@bbn.com>\n> Documentation-by: Richard Hansen <rhansen@bbn.com>\n> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n> ---\n\nDidn't we agree that this should be warn, not die?\n\n> +\tif (flags & TRANSPORT_PUSH_FORCE) {\n> +\t\tif (set_helper_option(transport, \"force\", \"true\") != 0)\n> +\t\t\tdie(\"helper %s does not support 'force'\", data->name);\n> +\t}\n> +\n>  \thelper = get_helper(transport);\n>  \n>  \twrite_constant(helper->in, \"export\\n\");\n"},{"id":"230456","messageId":"xmqqiovyjyyu.fsf@gitster.dls.corp.google.com","threadId":"35320","inReplyTo":"1384210507-26561-2-git-send-email-felipe.contreras@gmail.com","subject":"Re: [PATCH v6 00/10] transport-helper: updates","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-11-11T23:33:13Z","receivedAt":"2013-11-11T23:33:13Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Felipe Contreras <felipe.contreras@gmail.com> writes:\n\n> Here are the patches that allow transport helpers to be completely transparent;\n> renaming branches, deleting them, custom refspecs, --force, --dry-run,\n> reporting forced update, everything works.\n\nHow are you sending your patches?  The Message-ID's suggest that\ngit-send-email is being used, but when the patches are ordered by\nthe sender datestamp, they seem to come out in a random order,\nunlike the patches other people send with git-send-email.\n\ngit-send-email gives a timestamp to the first message it sends out\nand then gives consecutive timestamps, one second apart, to\nsubsequent messages, in order to make this \"sorting by sender\ntimestamp on Date: field\" work. I am wondering if there is something\nyou are doing differently, and/or if there is something that needs\nto be fixed in the version of git-send-email you are using.\n\nThanks.\n"},{"id":"230459","messageId":"xmqq38n2jys4.fsf@gitster.dls.corp.google.com","threadId":"35320","inReplyTo":"1384210507-26561-2-git-send-email-felipe.contreras@gmail.com","subject":"Re: [PATCH v6 00/10] transport-helper: updates","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-11-11T23:37:15Z","receivedAt":"2013-11-11T23:37:15Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Felipe Contreras <felipe.contreras@gmail.com> writes:\n\n> Small changes since v5:\n>\n> diff --git a/builtin/fast-export.c b/builtin/fast-export.c\n> index 8ed41b4..4b76222 100644\n> --- a/builtin/fast-export.c\n> +++ b/builtin/fast-export.c\n> @@ -736,9 +736,10 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)\n>  \t\tusage_with_options (fast_export_usage, options);\n>  \n>  \tif (refspecs_list.nr) {\n> -\t\tconst char *refspecs_str[refspecs_list.nr];\n> +\t\tconst char **refspecs_str;\n>  \t\tint i;\n>  \n> +\t\trefspecs_str = xmalloc(sizeof(*refspecs_str) * refspecs_list.nr);\n>  \t\tfor (i = 0; i < refspecs_list.nr; i++)\n>  \t\t\trefspecs_str[i] = refspecs_list.items[i].string;\n>  \n> @@ -746,6 +747,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)\n>  \t\trefspecs = parse_fetch_refspec(refspecs_nr, refspecs_str);\n>  \n>  \t\tstring_list_clear(&refspecs_list, 1);\n> +\t\tfree(refspecs_str);\n>  \t}\n>  \n>  \tif (use_done_feature)\n> diff --git a/git-remote-testgit.sh b/git-remote-testgit.sh\n> index 716aa4c..1c006a0 100755\n> --- a/git-remote-testgit.sh\n> +++ b/git-remote-testgit.sh\n> @@ -15,6 +15,8 @@ test -z \"$refspec\" && prefix=\"refs\"\n>  \n>  export GIT_DIR=\"$url/.git\"\n>  \n> +force=\n> +\n>  mkdir -p \"$dir\"\n>  \n>  if test -z \"$GIT_REMOTE_TESTGIT_NO_MARKS\"\n\nLooking good, modulo a few minor nits I noticed while comparing with\nthe one that has been queued in 'pu', which I commented separately.\n\nWill re-queue.  Thanks.\n"},{"id":"230460","messageId":"CAMP44s3cqnZrTPede8=ARGo9ZsZjwjshWq3GBSfG_19Vmxofzg@mail.gmail.com","threadId":"35320","inReplyTo":"xmqqiovyjyyu.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v6 00/10] transport-helper: updates","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-11-11T23:44:34Z","receivedAt":"2013-11-11T23:44:34Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Mon, Nov 11, 2013 at 5:33 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Felipe Contreras <felipe.contreras@gmail.com> writes:\n>\n>> Here are the patches that allow transport helpers to be completely transparent;\n>> renaming branches, deleting them, custom refspecs, --force, --dry-run,\n>> reporting forced update, everything works.\n>\n> How are you sending your patches?\n\n% git-send-email --no-annotate list-of-patches\n\nHowever, I just noticed that the list-of-patches is in the wrong order.\n\n-- \nFelipe Contreras\n"},{"id":"230461","messageId":"CAMP44s0GJOTPA1_KSG=xSNGfdFJxLXD10b+Dm2OeaB5FRz61bw@mail.gmail.com","threadId":"35320","inReplyTo":"xmqq7gcejyuc.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v6 03/10] transport-helper: add 'force' to 'export' helpers","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-11-11T23:47:39Z","receivedAt":"2013-11-11T23:47:39Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Mon, Nov 11, 2013 at 5:28 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Felipe Contreras <felipe.contreras@gmail.com> writes:\n>\n>> Otherwise they cannot know when to force the push or not (other than\n>> hacks).\n>>\n>> Tests-by: Richard Hansen <rhansen@bbn.com>\n>> Documentation-by: Richard Hansen <rhansen@bbn.com>\n>> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n>> ---\n>\n> Didn't we agree that this should be warn, not die?\n\nYes, and I assumed you would do it without a reroll, because no reroll\nwas needed. I've updated my side as well now, for the next reroll.\n\n-- \nFelipe Contreras\n"},{"id":"230462","messageId":"CAMP44s2ubU_R0GkEUpEh24TxER3uONQJprh9Ot7+PL0QiDRmDg@mail.gmail.com","threadId":"35320","inReplyTo":"xmqqd2m6jyue.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v6 06/10] fast-export: add new --refspec option","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-11-11T23:50:21Z","receivedAt":"2013-11-11T23:50:21Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Mon, Nov 11, 2013 at 5:25 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Felipe Contreras <felipe.contreras@gmail.com> writes:\n>\n>> So that we can convert the exported ref names.\n>>\n>> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n>> ---\n>\n> I thought that the discussion agreed this option should not be\n> called --refspec but something like --refmap?\n\nI don't know what you agreed to, but I didn't agree to anything. What\nyou pass to this option is a refspec, so it makes sense to name the\noption --refspec.\n\n-- \nFelipe Contreras\n"},{"id":"230478","messageId":"5281C8EA.8030002@bbn.com","threadId":"35320","inReplyTo":"1384210507-26561-2-git-send-email-felipe.contreras@gmail.com","subject":"Re: [PATCH v6 00/10] transport-helper: updates","fromName":"Richard Hansen","fromEmail":"rhansen@bbn.com","sentAt":"2013-11-12T06:21:30Z","receivedAt":"2013-11-12T06:21:30Z","isPatch":true,"sender":{"key":"rhansen@rhansen.org","avatar":null},"body":"On 2013-11-11 17:54, Felipe Contreras wrote:\n> Hi,\n> \n> Here are the patches that allow transport helpers to be completely transparent;\n> renaming branches, deleting them, custom refspecs, --force, --dry-run,\n> reporting forced update, everything works.\n> \n> Small changes since v5:\n> \n> diff --git a/builtin/fast-export.c b/builtin/fast-export.c\n> index 8ed41b4..4b76222 100644\n> --- a/builtin/fast-export.c\n> +++ b/builtin/fast-export.c\n> @@ -736,9 +736,10 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)\n>  \t\tusage_with_options (fast_export_usage, options);\n>  \n>  \tif (refspecs_list.nr) {\n> -\t\tconst char *refspecs_str[refspecs_list.nr];\n> +\t\tconst char **refspecs_str;\n>  \t\tint i;\n>  \n> +\t\trefspecs_str = xmalloc(sizeof(*refspecs_str) * refspecs_list.nr);\n>  \t\tfor (i = 0; i < refspecs_list.nr; i++)\n>  \t\t\trefspecs_str[i] = refspecs_list.items[i].string;\n>  \n> @@ -746,6 +747,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)\n>  \t\trefspecs = parse_fetch_refspec(refspecs_nr, refspecs_str);\n>  \n>  \t\tstring_list_clear(&refspecs_list, 1);\n> +\t\tfree(refspecs_str);\n>  \t}\n>  \n>  \tif (use_done_feature)\n> diff --git a/git-remote-testgit.sh b/git-remote-testgit.sh\n> index 716aa4c..1c006a0 100755\n> --- a/git-remote-testgit.sh\n> +++ b/git-remote-testgit.sh\n> @@ -15,6 +15,8 @@ test -z \"$refspec\" && prefix=\"refs\"\n>  \n>  export GIT_DIR=\"$url/.git\"\n>  \n> +force=\n> +\n>  mkdir -p \"$dir\"\n>  \n>  if test -z \"$GIT_REMOTE_TESTGIT_NO_MARKS\"\n\nWhat about changing those two test-hg.sh tests to test_expect_success?\n\n  http://article.gmane.org/gmane.comp.version-control.git/237606\n\nShould those changes be squashed into the \"transport-helper: don't\nupdate refs in dry-run\" and \"transport-helper: add 'force' to 'export'\nhelpers\" commits?  Or are those commits not really the appropriate place?\n\nThanks,\nRichard\n"},{"id":"230479","messageId":"1384239808-19065-1-git-send-email-rhansen@bbn.com","threadId":"35320","inReplyTo":"1384210507-26561-2-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v2] remote-bzr: support the new 'force' option","fromName":"Richard Hansen","fromEmail":"rhansen@bbn.com","sentAt":"2013-11-12T07:03:28Z","receivedAt":"2013-11-12T07:03:28Z","isPatch":true,"sender":{"key":"rhansen@rhansen.org","avatar":null},"body":"Signed-off-by: Richard Hansen <rhansen@bbn.com>\n---\n\nThis is a reroll of:\n  http://article.gmane.org/gmane.comp.version-control.git/237607\nbased on feedback from Felipe:\n  http://article.gmane.org/gmane.comp.version-control.git/237615\n\nThis patch is an optional extension to Felipe's \"transport-helper:\nupdates\" patch series:\n  http://thread.gmane.org/gmane.comp.version-control.git/237663\nand it requires those changes to work.\n\n contrib/remote-helpers/git-remote-bzr | 32 +++++++++++++++++++++++++++++++-\n contrib/remote-helpers/test-bzr.sh    | 22 +++++++++++++++++++++-\n 2 files changed, 52 insertions(+), 2 deletions(-)\n\ndiff --git a/contrib/remote-helpers/git-remote-bzr b/contrib/remote-helpers/git-remote-bzr\nindex 7e34532..2f481e9 100755\n--- a/contrib/remote-helpers/git-remote-bzr\n+++ b/contrib/remote-helpers/git-remote-bzr\n@@ -42,6 +42,7 @@ import json\n import re\n import StringIO\n import atexit, shutil, hashlib, urlparse, subprocess\n+import types\n \n NAME_RE = re.compile('^([^<>]+)')\n AUTHOR_RE = re.compile('^([^<>]+?)? ?[<>]([^<>]*)(?:$|>)')\n@@ -684,7 +685,8 @@ def do_export(parser):\n                 peer = bzrlib.branch.Branch.open(peers[name],\n                                                  possible_transports=transports)\n                 try:\n-                    peer.bzrdir.push_branch(branch, revision_id=revid)\n+                    peer.bzrdir.push_branch(branch, revision_id=revid,\n+                                            overwrite=force)\n                 except bzrlib.errors.DivergedBranches:\n                     print \"error %s non-fast forward\" % ref\n                     continue\n@@ -718,8 +720,32 @@ def do_capabilities(parser):\n         print \"*import-marks %s\" % path\n     print \"*export-marks %s\" % path\n \n+    print \"option\"\n     print\n \n+class InvalidOptionValue(Exception):\n+    pass\n+\n+def get_bool_option(val):\n+    if val == 'true':\n+        return True\n+    elif val == 'false':\n+        return False\n+    else:\n+        raise InvalidOptionValue()\n+\n+def do_option(parser):\n+    global force\n+    (opt, val) = parser[1:3]\n+    try:\n+        if opt == 'force':\n+            force = get_bool_option(val)\n+            print 'ok'\n+        else:\n+            print 'unsupported'\n+    except InvalidOptionValue:\n+        print \"error '%s' is not a valid value for option '%s'\" % (val, opt)\n+\n def ref_is_valid(name):\n     return not True in [c in name for c in '~^: \\\\']\n \n@@ -882,6 +908,7 @@ def main(args):\n     global is_tmp\n     global branches, peers\n     global transports\n+    global force\n \n     alias = args[1]\n     url = args[2]\n@@ -895,6 +922,7 @@ def main(args):\n     branches = {}\n     peers = {}\n     transports = []\n+    force = False\n \n     if alias[5:] == url:\n         is_tmp = True\n@@ -930,6 +958,8 @@ def main(args):\n             do_import(parser)\n         elif parser.check('export'):\n             do_export(parser)\n+        elif parser.check('option'):\n+            do_option(parser)\n         else:\n             die('unhandled command: %s' % line)\n         sys.stdout.flush()\ndiff --git a/contrib/remote-helpers/test-bzr.sh b/contrib/remote-helpers/test-bzr.sh\nindex 1e53ff9..4f379c2 100755\n--- a/contrib/remote-helpers/test-bzr.sh\n+++ b/contrib/remote-helpers/test-bzr.sh\n@@ -66,13 +66,33 @@ test_expect_success 'pushing' '\n \ttest_cmp expected actual\n '\n \n+test_expect_success 'forced pushing' '\n+\t(\n+\tcd gitrepo &&\n+\techo three-new >content &&\n+\tgit commit -a --amend -m three-new &&\n+\tgit push -f\n+\t) &&\n+\n+\t(\n+\tcd bzrrepo &&\n+\t# the forced update overwrites the bzr branch but not the bzr\n+\t# working directory (it tries to merge instead)\n+\tbzr revert\n+\t) &&\n+\n+\techo three-new >expected &&\n+\tcat bzrrepo/content >actual &&\n+\ttest_cmp expected actual\n+'\n+\n test_expect_success 'roundtrip' '\n \t(\n \tcd gitrepo &&\n \tgit pull &&\n \tgit log --format=\"%s\" -1 origin/master >actual\n \t) &&\n-\techo three >expected &&\n+\techo three-new >expected &&\n \ttest_cmp expected actual &&\n \n \t(cd gitrepo && git push && git pull) &&\n-- \n1.8.5.rc1.208.g8ff7964\n"},{"id":"230481","messageId":"5281DB46.2010004@bbn.com","threadId":"35320","inReplyTo":"CAMP44s2ubU_R0GkEUpEh24TxER3uONQJprh9Ot7+PL0QiDRmDg@mail.gmail.com","subject":"Re: [PATCH v6 06/10] fast-export: add new --refspec option","fromName":"Richard Hansen","fromEmail":"rhansen@bbn.com","sentAt":"2013-11-12T07:39:50Z","receivedAt":"2013-11-12T07:39:50Z","isPatch":true,"sender":{"key":"rhansen@rhansen.org","avatar":null},"body":"On 2013-11-11 18:50, Felipe Contreras wrote:\n> On Mon, Nov 11, 2013 at 5:25 PM, Junio C Hamano <gitster@pobox.com> wrote:\n>> Felipe Contreras <felipe.contreras@gmail.com> writes:\n>>\n>>> So that we can convert the exported ref names.\n>>>\n>>> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n>>> ---\n>>\n>> I thought that the discussion agreed this option should not be\n>> called --refspec but something like --refmap?\n> \n> I don't know what you agreed to,\n\nhttp://article.gmane.org/gmane.comp.version-control.git/237473\n\n> but I didn't agree to anything.\n\nBased on your silence I too thought that you had agreed.\n\n> What you pass to this option is a refspec, so it makes sense to name\n> the option --refspec.\n\nAs discussed in that thread, it's not really the same thing as a refspec\nused in push or fetch.  In those commands, the refspec specifies two\nseparable things:  what to transfer, and how to translate refs names\nbetween the remote and local repositories.  IIUC, the fast-export\n--refspec argument only specifies how to translate ref names, not what\ngets transferred.\n\nIf my understanding is correct, then I agree with Junio and Peff that\n--refmap is a better name.\n\n-Richard\n"},{"id":"230498","messageId":"xmqqtxfhim4t.fsf@gitster.dls.corp.google.com","threadId":"35320","inReplyTo":"5281DB46.2010004@bbn.com","subject":"Re: [PATCH v6 06/10] fast-export: add new --refspec option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-11-12T17:08:02Z","receivedAt":"2013-11-12T17:08:02Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Richard Hansen <rhansen@bbn.com> writes:\n\n>>> I thought that the discussion agreed this option should not be\n>>> called --refspec but something like --refmap?\n>> \n>> I don't know what you agreed to,\n>\n> http://article.gmane.org/gmane.comp.version-control.git/237473\n\nYup, that was what I had in mind.\n\n>> but I didn't agree to anything.\n>\n> Based on your silence I too thought that you had agreed.\n\nCareful.  Silence does not mean agreement, at least around here.  It\nmay be just the person was busy and hasn't got around to it, was not\npaying attention and missed the discussion, or was not as interested\nin the topic as his/her other activities.\n\nThat, especially the last possibility among the three example\nreasons above, was why I said \"the discussion agreed\", not \"you\nagreed\".\n\n>> What you pass to this option is a refspec, so it makes sense to name\n>> the option --refspec.\n>\n> As discussed in that thread, it's not really the same thing as a refspec\n> used in push or fetch.  In those commands, the refspec specifies two\n> separable things:  what to transfer, and how to translate refs names\n> between the remote and local repositories.  IIUC, the fast-export\n> --refspec argument only specifies how to translate ref names, not what\n> gets transferred.\n>\n> If my understanding is correct, then I agree with Junio and Peff that\n> --refmap is a better name.\n\nI know from one of the tests that the option Felipe added is\nimplemented in such a way that allows:\n\n    git fast-export --option refs/heads/master:refs/heads/next master\n\nto rename the destination, but I didn't check, when I wrote the\nmessage to envision how a similar mechanism could be used to enhance\npush/fetch in the future, if it can be actually used as a mapping\n\n    git fast-export --option refs/heads/*:refs/remotes/mine/* master\n\nBeing able to do so was the only reason why I agree with the patch\nin question (not my toy patch, but [6/10] that started this thread)\nthat it is a good idea in the longer term, as the other approach I\nsuggested to teach revision command line parser to optionally take\nrefspecs as if they specify LHS of the colon as object name with\nrev_cmdline annotations would not work well for such a purpose.\n\nThanks.\n"},{"id":"230515","messageId":"528295cecbb0b_3b98795e7895@nysa.notmuch","threadId":"35320","inReplyTo":"5281C8EA.8030002@bbn.com","subject":"Re: [PATCH v6 00/10] transport-helper: updates","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-11-12T20:55:42Z","receivedAt":"2013-11-12T20:55:42Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Richard Hansen wrote:\n> On 2013-11-11 17:54, Felipe Contreras wrote:\n> > Hi,\n> > \n> > Here are the patches that allow transport helpers to be completely transparent;\n> > renaming branches, deleting them, custom refspecs, --force, --dry-run,\n> > reporting forced update, everything works.\n> > \n> > Small changes since v5:\n> > \n> > diff --git a/builtin/fast-export.c b/builtin/fast-export.c\n> > index 8ed41b4..4b76222 100644\n> > --- a/builtin/fast-export.c\n> > +++ b/builtin/fast-export.c\n> > @@ -736,9 +736,10 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)\n> >  \t\tusage_with_options (fast_export_usage, options);\n> >  \n> >  \tif (refspecs_list.nr) {\n> > -\t\tconst char *refspecs_str[refspecs_list.nr];\n> > +\t\tconst char **refspecs_str;\n> >  \t\tint i;\n> >  \n> > +\t\trefspecs_str = xmalloc(sizeof(*refspecs_str) * refspecs_list.nr);\n> >  \t\tfor (i = 0; i < refspecs_list.nr; i++)\n> >  \t\t\trefspecs_str[i] = refspecs_list.items[i].string;\n> >  \n> > @@ -746,6 +747,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)\n> >  \t\trefspecs = parse_fetch_refspec(refspecs_nr, refspecs_str);\n> >  \n> >  \t\tstring_list_clear(&refspecs_list, 1);\n> > +\t\tfree(refspecs_str);\n> >  \t}\n> >  \n> >  \tif (use_done_feature)\n> > diff --git a/git-remote-testgit.sh b/git-remote-testgit.sh\n> > index 716aa4c..1c006a0 100755\n> > --- a/git-remote-testgit.sh\n> > +++ b/git-remote-testgit.sh\n> > @@ -15,6 +15,8 @@ test -z \"$refspec\" && prefix=\"refs\"\n> >  \n> >  export GIT_DIR=\"$url/.git\"\n> >  \n> > +force=\n> > +\n> >  mkdir -p \"$dir\"\n> >  \n> >  if test -z \"$GIT_REMOTE_TESTGIT_NO_MARKS\"\n> \n> What about changing those two test-hg.sh tests to test_expect_success?\n> \n>   http://article.gmane.org/gmane.comp.version-control.git/237606\n\nI can do that.\n\n> Should those changes be squashed into the \"transport-helper: don't\n> update refs in dry-run\" and \"transport-helper: add 'force' to 'export'\n> helpers\" commits?  Or are those commits not really the appropriate place?\n\nI think it should be a separate commit, since it's not part of the core, but\ncontrib area.\n\n-- \nFelipe Contreras\n"},{"id":"230534","messageId":"5282971e8103_3b98795e78fd@nysa.notmuch","threadId":"35320","inReplyTo":"1384239808-19065-1-git-send-email-rhansen@bbn.com","subject":"RE: [PATCH v2] remote-bzr: support the new 'force' option","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-11-12T21:01:18Z","receivedAt":"2013-11-12T21:01:18Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Richard Hansen wrote:\n> Signed-off-by: Richard Hansen <rhansen@bbn.com>\n> ---\n> \n> This is a reroll of:\n>   http://article.gmane.org/gmane.comp.version-control.git/237607\n> based on feedback from Felipe:\n>   http://article.gmane.org/gmane.comp.version-control.git/237615\n> \n> This patch is an optional extension to Felipe's \"transport-helper:\n> updates\" patch series:\n>   http://thread.gmane.org/gmane.comp.version-control.git/237663\n> and it requires those changes to work.\n> \n>  contrib/remote-helpers/git-remote-bzr | 32 +++++++++++++++++++++++++++++++-\n>  contrib/remote-helpers/test-bzr.sh    | 22 +++++++++++++++++++++-\n>  2 files changed, 52 insertions(+), 2 deletions(-)\n> \n> diff --git a/contrib/remote-helpers/git-remote-bzr b/contrib/remote-helpers/git-remote-bzr\n> index 7e34532..2f481e9 100755\n> --- a/contrib/remote-helpers/git-remote-bzr\n> +++ b/contrib/remote-helpers/git-remote-bzr\n> @@ -42,6 +42,7 @@ import json\n>  import re\n>  import StringIO\n>  import atexit, shutil, hashlib, urlparse, subprocess\n> +import types\n\nNo need for this any more.\n\n>  NAME_RE = re.compile('^([^<>]+)')\n>  AUTHOR_RE = re.compile('^([^<>]+?)? ?[<>]([^<>]*)(?:$|>)')\n> @@ -684,7 +685,8 @@ def do_export(parser):\n>                  peer = bzrlib.branch.Branch.open(peers[name],\n>                                                   possible_transports=transports)\n>                  try:\n> -                    peer.bzrdir.push_branch(branch, revision_id=revid)\n> +                    peer.bzrdir.push_branch(branch, revision_id=revid,\n> +                                            overwrite=force)\n>                  except bzrlib.errors.DivergedBranches:\n>                      print \"error %s non-fast forward\" % ref\n>                      continue\n> @@ -718,8 +720,32 @@ def do_capabilities(parser):\n>          print \"*import-marks %s\" % path\n>      print \"*export-marks %s\" % path\n>  \n> +    print \"option\"\n>      print\n>  \n> +class InvalidOptionValue(Exception):\n> +    pass\n> +\n> +def get_bool_option(val):\n> +    if val == 'true':\n> +        return True\n> +    elif val == 'false':\n> +        return False\n> +    else:\n> +        raise InvalidOptionValue()\n> +\n> +def do_option(parser):\n> +    global force\n> +    (opt, val) = parser[1:3]\n\nI prefer:\n\n  opt, val = parser[1:3]\n\nBut not a big deal.\n\nOtherwise the patch looks OK to me.\n\n-- \nFelipe Contreras\n"},{"id":"230535","messageId":"5282977b2ecd_3b98795e785e@nysa.notmuch","threadId":"35320","inReplyTo":"5281DB46.2010004@bbn.com","subject":"Re: [PATCH v6 06/10] fast-export: add new --refspec option","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-11-12T21:02:51Z","receivedAt":"2013-11-12T21:02:51Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Richard Hansen wrote:\n> On 2013-11-11 18:50, Felipe Contreras wrote:\n> > On Mon, Nov 11, 2013 at 5:25 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> >> Felipe Contreras <felipe.contreras@gmail.com> writes:\n> >>\n> >>> So that we can convert the exported ref names.\n> >>>\n> >>> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n> >>> ---\n> >>\n> >> I thought that the discussion agreed this option should not be\n> >> called --refspec but something like --refmap?\n> > \n> > I don't know what you agreed to,\n> \n> http://article.gmane.org/gmane.comp.version-control.git/237473\n> \n> > but I didn't agree to anything.\n> \n> Based on your silence I too thought that you had agreed.\n\nGiven that my opinion is regarded as inferior by those in the discussion, I\ndon't see why I should share it, specially since when I do, it's considered\ntoxic if I disagree.\n\n> > What you pass to this option is a refspec, so it makes sense to name\n> > the option --refspec.\n> \n> As discussed in that thread, it's not really the same thing as a refspec\n> used in push or fetch.  In those commands, the refspec specifies two\n> separable things:  what to transfer, and how to translate refs names\n> between the remote and local repositories.  IIUC, the fast-export\n> --refspec argument only specifies how to translate ref names, not what\n> gets transferred.\n\nDoes it?\n\n % git config remote.origin.fetch '+refs/heads/*:refs/remotes-test/origin/*'\n % git fetch origin master\n From /home/felipec/dev/git\n  * branch            master     -> FETCH_HEAD\n  * [new branch]      master     -> refs/remotes-test/origin/master\n\nIn this case remote.origin.fetch is determining how to translate ref names, not\nwhat gets transferred, *exactly* the same as we are doing with --refspec. And\nas far as I know, remote.origin.fetch is a refspec.\n\n-- \nFelipe Contreras\n"},{"id":"230538","messageId":"xmqq38n1guo8.fsf@gitster.dls.corp.google.com","threadId":"35320","inReplyTo":"5282977b2ecd_3b98795e785e@nysa.notmuch","subject":"Re: [PATCH v6 06/10] fast-export: add new --refspec option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-11-12T21:46:31Z","receivedAt":"2013-11-12T21:46:31Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Felipe Contreras <felipe.contreras@gmail.com> writes:\n\n> Does it?\n>\n>  % git config remote.origin.fetch '+refs/heads/*:refs/remotes-test/origin/*'\n>  % git fetch origin master\n>  From /home/felipec/dev/git\n>   * branch            master     -> FETCH_HEAD\n>   * [new branch]      master     -> refs/remotes-test/origin/master\n>\n> In this case remote.origin.fetch is determining how to translate ref names, not\n> what gets transferred, *exactly* the same as we are doing with --refspec. And\n> as far as I know, remote.origin.fetch is a refspec.\n\nIf you had 'next' and 'pu' branches at the remote, do they get\nfetched with that command line?\n"},{"id":"230542","messageId":"5282b7cdf3b12_1d45133de74b8@nysa.notmuch","threadId":"35320","inReplyTo":"xmqq38n1guo8.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v6 06/10] fast-export: add new --refspec option","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-11-12T23:20:46Z","receivedAt":"2013-11-12T23:20:46Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Junio C Hamano wrote:\n> Felipe Contreras <felipe.contreras@gmail.com> writes:\n> \n> > Does it?\n> >\n> >  % git config remote.origin.fetch '+refs/heads/*:refs/remotes-test/origin/*'\n> >  % git fetch origin master\n> >  From /home/felipec/dev/git\n> >   * branch            master     -> FETCH_HEAD\n> >   * [new branch]      master     -> refs/remotes-test/origin/master\n> >\n> > In this case remote.origin.fetch is determining how to translate ref names, not\n> > what gets transferred, *exactly* the same as we are doing with --refspec. And\n> > as far as I know, remote.origin.fetch is a refspec.\n> \n> If you had 'next' and 'pu' branches at the remote, do they get\n> fetched with that command line?\n\nNo, why would they? You specified a single branch to fetch. Try it yourself.\n\n % git clone git://git.kernel.org/pub/scm/git/git.git\n % git config remote.origin.fetch '+refs/heads/*:refs/remotes-test/origin/*'\n % git fetch origin master\n\n-- \nFelipe Contreras\n"},{"id":"230543","messageId":"xmqqob5pfa6j.fsf@gitster.dls.corp.google.com","threadId":"35320","inReplyTo":"xmqq38n1guo8.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v6 06/10] fast-export: add new --refspec option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-11-12T23:54:28Z","receivedAt":"2013-11-12T23:54:28Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Felipe Contreras <felipe.contreras@gmail.com> writes:\n>\n>> Does it?\n>>\n>>  % git config remote.origin.fetch '+refs/heads/*:refs/remotes-test/origin/*'\n>>  % git fetch origin master\n>>  From /home/felipec/dev/git\n>>   * branch            master     -> FETCH_HEAD\n>>   * [new branch]      master     -> refs/remotes-test/origin/master\n>>\n>> In this case remote.origin.fetch is determining how to translate ref names, not\n>> what gets transferred, *exactly* the same as we are doing with --refspec. And\n>> as far as I know, remote.origin.fetch is a refspec.\n>\n> If you had 'next' and 'pu' branches at the remote, do they get\n> fetched with that command line?\n\nMore interestingly, if you have\n\n\t[remote \"mothership\"]\n\t\tpush = +refs/heads/*:refs/remotes/satellite/*\n\nin your configuration and then said\n\n\t$ git push mothership master\n\nthen configured remote.mothership.push is not even used (I bring\nthis up because \"export\" is more closely related to \"push\" than\n\"fetch\").\n\nThis (and why 'next' and 'pu' are not fetched in the \"fetch\"\nexample) is because traditionally, refspecs that are explicitly\ngiven on the command line overrides configured ones (in other words,\nconfigured ones are used as a fallback default).\n\nThis is a bit of tangent, but since the recent discussion on the\ntriangular workflows, I've been wondering if we may want to have a\nnew way to configure things so that we can say \"When I push to\nmothership any one of my local branches, I want it to go to the ref\nwith the same name at the mothership under refs/remotes/satellite/\nhierarchy (because I am emulating 'git fetch' that is run on the\nmothership to get updates from this satellite)\", somewhat similar to\nwhat you added to \"fast-export\" via the option in question.\n\nBut we cannot achieve that mapping by changing the meaning of the\nconfigured refspecs remote.mothership.push without having to worry\nabout breaking existing practices of people.  When they say \"git\npush mothership master\", they do mean to push refs/heads/master to\nrefs/heads/master, and it will break the expectation in their\nexisting repositories if we change the semantics under them.\n\nA possible way to achieve that mapping \"When I push to mothership\nany one of my local branches,...\" could be to introduce a _new_\nconfiguration (so that existing repositories will not suddenly\nchange their behaviour):\n\n\t[remote \"mothership\"]\n\t\tpushmap = +refs/heads/*:refs/remotes/satellite/*\n\nAnd then we can allow this command line\n\n\t$ git push mothership master\n\nto be affected by the mapping when expanding the short-hand refspecs\ngiven on the command line.  Traditionally, anything without colon\nstood as a short-hand for \"push to the same name\", e.g. 'master' is\nfor 'refs/heads/master:refs/heads/master' in this example, and\n'v1.0' would be for 'refs/tags/v1.0:refs/tags/v1.0'.\n\nBut it does not have to stay that way.  In order to move things\nforward in that direction, this new configuration has to be\ndistinguishable from the traditional \"refspec\", as it embodies a\ndifferent concept.\n"},{"id":"231697","messageId":"52a2f1c59de6f_29836d5e9830@nysa.notmuch","threadId":"35320","inReplyTo":"xmqqob5pfa6j.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v6 06/10] fast-export: add new --refspec option","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-12-07T10:00:37Z","receivedAt":"2013-12-07T10:00:37Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Junio C Hamano wrote:\n> Junio C Hamano <gitster@pobox.com> writes:\n> > Felipe Contreras <felipe.contreras@gmail.com> writes:\n\n> But it does not have to stay that way.  In order to move things\n> forward in that direction, this new configuration has to be\n> distinguishable from the traditional \"refspec\", as it embodies a\n> different concept.\n\nIs it a different concept?\n\n % git config remote.origin.fetch '+refs/heads/*:refs/remotes-test/origin/*'\n % git fetch origin master\n\nWhat do you call this thing? ------^\n\n-- \nFelipe Contreras\n"},{"id":"231817","messageId":"xmqqbo0pyc2u.fsf@gitster.dls.corp.google.com","threadId":"35320","inReplyTo":"52a2f1c59de6f_29836d5e9830@nysa.notmuch","subject":"Re: [PATCH v6 06/10] fast-export: add new --refspec option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-12-09T21:00:09Z","receivedAt":"2013-12-09T21:00:09Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Felipe Contreras <felipe.contreras@gmail.com> writes:\n\n> Junio C Hamano wrote:\n>> Junio C Hamano <gitster@pobox.com> writes:\n>> > Felipe Contreras <felipe.contreras@gmail.com> writes:\n>\n>> But it does not have to stay that way.  In order to move things\n>> forward in that direction, this new configuration has to be\n>> distinguishable from the traditional \"refspec\", as it embodies a\n>> different concept.\n>\n> Is it a different concept?\n>\n>  % git config remote.origin.fetch '+refs/heads/*:refs/remotes-test/origin/*'\n>  % git fetch origin master\n>\n> What do you call this thing? ------^\n\nThe answer to that question is the \"value of the 'remote.*.fetch'\nconfiguration variable\".\n\nThe refspec mechanism and syntax used in \"fetch\" and \"push\" were\ninvented and designed to express two things [*1*]:\n\n 1) what is the set of objects that are necessary and sufficient to\n    complete some histories need to be transferred; what are the\n    tips of these histories that are being completed?\n\n 2) after the object transfer, some refs on the side that receive\n    the objects are optionally to be updated;\n\n    2-a) which refs are they?\n    2-b) what objects are they updated to point at?\n\nA refspec consists of one or more elements, each of which has\nright and left hand side separated by a colon, i.e. RHS:LHS, and\n\n 1) is determined by the RHS\n 2-a) is determined by the LHS\n 2-b) is determined by the correspondence between RHS-to-LHS.\n\nA wildcarded \"refs/heads/*:refs/remotes/origin/*\" dynamically\nexpands to what the side that sends objects have, e.g. if fetching\nfrom a repository with 'master' and 'next' branches, it becomes\n\n\trefs/heads/master:refs/remotes/origin/master\n        refs/heads/next:refs/remotes/origin/next\n\nSo with\n\n\t$ refspec='refs/heads/master:refs/remotes/origin/master\n\t        refs/heads/next:refs/remotes/origin/next'\n\t$ git fetch origin $refspec\n\nwe transfer objects to allow us to have complete histories leading\nto 'master' and 'next' from the origin repository.  And we update\nour refs/remotes/origin/{next,master} refs.\n\nTraditionally, when there is _no_ refspec on the command line, the\nvalue of 'remote.*.fetch' configuration variable is used as the\nfallback default, and that usage is still true.  When used in that\nway, the value of the variable _is taken as_ a refspec.\n\nHowever, we can no longer say that the variable _is_ a refspec with\nthe modern Git, and here is why.\n\n\"git fetch origin master\" used to ignore the 'remote.*.fetch'\nconfiguration variable completely, but since f2690487 (which is a\nfairly recent invention), the variable participates in the \"fetch\"\nprocess in a different way [*2*].  With this in the config:\n\n    [remote \"origin\"]\n    \tfetch = refs/heads/master:refs/remotes/origin/master\n        fetch = refs/heads/next:refs/remotes/origin/next\n\nthe command with 'master' refspec on the command line transfers the\nobjects required to complete the history only for the 'master', and\nnot 'next':\n\n\t$ git fetch origin master\n\nIn this usage, 'master' on the command line is the only thing that\ndetermines what histories are completed (because it does not say\n'next', the objects necessary to complete its history are not\ntransferred unless they are needed to complete 'master').  The value\nof the 'remote.*.fetch' configuration does not participate in the\ndetermination of the history being transferred at all.  It is not\nused as a refspec.\n\nBut unlike Git of the last year, we do map this 'master' using the\n'remote.*.fetch' configuration variable, in order to decide 2)\nabove.  We find that the given remote ref, 'master', has an element\nthat corresopnds to it in the 'remote.*.fetch' configuration, and\nthat element tells us to update refs/remotes/origin/master to point\nat the object they call 'master', effectively turning the above\ncommand line into this form (using \"refspec\" that has only one\nelement, refs/heads/master:refs/remotes/origin/master):\n\n\t$ git fetch origin refs/heads/master:refs/remotes/origin/master\n\nThere is no \"refs/heads/next:refs/remotes/origin/next\" here, because\nthe 'fetch' configuration is not used as a refspec, but as something\nelse.\n\nMy understanding of the added option parameter to \"git fast-export\"\nis that it is not about specifying the history being transferred,\nbut is about mapping the name of the destination.  For example, does\nobject between 'master' and 'next' participate in the datastream\nproduced with this?\n\n\tfast-export \\\n            --refspec=refs/heads/master:refs/remotes/origin/master \\\n            --refspec=refs/heads/next:refs/remotes/origin/next \\\n            master\n\nIf this parameter were a refspec, as we have discussed already in\nprevious rounds [*3*], we should be able to give it on the command line,\nlike any normal refspec, instead of repeating the same thing\n(i.e. up to what commit should the history be transported) as in:\n\n\tfast-export --refspec=refs/heads/master:refs/remotes/origin/master master\n\nbut just\n\n\tfast-export refs/heads/master:refs/remotes/origin/master\n\n\n[Footnote]\n\n *1* Note that readers are hearing the authoritative definition\n     given by the person who invented and designed it back in August\n     2005.\n\n *2* And a recent $gmane/238832 moves \"push\" in the direction to be\n     in line with \"fetch\" in this regard.\n\n *3* And I think I even outlined the code to do so.\n"},{"id":"231821","messageId":"xmqqr49lwwzf.fsf@gitster.dls.corp.google.com","threadId":"35320","inReplyTo":"xmqqbo0pyc2u.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v6 06/10] fast-export: add new --refspec option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-12-09T21:11:32Z","receivedAt":"2013-12-09T21:11:32Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> A refspec consists of one or more elements, each of which has\n> right and left hand side separated by a colon, i.e. RHS:LHS, and\n>\n>  1) is determined by the RHS\n>  2-a) is determined by the LHS\n>  2-b) is determined by the correspondence between RHS-to-LHS.\n\nHeh, I got my right and left the other way around ;-)\n"},{"id":"239530","messageId":"53588b4b84323_59ed83d3083b@nysa.notmuch","threadId":"35320","inReplyTo":"xmqqbo0pyc2u.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v6 06/10] fast-export: add new --refspec option","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2014-04-24T03:55:55Z","receivedAt":"2014-04-24T03:55:55Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"Hi,\n\nSorry it took too long to reply to this.\n\nJunio C Hamano wrote:\n> Felipe Contreras <felipe.contreras@gmail.com> writes:\n> \n> > Junio C Hamano wrote:\n> >> Junio C Hamano <gitster@pobox.com> writes:\n> >> > Felipe Contreras <felipe.contreras@gmail.com> writes:\n> >\n> >> But it does not have to stay that way.  In order to move things\n> >> forward in that direction, this new configuration has to be\n> >> distinguishable from the traditional \"refspec\", as it embodies a\n> >> different concept.\n> >\n> > Is it a different concept?\n> >\n> >  % git config remote.origin.fetch '+refs/heads/*:refs/remotes-test/origin/*'\n> >  % git fetch origin master\n> >\n> > What do you call this thing? ------^\n> \n> The answer to that question is the \"value of the 'remote.*.fetch'\n> configuration variable\".\n\nYou are avoiding the question: it's a refspec.\n\n> There is no \"refs/heads/next:refs/remotes/origin/next\" here, because\n> the 'fetch' configuration is not used as a refspec, but as something\n> else.\n\nYet both remote.fetch and remote.push are a 'struct refspec', and the\ndocumentation says they are a \"refspec\".\n\n> My understanding of the added option parameter to \"git fast-export\"\n> is that it is not about specifying the history being transferred,\n> but is about mapping the name of the destination.  For example, does\n> object between 'master' and 'next' participate in the datastream\n> produced with this?\n> \n> \tfast-export \\\n>             --refspec=refs/heads/master:refs/remotes/origin/master \\\n>             --refspec=refs/heads/next:refs/remotes/origin/next \\\n>             master\n> \n> If this parameter were a refspec, as we have discussed already in\n> previous rounds [*3*], we should be able to give it on the command line,\n> like any normal refspec, instead of repeating the same thing\n> (i.e. up to what commit should the history be transported) as in:\n> \n> \tfast-export --refspec=refs/heads/master:refs/remotes/origin/master master\n> \n> but just\n> \n> \tfast-export refs/heads/master:refs/remotes/origin/master\n\nMaybe in an ideal world, which we don't live in.\n\nMy guess is that trying to accomplish such a goal would result in an\nunbelievable mess of the code that I wouldn't even want to think about where\nto start to code this.\n\nMoreover, `git grep refmap` returns me the following:\n\n  t/t5516-fetch-push.sh:test_expect_success 'pushing a specific ref applies remote.$name.push as refmap' '\n  t/t5516-fetch-push.sh:test_expect_success 'with no remote.$name.push, it is not used as refmap' '\n\nI'd say with --refspec is the simplest and most sensible way this can be\nimplemented.\n\n-- \nFelipe Contreras\n"}]}