{"thread":{"id":"48204","subject":"[PATCH] ls-remote: create '--sort' option","startedAt":"2018-04-02T20:08:14Z","lastAt":"2018-04-02T21:19:26Z","messageCount":4,"participants":["Harald Nordgren","Junio C Hamano","Jeff King"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"343603","messageId":"20180402200736.80161-1-haraldnordgren@gmail.com","threadId":"48204","inReplyTo":null,"subject":"[PATCH] ls-remote: create '--sort' option","fromName":"Harald Nordgren","fromEmail":"haraldnordgren@gmail.com","sentAt":"2018-04-02T20:07:36Z","receivedAt":"2018-04-02T20:08:14Z","isPatch":true,"sender":{"key":"haraldnordgren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/9569897?v=4"},"body":"Create a '--sort' option for ls-remote. This is useful e.g. for the Go\nrepository after the release of version 1.10, where by default v1.10 is\nsorted before v1.2. See:\n\n\t$ git ls-remote -t https://go.googlesource.com/go\n\t...\n\t205f850ceacfc39d1e9d76a9569416284594ce8c        refs/tags/go1.1\n\td260448f6b6ac10efe4ae7f6dfe944e72bc2a676        refs/tags/go1.1.1\n\t1d6d8fca241bb611af51e265c1b5a2e9ae904702        refs/tags/go1.1.2\n\tbf86aec25972f3a100c3aa58a6abcbcc35bdea49        refs/tags/go1.10\n\tac7c0ee26dda18076d5f6c151d8f920b43340ae3        refs/tags/go1.10.1\n\t9ce6b5c2ed5d3d5251b9a6a0c548d5fb2c8567e8        refs/tags/go1.10beta1\n\t594668a5a96267a46282ce3007a584ec07adf705        refs/tags/go1.10beta2\n\t5348aed83e39bd1d450d92d7f627e994c2db6ebf        refs/tags/go1.10rc1\n\t20e228f2fdb44350c858de941dff4aea9f3127b8        refs/tags/go1.10rc2\n\t1c5438aae896edcd1e9f9618f4776517f08053b3        refs/tags/go1.1rc2\n\t46a6097aa7943a490e9bd2e04274845d0e5e200f        refs/tags/go1.1rc3\n\t402d3590b54e4a0df9fb51ed14b2999e85ce0b76        refs/tags/go1.2\n\t9c9802fad57c1bcb72ea98c5c55ea2652efc5772        refs/tags/go1.2.1\n\t...\n\nSigned-off-by: Harald Nordgren <haraldnordgren@gmail.com>\n---\n Documentation/git-ls-remote.txt | 12 +++++++++++-\n builtin/ls-remote.c             | 27 +++++++++++++++++++++++++--\n t/t5512-ls-remote.sh            | 41 ++++++++++++++++++++++++++++++++++++++++-\n 3 files changed, 76 insertions(+), 4 deletions(-)\n\ndiff --git a/Documentation/git-ls-remote.txt b/Documentation/git-ls-remote.txt\nindex 5f2628c8f..17fae7218 100644\n--- a/Documentation/git-ls-remote.txt\n+++ b/Documentation/git-ls-remote.txt\n@@ -10,7 +10,7 @@ SYNOPSIS\n --------\n [verse]\n 'git ls-remote' [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n-\t      [-q | --quiet] [--exit-code] [--get-url]\n+\t      [-q | --quiet] [--exit-code] [--get-url] [--sort=<key>]\n \t      [--symref] [<repository> [<refs>...]]\n \n DESCRIPTION\n@@ -60,6 +60,16 @@ OPTIONS\n \tupload-pack only shows the symref HEAD, so it will be the only\n \tone shown by ls-remote.\n \n+--sort=<key>::\n+\tSort based on the key given.  Prefix `-` to sort in\n+\tdescending order of the value. You may use the --sort=<key> option\n+\tmultiple times, in which case the last key becomes the primary\n+\tkey. Also supports \"version:refname\" or \"v:refname\" (tag\n+\tnames are treated as versions). The \"version:refname\" sort\n+\torder can also be affected by the \"versionsort.suffix\"\n+\tconfiguration variable.\n+\tThe keys supported are the same as those in `git for-each-ref`.\n+\n <repository>::\n \tThe \"remote\" repository to query.  This parameter can be\n \teither a URL or the name of a remote (see the GIT URLS and\ndiff --git a/builtin/ls-remote.c b/builtin/ls-remote.c\nindex 540d56429..5521c72f4 100644\n--- a/builtin/ls-remote.c\n+++ b/builtin/ls-remote.c\n@@ -1,6 +1,7 @@\n #include \"builtin.h\"\n #include \"cache.h\"\n #include \"transport.h\"\n+#include \"ref-filter.h\"\n #include \"remote.h\"\n \n static const char * const ls_remote_usage[] = {\n@@ -47,6 +48,8 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)\n \tstruct remote *remote;\n \tstruct transport *transport;\n \tconst struct ref *ref;\n+\tstruct ref_array array;\n+\tstatic struct ref_sorting *sorting = NULL, **sorting_tail = &sorting;\n \n \tstruct option options[] = {\n \t\tOPT__QUIET(&quiet, N_(\"do not print remote URL\")),\n@@ -60,6 +63,8 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)\n \t\tOPT_BIT(0, \"refs\", &flags, N_(\"do not show peeled tags\"), REF_NORMAL),\n \t\tOPT_BOOL(0, \"get-url\", &get_url,\n \t\t\t N_(\"take url.<base>.insteadOf into account\")),\n+\t\tOPT_CALLBACK(0 , \"sort\", sorting_tail, N_(\"key\"),\n+\t\t\t     N_(\"field name to sort on\"), &parse_opt_ref_sorting),\n \t\tOPT_SET_INT_F(0, \"exit-code\", &status,\n \t\t\t      N_(\"exit with exit code 2 if no matching refs are found\"),\n \t\t\t      2, PARSE_OPT_NOCOMPLETE),\n@@ -68,6 +73,8 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)\n \t\tOPT_END()\n \t};\n \n+\tmemset(&array, 0, sizeof(array));\n+\n \targc = parse_options(argc, argv, prefix, options, ls_remote_usage,\n \t\t\t     PARSE_OPT_STOP_AT_NON_OPTION);\n \tdest = argv[0];\n@@ -108,9 +115,25 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)\n \t\t\tcontinue;\n \t\tif (!tail_match(pattern, ref->name))\n \t\t\tcontinue;\n+\n+\t\tstruct ref_array_item *item;\n+\t\tFLEX_ALLOC_MEM(item, refname, ref->name, strlen(ref->name));\n+\t\titem->symref = ref->symref;\n+\t\titem->objectname = ref->old_oid;\n+\n+\t\tREALLOC_ARRAY(array.items, array.nr + 1);\n+\t\tarray.items[array.nr++] = item;\n+\t}\n+\n+\tif (sorting) {\n+\t\tref_array_sort(sorting, &array);\n+\t}\n+\n+\tfor (int i = 0; i < array.nr; i++) {\n+\t\tconst struct ref_array_item *ref = array.items[i];\n \t\tif (show_symref_target && ref->symref)\n-\t\t\tprintf(\"ref: %s\\t%s\\n\", ref->symref, ref->name);\n-\t\tprintf(\"%s\\t%s\\n\", oid_to_hex(&ref->old_oid), ref->name);\n+\t\t\tprintf(\"ref: %s\\t%s\\n\", ref->symref, ref->refname);\n+\t\tprintf(\"%s\\t%s\\n\", oid_to_hex(&ref->objectname), ref->refname);\n \t\tstatus = 0; /* we found something */\n \t}\n \treturn status;\ndiff --git a/t/t5512-ls-remote.sh b/t/t5512-ls-remote.sh\nindex 02106c922..66370cd88 100755\n--- a/t/t5512-ls-remote.sh\n+++ b/t/t5512-ls-remote.sh\n@@ -10,6 +10,9 @@ test_expect_success setup '\n \ttest_tick &&\n \tgit commit -m initial &&\n \tgit tag mark &&\n+\tgit tag mark1.1 &&\n+\tgit tag mark1.2 &&\n+\tgit tag mark1.10 &&\n \tgit show-ref --tags -d | sed -e \"s/ /\t/\" >expected.tag &&\n \t(\n \t\techo \"$(git rev-parse HEAD)\tHEAD\"\n@@ -39,6 +42,39 @@ test_expect_success 'ls-remote self' '\n \ttest_cmp expected.all actual\n '\n \n+test_expect_success 'ls-remote --sort=\"version:refname\" --tags self' '\n+\tcat >expect <<-\\EOF &&\n+\t1bd44cb9d13204b0fe1958db0082f5028a16eb3a\trefs/tags/mark\n+\t1bd44cb9d13204b0fe1958db0082f5028a16eb3a\trefs/tags/mark1.1\n+\t1bd44cb9d13204b0fe1958db0082f5028a16eb3a\trefs/tags/mark1.2\n+\t1bd44cb9d13204b0fe1958db0082f5028a16eb3a\trefs/tags/mark1.10\n+\tEOF\n+\tgit ls-remote --sort=\"version:refname\" --tags self >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'ls-remote --sort=\"-version:refname\" --tags self' '\n+\tcat >expect <<-\\EOF &&\n+\t1bd44cb9d13204b0fe1958db0082f5028a16eb3a\trefs/tags/mark1.10\n+\t1bd44cb9d13204b0fe1958db0082f5028a16eb3a\trefs/tags/mark1.2\n+\t1bd44cb9d13204b0fe1958db0082f5028a16eb3a\trefs/tags/mark1.1\n+\t1bd44cb9d13204b0fe1958db0082f5028a16eb3a\trefs/tags/mark\n+\tEOF\n+\tgit ls-remote --sort=\"-version:refname\" --tags self >actual &&\n+\ttest_cmp expect actual\n+'\n+\n+test_expect_success 'ls-remote --sort=\"-refname\" --tags self' '\n+\tcat >expect <<-\\EOF &&\n+\t1bd44cb9d13204b0fe1958db0082f5028a16eb3a\trefs/tags/mark1.2\n+\t1bd44cb9d13204b0fe1958db0082f5028a16eb3a\trefs/tags/mark1.10\n+\t1bd44cb9d13204b0fe1958db0082f5028a16eb3a\trefs/tags/mark1.1\n+\t1bd44cb9d13204b0fe1958db0082f5028a16eb3a\trefs/tags/mark\n+\tEOF\n+\tgit ls-remote --sort=\"-refname\" --tags self >actual &&\n+\ttest_cmp expect actual\n+'\n+\n test_expect_success 'dies when no remote specified and no default remotes found' '\n \ttest_must_fail git ls-remote\n '\n@@ -131,7 +167,7 @@ test_expect_success 'Report no-match with --exit-code' '\n \n test_expect_success 'Report match with --exit-code' '\n \tgit ls-remote --exit-code other.git \"refs/tags/*\" >actual &&\n-\tgit ls-remote . tags/mark >expect &&\n+\tgit ls-remote . tags/mark* >expect &&\n \ttest_cmp expect actual\n '\n \n@@ -178,6 +214,9 @@ test_expect_success 'ls-remote --symref' '\n \t1bd44cb9d13204b0fe1958db0082f5028a16eb3a\trefs/remotes/origin/HEAD\n \t1bd44cb9d13204b0fe1958db0082f5028a16eb3a\trefs/remotes/origin/master\n \t1bd44cb9d13204b0fe1958db0082f5028a16eb3a\trefs/tags/mark\n+\t1bd44cb9d13204b0fe1958db0082f5028a16eb3a\trefs/tags/mark1.1\n+\t1bd44cb9d13204b0fe1958db0082f5028a16eb3a\trefs/tags/mark1.10\n+\t1bd44cb9d13204b0fe1958db0082f5028a16eb3a\trefs/tags/mark1.2\n \tEOF\n \tgit ls-remote --symref >actual &&\n \ttest_cmp expect actual\n-- \n2.14.3 (Apple Git-98)\n\n"},{"id":"343606","messageId":"xmqq1sfxz7t4.fsf@gitster-ct.c.googlers.com","threadId":"48204","inReplyTo":"20180402200736.80161-1-haraldnordgren@gmail.com","subject":"Re: [PATCH] ls-remote: create '--sort' option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2018-04-02T20:12:39Z","receivedAt":"2018-04-02T20:12:46Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Harald Nordgren <haraldnordgren@gmail.com> writes:\n\n> Subject: Re: [PATCH] ls-remote: create '--sort' option\n\nIt would be more helpful to mark as [PATCH v2] a rerolled patch like\nthis.\n\n> Create a '--sort' option for ls-remote. This is useful e.g. for the Go\n> repository after the release of version 1.10, where by default v1.10 is\n> sorted before v1.2. See:\n>\n> \t$ git ls-remote -t https://go.googlesource.com/go\n\nDoes this sample command line also need updating for the refined\ndesign?\n\n> \t...\n> \t205f850ceacfc39d1e9d76a9569416284594ce8c        refs/tags/go1.1\n> \td260448f6b6ac10efe4ae7f6dfe944e72bc2a676        refs/tags/go1.1.1\n> \t1d6d8fca241bb611af51e265c1b5a2e9ae904702        refs/tags/go1.1.2\n> \tbf86aec25972f3a100c3aa58a6abcbcc35bdea49        refs/tags/go1.10\n> \tac7c0ee26dda18076d5f6c151d8f920b43340ae3        refs/tags/go1.10.1\n> ...\n> +\tgit ls-remote --sort=\"-version:refname\" --tags self >actual &&\n> +\ttest_cmp expect actual\n> +...\n> +\tgit ls-remote --sort=\"-refname\" --tags self >actual &&\n\nThese both look sensible (also the variant without the dash prefix\nwhich I omitted from the quote).\n\n\n\n"},{"id":"343628","messageId":"CAHwyqnXx86jHrDNhTphzT19egY=tdrS67L3Hs=XTcSBbxpwnZw@mail.gmail.com","threadId":"48204","inReplyTo":"xmqq1sfxz7t4.fsf@gitster-ct.c.googlers.com","subject":"Re: [PATCH] ls-remote: create '--sort' option","fromName":"Harald Nordgren","fromEmail":"haraldnordgren@gmail.com","sentAt":"2018-04-02T21:14:53Z","receivedAt":"2018-04-02T21:15:40Z","isPatch":true,"sender":{"key":"haraldnordgren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/9569897?v=4"},"body":"I shortened the commit message. Since we already have this feature for\nother sub-commands I guess I don't have to explain what version\nsemantics are.\n\nHave to say I'm a bit confused about 'git send-mail'. This time I tried\n\n    git send-email --subject-prefix=\"PATCH v4\"\n--in-reply-to='20180402005248.52418-1-haraldnordgren@gmail.com'\n--compose -1\n\n...and the supplied 'git@vger.kernel.org' on the prompt. hopefully\neveryone received the latest patches. However, at least what it looks\nlike from Gmail / Google Inbox, the discussion is now split into two\nthreads. Hopefully the patches still make sense though.\n\nI will post replies to the original email chain after this message.\n\nOn Mon, Apr 2, 2018 at 10:12 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Harald Nordgren <haraldnordgren@gmail.com> writes:\n>\n>> Subject: Re: [PATCH] ls-remote: create '--sort' option\n>\n> It would be more helpful to mark as [PATCH v2] a rerolled patch like\n> this.\n>\n>> Create a '--sort' option for ls-remote. This is useful e.g. for the Go\n>> repository after the release of version 1.10, where by default v1.10 is\n>> sorted before v1.2. See:\n>>\n>>       $ git ls-remote -t https://go.googlesource.com/go\n>\n> Does this sample command line also need updating for the refined\n> design?\n>\n>>       ...\n>>       205f850ceacfc39d1e9d76a9569416284594ce8c        refs/tags/go1.1\n>>       d260448f6b6ac10efe4ae7f6dfe944e72bc2a676        refs/tags/go1.1.1\n>>       1d6d8fca241bb611af51e265c1b5a2e9ae904702        refs/tags/go1.1.2\n>>       bf86aec25972f3a100c3aa58a6abcbcc35bdea49        refs/tags/go1.10\n>>       ac7c0ee26dda18076d5f6c151d8f920b43340ae3        refs/tags/go1.10.1\n>> ...\n>> +     git ls-remote --sort=\"-version:refname\" --tags self >actual &&\n>> +     test_cmp expect actual\n>> +...\n>> +     git ls-remote --sort=\"-refname\" --tags self >actual &&\n>\n> These both look sensible (also the variant without the dash prefix\n> which I omitted from the quote).\n>\n>\n>\n"},{"id":"343630","messageId":"20180402211920.GA32099@sigill.intra.peff.net","threadId":"48204","inReplyTo":"20180402200736.80161-1-haraldnordgren@gmail.com","subject":"Re: [PATCH] ls-remote: create '--sort' option","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2018-04-02T21:19:20Z","receivedAt":"2018-04-02T21:19:26Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Apr 02, 2018 at 10:07:36PM +0200, Harald Nordgren wrote:\n\n> @@ -108,9 +115,25 @@ int cmd_ls_remote(int argc, const char **argv, const char *prefix)\n>  \t\t\tcontinue;\n>  \t\tif (!tail_match(pattern, ref->name))\n>  \t\t\tcontinue;\n> +\n> +\t\tstruct ref_array_item *item;\n\nWe don't allow mixed declarations and code; this line needs to go at the\ntop of the block.\n\n> +\t\tFLEX_ALLOC_MEM(item, refname, ref->name, strlen(ref->name));\n> +\t\titem->symref = ref->symref;\n> +\t\titem->objectname = ref->old_oid;\n> +\n> +\t\tREALLOC_ARRAY(array.items, array.nr + 1);\n> +\t\tarray.items[array.nr++] = item;\n> +\t}\n\nThis will grow by one each time, which ends up doing quadratic work in\nthe number of items (although it can often be less if the realloc is\nable to just extend the block). It should probably use ALLOC_GROW()\nto move it more aggressively.\n\nInterestingly, the ref-filter code itself seems to have the same\nproblem, but I couldn't measure any speedup. So either my analysis is\ntotally wrong, or we end up reusing the block most of the time in\npractice.\n\n> +\n> +\tif (sorting) {\n> +\t\tref_array_sort(sorting, &array);\n> +\t}\n\nMinor style nit: we usually omit the braces for a one-liner block.\n\nThe ref-filter code lets you sort on any arbitrary field. So you could\ndo:\n\n  git ls-remote --sort=committerdate\n\nWhat should that do?\n\nWith your patch, I think we'll just get something like:\n\n  fatal: missing object 468165c1d8a442994a825f3684528361727cd8c0 for HEAD\n\nwhich is perhaps the best we can do (it might even work if you've\nrecently fetched from the other side).\n\n-Peff\n"}]}