{"thread":{"id":"35214","subject":"[PATCH v4 00/10] transport-helper: updates","startedAt":"2013-10-27T07:05:11Z","lastAt":"2013-11-12T06:09:46Z","messageCount":20,"participants":["Felipe Contreras","Eric Sunshine","Richard Hansen","Junio C Hamano"],"isPatch":true,"patchVersion":4,"patchTotal":10},"messages":[{"id":"229589","messageId":"1382857521-7005-1-git-send-email-felipe.contreras@gmail.com","threadId":"35214","inReplyTo":null,"subject":"[PATCH v4 00/10] transport-helper: updates","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-10-27T07:05:11Z","receivedAt":"2013-10-27T07:05:11Z","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\nSome of these were were sent before and rejected without a reason, but here\nthey are again in case anybody is interested.\n\nThis time rebased on top of the latest master, plus a few fixes.\n\nDiff from v3:\n\ndiff --git a/builtin/fast-export.c b/builtin/fast-export.c\nindex 9b728ca..60d4c80 100644\n--- a/builtin/fast-export.c\n+++ b/builtin/fast-export.c\n@@ -686,7 +686,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)\n        struct commit *commit;\n        char *export_filename = NULL, *import_filename = NULL;\n        uint32_t lastimportid;\n-       struct string_list refspecs_list;\n+       struct string_list refspecs_list = STRING_LIST_INIT_NODUP;\n        struct option options[] = {\n                OPT_INTEGER(0, \"progress\", &progress,\n                            N_(\"show progress after <n> objects\")),\ndiff --git a/transport-helper.c b/transport-helper.c\nindex d94eaf4..91636d5 100644\n--- a/transport-helper.c\n+++ b/transport-helper.c\n@@ -836,9 +836,6 @@ static int push_refs_with_export(struct transport *transport,\n                char *private;\n                unsigned char sha1[20];\n \n-               if (ref->deletion)\n-                       die(\"remote-helpers do not support ref deletion\");\n-\n                private = apply_refspecs(data->refspecs, data->refspec_nr, ref->name);\n                if (private && !get_sha1(private, sha1)) {\n                        strbuf_addf(&buf, \"^%s\", private);\n\nFelipe Contreras (10):\n  transport-helper: add 'force' to 'export' helpers\n  transport-helper: fix extra lines\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  transport-helper: don't update refs in dry-run\n\n Documentation/git-fast-export.txt |  4 ++++\n Documentation/git-fast-import.txt |  3 +++\n builtin/fast-export.c             | 47 ++++++++++++++++++++++++++++++++++++++-\n fast-import.c                     | 13 ++++++++---\n t/t5801-remote-helpers.sh         | 10 ++++++++-\n t/t9300-fast-import.sh            | 18 +++++++++++++++\n t/t9350-fast-export.sh            | 18 +++++++++++++++\n transport-helper.c                | 47 ++++++++++++++++++++++++++-------------\n 8 files changed, 140 insertions(+), 20 deletions(-)\n\n-- \n1.8.4-fc\n"},{"id":"229590","messageId":"1382857521-7005-2-git-send-email-felipe.contreras@gmail.com","threadId":"35214","inReplyTo":"1382857521-7005-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v4 03/10] transport-helper: check for 'forced update' message","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-10-27T07:05:12Z","receivedAt":"2013-10-27T07:05:12Z","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 707351d..f8eb143 100644\n--- a/transport-helper.c\n+++ b/transport-helper.c\n@@ -643,7 +643,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@@ -701,6 +701,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@@ -722,6 +727,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-fc\n"},{"id":"229591","messageId":"1382857521-7005-3-git-send-email-felipe.contreras@gmail.com","threadId":"35214","inReplyTo":"1382857521-7005-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v4 05/10] fast-export: add new --refspec option","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-10-27T07:05:13Z","receivedAt":"2013-10-27T07:05:13Z","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             | 30 ++++++++++++++++++++++++++++++\n t/t9350-fast-export.sh            |  7 +++++++\n 3 files changed, 41 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..b6f623e 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,19 @@ 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[refspecs_list.nr];\n+\t\tint i;\n+\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}\n+\n \tif (use_done_feature)\n \t\tprintf(\"feature done\\n\");\n \n@@ -741,5 +769,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 34c2d8f..dc6666f 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-fc\n"},{"id":"229593","messageId":"1382857521-7005-4-git-send-email-felipe.contreras@gmail.com","threadId":"35214","inReplyTo":"1382857521-7005-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v4 06/10] transport-helper: add support for old:new refspec","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-10-27T07:05:14Z","receivedAt":"2013-10-27T07:05:14Z","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 613f69a..407c18d 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 f8eb143..5454822 100644\n--- a/transport-helper.c\n+++ b/transport-helper.c\n@@ -848,7 +848,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@@ -886,8 +886,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@@ -895,6 +900,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);\n-- \n1.8.4-fc\n"},{"id":"229595","messageId":"1382857521-7005-5-git-send-email-felipe.contreras@gmail.com","threadId":"35214","inReplyTo":"1382857521-7005-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v4 02/10] transport-helper: fix extra lines","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-10-27T07:05:15Z","receivedAt":"2013-10-27T07:05:15Z","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 408d596..707351d 100644\n--- a/transport-helper.c\n+++ b/transport-helper.c\n@@ -879,9 +879,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-fc\n"},{"id":"229592","messageId":"1382857521-7005-6-git-send-email-felipe.contreras@gmail.com","threadId":"35214","inReplyTo":"1382857521-7005-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v4 09/10] transport-helper: add support to delete branches","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-10-27T07:05:16Z","receivedAt":"2013-10-27T07:05:16Z","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 407c18d..be543c0 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 '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 5454822..4f47bdd 100644\n--- a/transport-helper.c\n+++ b/transport-helper.c\n@@ -874,9 +874,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@@ -888,12 +885,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-fc\n"},{"id":"229598","messageId":"1382857521-7005-7-git-send-email-felipe.contreras@gmail.com","threadId":"35214","inReplyTo":"1382857521-7005-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v4 01/10] transport-helper: add 'force' to 'export' helpers","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-10-27T07:05:17Z","receivedAt":"2013-10-27T07:05:17Z","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\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n transport-helper.c | 5 +++++\n 1 file changed, 5 insertions(+)\n\ndiff --git a/transport-helper.c b/transport-helper.c\nindex b32e2d6..408d596 100644\n--- a/transport-helper.c\n+++ b/transport-helper.c\n@@ -853,6 +853,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-fc\n"},{"id":"229594","messageId":"1382857521-7005-8-git-send-email-felipe.contreras@gmail.com","threadId":"35214","inReplyTo":"1382857521-7005-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v4 08/10] fast-export: add support to delete refs","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-10-27T07:05:18Z","receivedAt":"2013-10-27T07:05:18Z","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 b6f623e..8ed41b4 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@@ -762,6 +775,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 dc6666f..ea6c96c 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-fc\n"},{"id":"229596","messageId":"1382857521-7005-9-git-send-email-felipe.contreras@gmail.com","threadId":"35214","inReplyTo":"1382857521-7005-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v4 10/10] transport-helper: don't update refs in dry-run","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-10-27T07:05:19Z","receivedAt":"2013-10-27T07:05:19Z","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 4f47bdd..ef91882 100644\n--- a/transport-helper.c\n+++ b/transport-helper.c\n@@ -733,7 +733,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@@ -747,7 +748,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@@ -838,7 +839,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@@ -905,7 +906,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-fc\n"},{"id":"229597","messageId":"1382857521-7005-10-git-send-email-felipe.contreras@gmail.com","threadId":"35214","inReplyTo":"1382857521-7005-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v4 07/10] fast-import: add support to delete refs","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-10-27T07:05:20Z","receivedAt":"2013-10-27T07:05:20Z","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..c49ede4 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) specifices 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 88fc407..f453388 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-fc\n"},{"id":"229599","messageId":"1382857521-7005-11-git-send-email-felipe.contreras@gmail.com","threadId":"35214","inReplyTo":"1382857521-7005-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v4 04/10] fast-export: improve argument parsing","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-10-27T07:05:21Z","receivedAt":"2013-10-27T07:05:21Z","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-fc\n"},{"id":"229609","messageId":"CAPig+cRDwrofbWOoZLnk9abUXmZWUQvmNLmRk9A+Kv7hcQLUXw@mail.gmail.com","threadId":"35214","inReplyTo":"1382857521-7005-10-git-send-email-felipe.contreras@gmail.com","subject":"Re: [PATCH v4 07/10] fast-import: add support to delete refs","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2013-10-27T10:24:04Z","receivedAt":"2013-10-27T10:24:04Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Sun, Oct 27, 2013 at 3:05 AM, Felipe Contreras\n<felipe.contreras@gmail.com> wrote:\n> 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>\n> diff --git a/Documentation/git-fast-import.txt b/Documentation/git-fast-import.txt\n> index 73f9806..c49ede4 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) specifices that the branch is to be\n\ns/specifices/specifies/\n\n> +  removed.\n> +\n>  The special case of restarting an incremental import from the\n>  current branch value should be written as:\n>  ----\n"},{"id":"229619","messageId":"1382908273-11200-1-git-send-email-rhansen@bbn.com","threadId":"35214","inReplyTo":"1382857521-7005-7-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v4 11/10] fixup! transport-helper: add 'force' to 'export' helpers","fromName":"Richard Hansen","fromEmail":"rhansen@bbn.com","sentAt":"2013-10-27T21:11:13Z","receivedAt":"2013-10-27T21:11:13Z","isPatch":true,"sender":{"key":"rhansen@rhansen.org","avatar":null},"body":"document the new 'force' option\n\nSigned-off-by: Richard Hansen <rhansen@bbn.com>\n---\n Documentation/gitremote-helpers.txt | 4 ++++\n 1 file changed, 4 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]\n-- \n1.8.4.1.610.g2fe5c0e\n"},{"id":"229620","messageId":"1382908589-7000-1-git-send-email-rhansen@bbn.com","threadId":"35214","inReplyTo":"1382857521-7005-1-git-send-email-felipe.contreras@gmail.com","subject":"[PATCH v4 12/10] git-remote-testgit: support the new 'force' option","fromName":"Richard Hansen","fromEmail":"rhansen@bbn.com","sentAt":"2013-10-27T21:16:28Z","receivedAt":"2013-10-27T21:16:28Z","isPatch":true,"sender":{"key":"rhansen@rhansen.org","avatar":null},"body":"Signed-off-by: Richard Hansen <rhansen@bbn.com>\n---\n git-remote-testgit.sh | 18 ++++++++++++++++++\n 1 file changed, 18 insertions(+)\n\ndiff --git a/git-remote-testgit.sh b/git-remote-testgit.sh\nindex 6d2f282..80546c1 100755\n--- a/git-remote-testgit.sh\n+++ b/git-remote-testgit.sh\n@@ -6,6 +6,7 @@ url=$2\n \n dir=\"$GIT_DIR/testgit/$alias\"\n prefix=\"refs/testgit/$alias\"\n+forcearg=\n \n default_refspec=\"refs/heads/*:${prefix}/heads/*\"\n \n@@ -39,6 +40,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 +95,7 @@ do\n \t\tbefore=$(git for-each-ref --format=' %(refname) %(objectname) ')\n \n \t\tgit fast-import \\\n+\t\t\t${forcearg} \\\n \t\t\t${testgitmarks:+\"--import-marks=$testgitmarks\"} \\\n \t\t\t${testgitmarks:+\"--export-marks=$testgitmarks\"} \\\n \t\t\t--quiet\n@@ -115,6 +118,21 @@ do\n \n \t\techo\n \t\t;;\n+\toption\\ *)\n+\t\tread cmd opt val <<EOF\n+${line}\n+EOF\n+\t\tcase ${opt} in\n+\t\t    force)\n+\t\t\tcase ${val} in\n+\t\t\t    true) forcearg=--force; echo 'ok';;\n+\t\t\t    false) forcearg=; echo 'ok';;\n+\t\t\t    *) printf %s\\\\n \"error '${val}'\\\n+ is not a valid value for option ${opt}\";;\n+\t\t\tesac;;\n+\t\t    *) echo \"unsupported\";;\n+\t\tesac\n+\t\t;;\n \t'')\n \t\texit\n \t\t;;\n-- \n1.8.4.1.614.ga09cf56\n"},{"id":"229621","messageId":"1382908589-7000-2-git-send-email-rhansen@bbn.com","threadId":"35214","inReplyTo":"1382908589-7000-1-git-send-email-rhansen@bbn.com","subject":"[PATCH v4 13/10] test: remote-helper: add test for force pushes","fromName":"Richard Hansen","fromEmail":"rhansen@bbn.com","sentAt":"2013-10-27T21:16:29Z","receivedAt":"2013-10-27T21:16:29Z","isPatch":true,"sender":{"key":"rhansen@rhansen.org","avatar":null},"body":"Signed-off-by: Richard Hansen <rhansen@bbn.com>\n---\n t/t5801-remote-helpers.sh | 13 +++++++++++++\n 1 file changed, 13 insertions(+)\n\ndiff --git a/t/t5801-remote-helpers.sh b/t/t5801-remote-helpers.sh\nindex be543c0..93a7d34 100755\n--- a/t/t5801-remote-helpers.sh\n+++ b/t/t5801-remote-helpers.sh\n@@ -102,6 +102,19 @@ test_expect_success 'push delete branch' '\n \t rev-parse --verify refs/heads/new-name\n '\n \n+test_expect_success 'force push' '\n+\t(cd local &&\n+\t git checkout -b force-test &&\n+\t echo content >>file &&\n+\t git commit -a -m eight &&\n+\t git push origin force-test &&\n+\t echo content >>file &&\n+\t git commit -a --amend -m eight-modified &&\n+\t git 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 &&\n-- \n1.8.4.1.614.ga09cf56\n"},{"id":"229715","messageId":"526f74cf8307f_37cdfb1e7c31@nysa.notmuch","threadId":"35214","inReplyTo":"1382908589-7000-1-git-send-email-rhansen@bbn.com","subject":"RE: [PATCH v4 12/10] git-remote-testgit: support the new 'force' option","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-10-29T08:41:51Z","receivedAt":"2013-10-29T08:41:51Z","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>  git-remote-testgit.sh | 18 ++++++++++++++++++\n>  1 file changed, 18 insertions(+)\n> \n> diff --git a/git-remote-testgit.sh b/git-remote-testgit.sh\n> index 6d2f282..80546c1 100755\n> --- a/git-remote-testgit.sh\n> +++ b/git-remote-testgit.sh\n> @@ -6,6 +6,7 @@ url=$2\n>  \n>  dir=\"$GIT_DIR/testgit/$alias\"\n>  prefix=\"refs/testgit/$alias\"\n> +forcearg=\n>  \n>  default_refspec=\"refs/heads/*:${prefix}/heads/*\"\n>  \n> @@ -39,6 +40,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 +95,7 @@ do\n>  \t\tbefore=$(git for-each-ref --format=' %(refname) %(objectname) ')\n>  \n>  \t\tgit fast-import \\\n> +\t\t\t${forcearg} \\\n>  \t\t\t${testgitmarks:+\"--import-marks=$testgitmarks\"} \\\n>  \t\t\t${testgitmarks:+\"--export-marks=$testgitmarks\"} \\\n>  \t\t\t--quiet\n> @@ -115,6 +118,21 @@ do\n>  \n>  \t\techo\n>  \t\t;;\n> +\toption\\ *)\n> +\t\tread cmd opt val <<EOF\n> +${line}\n> +EOF\n\nWe can do <<-EOF to align this properly.\n\nAlso, I don't see why all the variables are ${foo} instead of $foo.\n\n> +\t\tcase ${opt} in\n> +\t\t    force)\n\nI think the convention is to align these:\n\ncase $opt in\nforce)\n\n> +\t\t\tcase ${val} in\n> +\t\t\t    true) forcearg=--force; echo 'ok';;\n> +\t\t\t    false) forcearg=; echo 'ok';;\n> +\t\t\t    *) printf %s\\\\n \"error '${val}'\\\n> + is not a valid value for option ${opt}\";;\n\nI think this is packing a lot of stuff and it's not that readable.\n\nMoreover, this is not for production purposes, it's for testing purposes and a\nguideline, I think this suffices.\n\n\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\nBut this is definetly good to have, will merge.\n\n-- \nFelipe Contreras\n"},{"id":"230374","messageId":"52800CB7.7080905@bbn.com","threadId":"35214","inReplyTo":"526f74cf8307f_37cdfb1e7c31@nysa.notmuch","subject":"Re: [PATCH v4 12/10] git-remote-testgit: support the new 'force' option","fromName":"Richard Hansen","fromEmail":"rhansen@bbn.com","sentAt":"2013-11-10T22:46:15Z","receivedAt":"2013-11-10T22:46:15Z","isPatch":true,"sender":{"key":"rhansen@rhansen.org","avatar":null},"body":"On 2013-10-29 04:41, Felipe Contreras wrote:\n> Richard Hansen wrote:\n>> Signed-off-by: Richard Hansen <rhansen@bbn.com>\n>> ---\n>>  git-remote-testgit.sh | 18 ++++++++++++++++++\n>>  1 file changed, 18 insertions(+)\n>>\n>> diff --git a/git-remote-testgit.sh b/git-remote-testgit.sh\n>> index 6d2f282..80546c1 100755\n>> --- a/git-remote-testgit.sh\n>> +++ b/git-remote-testgit.sh\n>> @@ -6,6 +6,7 @@ url=$2\n>>  \n>>  dir=\"$GIT_DIR/testgit/$alias\"\n>>  prefix=\"refs/testgit/$alias\"\n>> +forcearg=\n>>  \n>>  default_refspec=\"refs/heads/*:${prefix}/heads/*\"\n>>  \n>> @@ -39,6 +40,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 +95,7 @@ do\n>>  \t\tbefore=$(git for-each-ref --format=' %(refname) %(objectname) ')\n>>  \n>>  \t\tgit fast-import \\\n>> +\t\t\t${forcearg} \\\n>>  \t\t\t${testgitmarks:+\"--import-marks=$testgitmarks\"} \\\n>>  \t\t\t${testgitmarks:+\"--export-marks=$testgitmarks\"} \\\n>>  \t\t\t--quiet\n>> @@ -115,6 +118,21 @@ do\n>>  \n>>  \t\techo\n>>  \t\t;;\n>> +\toption\\ *)\n>> +\t\tread cmd opt val <<EOF\n>> +${line}\n>> +EOF\n> \n> We can do <<-EOF to align this properly.\n\nGood point.  I personally avoid tabs whenever possible, and <<- only\nworks with tabs, so I'm in the habit of doing <<EOF.\n\n> \n> Also, I don't see why all the variables are ${foo} instead of $foo.\n\nI'm in the habit of doing ${foo} because I like the consistency --\nsometimes you need them to disambiguate, and sometimes you need special\nexpansions like ${foo##bar} or ${foo:-bar}.\n\nIn this case it's actually less consistent to do ${foo} because the rest\nof the file doesn't use {} when not needed, so I agree with your change.\n\n> \n>> +\t\tcase ${opt} in\n>> +\t\t    force)\n> \n> I think the convention is to align these:\n> \n> case $opt in\n> force)\n\nThe existing case statement in this file indents the patterns the same\namount as the case statement, so this should be aligned to match.\n\nIn general I rarely see the case patterns indented at the same level as\nthe case statement, possibly because Emacs shell-mode indents the\npatterns more than the case statement (by default).  The POSIX spec\ncontains a mix of styles:\n  * the normative text documenting the format of a 'case' construct\n    indents the patterns more than the 'case' statement\n  * two of the four non-normative examples indent the patterns\n    more than the 'case' statements; the other two do not\n\n> \n>> +\t\t\tcase ${val} in\n>> +\t\t\t    true) forcearg=--force; echo 'ok';;\n>> +\t\t\t    false) forcearg=; echo 'ok';;\n>> +\t\t\t    *) printf %s\\\\n \"error '${val}'\\\n>> + is not a valid value for option ${opt}\";;\n> \n> I think this is packing a lot of stuff and it's not that readable.\n> \n> Moreover, this is not for production purposes, it's for testing purposes and a\n> guideline, I think this suffices.\n> \n> \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\nWorks for me.\n\n> \n> But this is definetly good to have, will merge.\n\nThanks,\nRichard\n"},{"id":"230377","messageId":"CAMP44s3P7mmBP7=g4ZZpQcqyzeyAcAeH6gNfusbNX8xeQ+0JVQ@mail.gmail.com","threadId":"35214","inReplyTo":"52800CB7.7080905@bbn.com","subject":"Re: [PATCH v4 12/10] git-remote-testgit: support the new 'force' option","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2013-11-11T03:57:16Z","receivedAt":"2013-11-11T03:57:16Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"On Sun, Nov 10, 2013 at 4:46 PM, Richard Hansen <rhansen@bbn.com> wrote:\n> On 2013-10-29 04:41, Felipe Contreras wrote:\n>> Richard Hansen wrote:\n>>> Signed-off-by: Richard Hansen <rhansen@bbn.com>\n>>> ---\n>>>  git-remote-testgit.sh | 18 ++++++++++++++++++\n>>>  1 file changed, 18 insertions(+)\n>>>\n>>> diff --git a/git-remote-testgit.sh b/git-remote-testgit.sh\n>>> index 6d2f282..80546c1 100755\n>>> --- a/git-remote-testgit.sh\n>>> +++ b/git-remote-testgit.sh\n>>> @@ -6,6 +6,7 @@ url=$2\n>>>\n>>>  dir=\"$GIT_DIR/testgit/$alias\"\n>>>  prefix=\"refs/testgit/$alias\"\n>>> +forcearg=\n>>>\n>>>  default_refspec=\"refs/heads/*:${prefix}/heads/*\"\n>>>\n>>> @@ -39,6 +40,7 @@ do\n>>>              fi\n>>>              test -n \"$GIT_REMOTE_TESTGIT_SIGNED_TAGS\" && echo \"signed-tags\"\n>>>              test -n \"$GIT_REMOTE_TESTGIT_NO_PRIVATE_UPDATE\" && echo \"no-private-update\"\n>>> +            echo 'option'\n>>>              echo\n>>>              ;;\n>>>      list)\n>>> @@ -93,6 +95,7 @@ do\n>>>              before=$(git for-each-ref --format=' %(refname) %(objectname) ')\n>>>\n>>>              git fast-import \\\n>>> +                    ${forcearg} \\\n>>>                      ${testgitmarks:+\"--import-marks=$testgitmarks\"} \\\n>>>                      ${testgitmarks:+\"--export-marks=$testgitmarks\"} \\\n>>>                      --quiet\n>>> @@ -115,6 +118,21 @@ do\n>>>\n>>>              echo\n>>>              ;;\n>>> +    option\\ *)\n>>> +            read cmd opt val <<EOF\n>>> +${line}\n>>> +EOF\n>>\n>> We can do <<-EOF to align this properly.\n>\n> Good point.  I personally avoid tabs whenever possible, and <<- only\n> works with tabs, so I'm in the habit of doing <<EOF.\n\nThat looks very weird to me, plus <<-EOF is often used already in git tests.\n\n>> Also, I don't see why all the variables are ${foo} instead of $foo.\n>\n> I'm in the habit of doing ${foo} because I like the consistency --\n\nSure, but with the price of less readibility. If consistency was the\npriority, we would be doing the follwoing in C:\n\nif (foo) {\n  # single line\n}\n\nSince the if might contain multiple lines, but we don't do that,\nbecause readibility is more important than consistency. So sometimes\nit's with braces, sometimes without.\n\n>>> +            case ${opt} in\n>>> +                force)\n>>\n>> I think the convention is to align these:\n>>\n>> case $opt in\n>> force)\n>\n> The existing case statement in this file indents the patterns the same\n> amount as the case statement, so this should be aligned to match.\n>\n> In general I rarely see the case patterns indented at the same level as\n> the case statement, possibly because Emacs shell-mode indents the\n> patterns more than the case statement (by default).  The POSIX spec\n> contains a mix of styles:\n>   * the normative text documenting the format of a 'case' construct\n>     indents the patterns more than the 'case' statement\n>   * two of the four non-normative examples indent the patterns\n>     more than the 'case' statements; the other two do not\n\nThe style in C has the cases at the same level, so I think it makes\nsense to do the same in shell, but I'm not sure if that's followed\nalready.\n\n>>> +                    case ${val} in\n>>> +                        true) forcearg=--force; echo 'ok';;\n>>> +                        false) forcearg=; echo 'ok';;\n>>> +                        *) printf %s\\\\n \"error '${val}'\\\n>>> + is not a valid value for option ${opt}\";;\n>>\n>> I think this is packing a lot of stuff and it's not that readable.\n>>\n>> Moreover, this is not for production purposes, it's for testing purposes and a\n>> guideline, I think this suffices.\n>>\n>>\n>>       option\\ *)\n>>               read cmd opt val <<-EOF\n>>               $line\n>>               EOF\n>>               case $opt in\n>>               force)\n>>                       test $val = \"true\" && force=\"true\" || force=\n>>                       echo \"ok\"\n>>                       ;;\n>>\n>>                       echo \"unsupported\"\n>>                       ;;\n>>               esac\n>>               ;;\n>\n> Works for me.\n\nGood, the final code style can be decided later on, and perhaps update\nDocumentation/CodingGuidelines, but it's good the rest is more or less\nsettled.\n\nCheers.\n\n-- \nFelipe Contreras\n"},{"id":"230407","messageId":"xmqqwqkelrn1.fsf@gitster.dls.corp.google.com","threadId":"35214","inReplyTo":"52800CB7.7080905@bbn.com","subject":"Re: [PATCH v4 12/10] git-remote-testgit: support the new 'force' option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2013-11-11T18:28:34Z","receivedAt":"2013-11-11T18:28:34Z","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 think the convention is to align these:\n>> \n>> case $opt in\n>> force)\n>\n> The existing case statement in this file indents the patterns the same\n> amount as the case statement, so this should be aligned to match.\n>\n> In general I rarely see the case patterns indented at the same level as\n> the case statement,\n\nWhat you see does not matter in the context of this project ;-)\nThis is what we have in Documentation/CodingGuidelines:\n\n    For shell scripts specifically (not exhaustive):\n\n     - Case arms are indented at the same depth as case and esac lines.\n\nThanks.\n"},{"id":"230476","messageId":"5281C62A.6070208@bbn.com","threadId":"35214","inReplyTo":"xmqqwqkelrn1.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v4 12/10] git-remote-testgit: support the new 'force' option","fromName":"Richard Hansen","fromEmail":"rhansen@bbn.com","sentAt":"2013-11-12T06:09:46Z","receivedAt":"2013-11-12T06:09:46Z","isPatch":true,"sender":{"key":"rhansen@rhansen.org","avatar":null},"body":"On 2013-11-11 13:28, Junio C Hamano wrote:\n> Richard Hansen <rhansen@bbn.com> writes:\n> \n>>> I think the convention is to align these:\n>>>\n>>> case $opt in\n>>> force)\n>>\n>> The existing case statement in this file indents the patterns the same\n>> amount as the case statement, so this should be aligned to match.\n>>\n>> In general I rarely see the case patterns indented at the same level as\n>> the case statement,\n> \n> What you see does not matter in the context of this project ;-)\n> This is what we have in Documentation/CodingGuidelines:\n> \n>     For shell scripts specifically (not exhaustive):\n> \n>      - Case arms are indented at the same depth as case and esac lines.\n\nDoh!  I missed that.  Thanks for pointing it out.\n\nThanks,\nRichard\n"}]}