{"thread":{"id":"30655","subject":"[PATCH/RFC] improve no-op push output","startedAt":"2012-05-30T12:08:04Z","lastAt":"2012-06-05T10:10:19Z","messageCount":6,"participants":["Jeff King","Junio C Hamano","Matthieu Moy"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"192481","messageId":"20120530120804.GA3501@sigill.intra.peff.net","threadId":"30655","inReplyTo":null,"subject":"[PATCH/RFC] improve no-op push output","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2012-05-30T12:08:04Z","receivedAt":"2012-05-30T12:08:04Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"I noticed the mention of the \"Everything up-to-date\" message in a nearby\nthread. This patch doesn't help with the case there, but it made me\nthink about how vague that message is.\n\n-- >8 --\nWhen a push is a no-op because all refs are up-to-date, we print\n\"Everything up-to-date\". That is reasonable when push.default is\n\"matching\" (or when a wildcard refspec is given), because \"Everything\"\npretty obviously means \"everything you asked git to push\".\n\nBut when one of the single-ref push.default modes is used, the\n\"Everything\" is slightly misleading; we only tried to push one thing,\nand we should not give the user the impression that the remote is\ncompletely in sync with what is in their local repo.\n\nInstead, let's detect the case that we attempted to push a single ref,\nand if so, just show the verbose status table (which includes the\nup-to-date ref). We don't want to show it if we tried to push many refs,\nbecause it could be quite long (e.g., in the case of \"matching\").\n\n---\nSo before, running:\n\n  git init -q --bare parent &&\n  git clone -q parent child 2>/dev/null &&\n  cd child &&\n  echo one >one && git add one && git commit -q -m one &&\n  git branch other &&\n  git -c push.default=simple push\n\nwould just print:\n\n  Everything up-to-date\n\nand now you get:\n\n  To /tmp/push-message/parent\n   = [up to date]      master -> master\n\nwhich is much more informative. And this could naturally extend to\nprinting the whole table when n < 5, or something similar. I don't think\nit would help the case that David reported, though, since it sounds like\nhis problem was being on a detached HEAD without realizing it (and even\nif we did print a status table, he would be similarly confused).\n\ndiff --git a/transport.c b/transport.c\nindex 1811b50..4dc09da 100644\n--- a/transport.c\n+++ b/transport.c\n@@ -1033,6 +1033,15 @@ static void die_with_unpushed_submodules(struct string_list *needs_pushing)\n \tdie(\"Aborting.\");\n }\n \n+static int num_uptodate(struct ref *ref)\n+{\n+\tint n = 0;\n+\tfor (; ref; ref = ref->next)\n+\t\tif (ref->status == REF_STATUS_UPTODATE)\n+\t\t\tn++;\n+\treturn n;\n+}\n+\n int transport_push(struct transport *transport,\n \t\t   int refspec_nr, const char **refspec, int flags,\n \t\t   int *nonfastforward)\n@@ -1116,8 +1125,15 @@ int transport_push(struct transport *transport,\n \n \t\tif (porcelain && !push_ret)\n \t\t\tputs(\"Done\");\n-\t\telse if (!quiet && !ret && !transport_refs_pushed(remote_refs))\n-\t\t\tfprintf(stderr, \"Everything up-to-date\\n\");\n+\t\telse if (!quiet && !ret && !transport_refs_pushed(remote_refs)) {\n+\t\t\tif (verbose)\n+\t\t\t\t; /* already showed the up-to-date entries */\n+\t\t\telse if (num_uptodate(remote_refs) == 1)\n+\t\t\t\ttransport_print_push_status(transport->url,\n+\t\t\t\t    remote_refs, 1, 0, nonfastforward);\n+\t\t\telse\n+\t\t\t\tfprintf(stderr, \"Everything up-to-date\\n\");\n+\t\t}\n \n \t\treturn ret;\n \t}\n"},{"id":"192501","messageId":"7vr4u1zhcz.fsf@alter.siamese.dyndns.org","threadId":"30655","inReplyTo":"20120530120804.GA3501@sigill.intra.peff.net","subject":"Re: [PATCH/RFC] improve no-op push output","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-05-30T17:52:28Z","receivedAt":"2012-05-30T17:52:28Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> I noticed the mention of the \"Everything up-to-date\" message in a nearby\n> thread. This patch doesn't help with the case there, but it made me\n> think about how vague that message is.\n>\n> -- >8 --\n> When a push is a no-op because all refs are up-to-date, we print\n> \"Everything up-to-date\". That is reasonable when push.default is\n> \"matching\" (or when a wildcard refspec is given), because \"Everything\"\n> pretty obviously means \"everything you asked git to push\".\n>\n> But when one of the single-ref push.default modes is used, the\n> \"Everything\" is slightly misleading; we only tried to push one thing,\n> and we should not give the user the impression that the remote is\n> completely in sync with what is in their local repo.\n>\n> Instead, let's detect the case that we attempted to push a single ref,\n> and if so, just show the verbose status table (which includes the\n> up-to-date ref). We don't want to show it if we tried to push many refs,\n> because it could be quite long (e.g., in the case of \"matching\").\n>\n> ---\n> So before, running:\n>\n>   git init -q --bare parent &&\n>   git clone -q parent child 2>/dev/null &&\n>   cd child &&\n>   echo one >one && git add one && git commit -q -m one &&\n>   git branch other &&\n>   git -c push.default=simple push\n>\n> would just print:\n>\n>   Everything up-to-date\n>\n> and now you get:\n>\n>   To /tmp/push-message/parent\n>    = [up to date]      master -> master\n>\n> which is much more informative.\n\nI think a more interesting case is to do this in the child:\n\n\tgit checkout other\n        git -c push.default=matching push\n\nafter the above sequence.  It will try to push master to master (and\nthe most important part is 'other' is not involved in this push at\nall) and would give you the same updated message, which would make\nit more clear that 'other' is not involved.  Although it by itself\nis good, but unless you are paying attention, you may not catch that\nyour current branch is *not* listed in the output, so it might not\nhelp people that much, even if they weren't on a detached HEAD.\n\nSomebody who is unaware that she has been working on detached HEAD\nis by definition very unlikely to notice that the 'master' in the\noutput is different from her current branch, as she is not paying\nattention to what branch she is working on.\n\nIt might be a better approach to check if the set of pushed refs\ninclude the current branch and rephrase the message only in that\ncase, perhaps\n\n\tEverything up-to-date (the current branch not pushed)\n\nor something.\n"},{"id":"192534","messageId":"vpqtxywswwo.fsf@bauges.imag.fr","threadId":"30655","inReplyTo":"7vr4u1zhcz.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH/RFC] improve no-op push output","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2012-05-31T06:10:47Z","receivedAt":"2012-05-31T06:10:47Z","isPatch":true,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n>> would just print:\n>>\n>>   Everything up-to-date\n>>\n>> and now you get:\n>>\n>>   To /tmp/push-message/parent\n>>    = [up to date]      master -> master\n> [...]\n>\n> \tEverything up-to-date (the current branch not pushed)\n\nI like both. They don't really take more screen space (1 more line for\nJeff, which is acceptable IMHO), and do add information.\n\nI'd add the number of branches pushed in case it's not one, so it could\nsay one of:\n\n  To /tmp/push-message/parent\n   = [up to date]      master -> master\n\nor\n\n  Everything up-to-date (X branches pushed, including the current)\n\nor\n\n  Everything up-to-date (X branches pushed, not including the current)\n\nIt would give a clue to a user having created many local branches that\nhis local branches were not pushed, and vice-versa, may help people who\ndid not understand that \"push.default=matching\" was pushing multiple\nbranches.\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"192800","messageId":"20120604125126.GD27676@sigill.intra.peff.net","threadId":"30655","inReplyTo":"7vr4u1zhcz.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH/RFC] improve no-op push output","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2012-06-04T12:51:26Z","receivedAt":"2012-06-04T12:51:26Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Wed, May 30, 2012 at 10:52:28AM -0700, Junio C Hamano wrote:\n\n> > So before, running:\n> >\n> >   git init -q --bare parent &&\n> >   git clone -q parent child 2>/dev/null &&\n> >   cd child &&\n> >   echo one >one && git add one && git commit -q -m one &&\n> >   git branch other &&\n> >   git -c push.default=simple push\n> >\n> > would just print:\n> >\n> >   Everything up-to-date\n> >\n> > and now you get:\n> >\n> >   To /tmp/push-message/parent\n> >    = [up to date]      master -> master\n> >\n> > which is much more informative.\n> \n> I think a more interesting case is to do this in the child:\n> \n> \tgit checkout other\n>         git -c push.default=matching push\n> \n> after the above sequence.  It will try to push master to master (and\n> the most important part is 'other' is not involved in this push at\n> all) and would give you the same updated message, which would make\n> it more clear that 'other' is not involved.\n\nThanks for a good example. Part of the reason my patch was RFC was that\nI had a feeling there was a more general problem to be solved, and I\ncouldn't quite put my finger on it.\n\nTaking a step back, the real issue is not that \"everything up to date\"\nis not accurate for single-branch pushes. It is that users sometimes\nexpect a thing to have been pushed, and it is not (because the\nconfiguration is different than they expect, or because they are on a\ndifferent branch than they expect). Sometimes that is masked by saying\n\"Everything up-to-date\" (because the user thinks \"everything\" included\nwhat they wanted, even though it did not). But sometimes it is because\nthings _do_ get pushed, but they fail to notice that the thing they\nexpected was not in the list.\n\nSo I think in general, the solution is for \"git push\" to be more\nspecific about what happened. But there are some complications, as I'll\nget to below.\n\n> Although it by itself is good, but unless you are paying attention,\n> you may not catch that your current branch is *not* listed in the\n> output, so it might not help people that much, even if they weren't on\n> a detached HEAD.\n> \n> Somebody who is unaware that she has been working on detached HEAD is\n> by definition very unlikely to notice that the 'master' in the output\n> is different from her current branch, as she is not paying attention\n> to what branch she is working on.\n> \n> It might be a better approach to check if the set of pushed refs\n> include the current branch and rephrase the message only in that case,\n> perhaps\n> \n> \tEverything up-to-date (the current branch not pushed)\n> \n> or something.\n\nHmm. I like that approach, because it is directly responding to a\nspecific thing that might be confusing the user.  But I'm not sure it is\ncomplete.\n\nFor one thing, it only helps for the case of \"push.default is matching,\nand my HEAD was not pushed\" (detached or not). Another one I'd expect is\n\"push.default is not matching, and I expected all of my work to be\npushed\". And you mentioned above \"push.default is matching, and I\nexpected 'foo' to be pushed, but forgot that upstream does not yet have\nit).\n\nSecondly, it helps the detached HEAD case for \"matching\", but should do\nnothing for the other cases, all of which should error out (because\nthere is by definition no defined upstream for \"upstream\" or \"simple\",\nnor would we know what to call the remote side for \"current\").\n\nSo I think we would really need to break down each potentially confusing\ncase, and come up with a solution for each. I think we can divide the\npush configuration into three cases: matching, single (which includes\n\"upstream\", \"simple\", and \"current\"), or custom refspecs. Let's ignore\nthe final one for now. It's relatively rare, and probably the most\ncommon use is mirroring (in which case we know we pushed everything,\nanyway). And then we have a few potential confusing situations:\n\n  1. We are on a detached HEAD; the user expects their current work to\n     be pushed, but it is not. With the \"single\" cases, we should\n     already error out. For the \"matching\" case, we don't want to error\n     out, but it might be worth printing a warning to say \"by the way,\n     your HEAD is detached\", whether everything is up-to-date or not.\n\n     Maybe that would be annoying, though. I guess it could be\n     configurable with an advice.*. Or maybe it's not worth caring\n     about, since we are pushing new people towards the \"single\" case\n     anyway.\n\n  2. We are on a branch; the user expects it to be pushed, but it is\n     not. This can't happen with the \"single\" cases, since they always\n     push HEAD (or fail). For matching, again, a solution might be \"by\n     the way, your HEAD was not pushed\", with the same caveats as above.\n\n  3. We are on a branch; the user expects some other branch X to be\n     pushed, but it is not.\n\n     For the \"single\" cases, they will either get a single-line status\n     table (mentioning HEAD), or they will get \"Everything up-to-date\".\n     In the former case, it is hopefully obvious that their branch is\n     not mentioned. In the latter case, I think the \"everything\" is\n     potentially misleading (and the fact that we never say _which_\n     branch is pushed. So if they thought they were on X, but were on Y,\n     they might be confused). So I think the right solution is to just\n     be more specific; say \"X is up-to-date\", or just show the\n     single-line status table.\n\n     For the \"matching\" case, it's much harder.\n\n     If we show them the whole description of what happened and hoping\n     they notice that their branch is not included.  When something\n     actually gets pushed, we show the status table already, and they\n     may or may not look through it to find the branch in question\n     (indeed, they may not even be trying to push X at the time, but\n     rather may later say \"Hey, I thought I pushed everything; why is X\n     not here?).\n\n     If nothing gets pushed (i.e., \"Everything up-to-date\"), we are not\n     much better off. We don't currently show the list of what we\n     attempted (without \"-v\"), but showing it would not be much better.\n     It is potentially long, and the user has no reason to scan through\n     it checking to make sure each branch is there.\n\n     So it would really depend on us noting that the branch is\n     exceptional for some reason in not being pushed. In case (2) above,\n     we noted that the branch is HEAD, which makes us think maybe they\n     wanted to push it, and we should give it special mention. We could\n     also potentially show the list of branches that _weren't_ pushed.\n     Depending on your workflow, that may be a small list, and an\n     exceptional circumstance. But it may also be quite large.\n\nSorry, that explanation ended up long. As you can see, I'm still talking\nout what the actual problem is. By the analysis above, there are\nbasically two features I'd consider:\n\n  1. For a single-ref push, always mention the ref name, even if it is\n     up-to-date. My previous patch showed the status table, but we could\n     also just tweak the \"Everything up-to-date\" to say \"Ref X is\n     up-to-date\".\n\n     We could also consider doing it not just in the single-ref case,\n     but when there are fewer than N refs. The single-ref one is the\n     most interesting, though, because it hits the newer push.default\n     settings.\n\n  2. Introduce a \"push.warnMatch\" config option, which can be set to one\n     of:\n\n       - \"none\"; the current behavior\n\n       - \"branches\"; mention all unmatched refs which are in refs/heads\n\n       - \"head\"; mention the current HEAD if it is unmatched\n\n-Peff\n"},{"id":"192811","messageId":"7vzk8jt4q5.fsf@alter.siamese.dyndns.org","threadId":"30655","inReplyTo":"20120604125126.GD27676@sigill.intra.peff.net","subject":"Re: [PATCH/RFC] improve no-op push output","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2012-06-04T16:35:30Z","receivedAt":"2012-06-04T16:35:30Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Jeff King <peff@peff.net> writes:\n\n> So I think we would really need to break down each potentially confusing\n> case, and come up with a solution for each. I think we can divide the\n> push configuration into three cases: matching, single (which includes\n> \"upstream\", \"simple\", and \"current\"), or custom refspecs. Let's ignore\n> the final one for now. It's relatively rare, and probably the most\n> common use is mirroring (in which case we know we pushed everything,\n> anyway). And then we have a few potential confusing situations:\n\nDoes \"single\" include \"upstream\", \"simple\" and \"current\", or does it\nconsists of these three and nothing else? I think it is the latter,\nand I mean the latter in the remainder of my response. Specifically,\nI would exclude the case where you have remote.$there.push that only\npushes one ref from \"single\".\n\n>   1. We are on a detached HEAD; the user expects their current work to\n>      be pushed, but it is not. With the \"single\" cases, we should\n>      already error out.\n\nAll the \"single\" cases should error out when run on a detached HEAD\n(otherwise they should be fixed).\n\nI have a feeling that it is not the best approach to classify the\n\"detached HEAD\" as a special failure mode for \"single\".  If you view\n\"single\" as \"push the curent branch out, but the name of the\ndestination ref may be different depending on the mode\", the\ndetached HEAD case is just a natural extension of the error case\n\"nothing is specified to be updated from this state, hence we error\nout\".\n\n>      For the \"matching\" case, we don't want to error\n>      out, but it might be worth printing a warning to say \"by the way,\n>      your HEAD is detached\", whether everything is up-to-date or not.\n\nBoth \"matching\" and \"specific remote.$there.push\" cases are \"it does\nnot matter what branch happens to be checked out; I am giving you\nthe set of refs I want to push out by default\", so even though you\nsaid you ignore the specific refspec case, they fall into the same\ncategory here.\n\nI find the above an unnecessarily roundabout way to help people who\nexpect the current branch to always be involved in an unnamed push\nto say \"your HEAD is detached\"; it requires them to be intelligent\nenough to connect \"HEAD detached\", \"no current branch\" and \"hence\nnothing pushed\".  A more direct way \"detached HEAD not pushed\" may\nbe better.\n\n>   2. We are on a branch; the user expects it to be pushed, but it is\n>      not. This can't happen with the \"single\" cases, since they always\n>      push HEAD (or fail). For matching, again, a solution might be \"by\n>      the way, your HEAD was not pushed\", with the same caveats as above.\n\nYes, \"by the way, your current branch was not pushed\" is much better\nthan \"HEAD is detached\" you wrote in 1.\n\n>   3. We are on a branch; the user expects some other branch X to be\n>      pushed, but it is not.\n>      ... So I think the right solution is to just\n>      be more specific; say \"X is up-to-date\", or just show the\n>      single-line status table.\n\nOK.\n\n>      For the \"matching\" case, it's much harder.\n>\n>      If we show them the whole description of what happened and hoping\n>      they notice that their branch is not included.  When something\n>      actually gets pushed, we show the status table already, and they\n>      may or may not look through it to find the branch in question\n>      (indeed, they may not even be trying to push X at the time, but\n>      rather may later say \"Hey, I thought I pushed everything; why is X\n>      not here?).\n\nWe can cover both the \"here are the list\" and the \"everything\nup-to-date\" cases with \"(current branch not pushed)\" (or \"detached\nHEAD not pushed)\".\n\n>   1. For a single-ref push, always mention the ref name, even if it is\n>      up-to-date. My previous patch showed the status table, but we could\n>      also just tweak the \"Everything up-to-date\" to say \"Ref X is\n>      up-to-date\".\n\nI think this is a sane thing to do in any case.\n\n>   2. Introduce a \"push.warnMatch\" config option, which can be set to one\n>      of:\n>\n>        - \"none\"; the current behavior\n>\n>        - \"branches\"; mention all unmatched refs which are in refs/heads\n\nDoesn't this assume that among many existing branches, what are not\npushed are minority (hence it is easier to spot the presense of the\ninteresting branch in the output, than to spot the absense of the\nlist of updated ones)? I am not convinced if that is the case, and I\ndoubt it would be very useful.\n\nAn alternative might be to show the usual list of refs with [up to date]\nmarks even when we currently say \"Everything up-to-date\", like \"push -v\"\ndoes.  I.e. instead of:\n\n        $ git push ko\n        Everything up-to-date\n\nwe can say\n\n\t$ git push ko\n\tTo: kernel.org:/pub/scm/git/git.git\n        = [up to date]      maint -> maint\n        = [up to date]      master -> master\n        = [up to date]      next -> next\n        = [up to date]      pu -> pu\n\nomitting \"Pushing to $where\" at the beginning and \"Everything up-to-date\"\nat the end of the \"push -v\" output.\n\n>        - \"head\"; mention the current HEAD if it is unmatched\n\nThis might be a sane thing to do unconditionally, especially if it\ncan be done without taking too much screen real estate.\n"},{"id":"192889","messageId":"20120605101019.GA30402@sigill.intra.peff.net","threadId":"30655","inReplyTo":"7vzk8jt4q5.fsf@alter.siamese.dyndns.org","subject":"Re: [PATCH/RFC] improve no-op push output","fromName":"Jeff King","fromEmail":"peff@peff.net","sentAt":"2012-06-05T10:10:19Z","receivedAt":"2012-06-05T10:10:19Z","isPatch":true,"sender":{"key":"peff@peff.net","avatar":"https://avatars.githubusercontent.com/u/45925?v=4"},"body":"On Mon, Jun 04, 2012 at 09:35:30AM -0700, Junio C Hamano wrote:\n\n> Jeff King <peff@peff.net> writes:\n> \n> > So I think we would really need to break down each potentially confusing\n> > case, and come up with a solution for each. I think we can divide the\n> > push configuration into three cases: matching, single (which includes\n> > \"upstream\", \"simple\", and \"current\"), or custom refspecs. Let's ignore\n> > the final one for now. It's relatively rare, and probably the most\n> > common use is mirroring (in which case we know we pushed everything,\n> > anyway). And then we have a few potential confusing situations:\n> \n> Does \"single\" include \"upstream\", \"simple\" and \"current\", or does it\n> consists of these three and nothing else? I think it is the latter,\n> and I mean the latter in the remainder of my response. Specifically,\n> I would exclude the case where you have remote.$there.push that only\n> pushes one ref from \"single\".\n\nYes, I think it is just those cases in my analysis (which is different\nfrom my original patch).  We can probably assume that somebody\nspecifying a refspec on the command line, or one with configured push\nrefspecs, would know what they are doing.\n\n> >   1. We are on a detached HEAD; the user expects their current work to\n> >      be pushed, but it is not. With the \"single\" cases, we should\n> >      already error out.\n> \n> All the \"single\" cases should error out when run on a detached HEAD\n> (otherwise they should be fixed).\n\nThey do (I just checked). However, \"current\" only fails because the\nright-hand-side HEAD is not fully qualified, and thus the message is\nsomewhat daunting:\n\n  error: unable to push to unqualified destination: HEAD\n  The destination refspec neither matches an existing ref on the remote\n  nor begins with refs/, and we are unable to guess a prefix based on\n  the source ref.\n  error: failed to push some refs to ...\n\nwhereas the simple/upstream case says:\n\n  fatal: You are not currently on a branch.\n  To push the history leading to the current (detached HEAD)\n  state now, use\n\n      git push github HEAD:<name-of-remote-branch>\n\nIt might be nicer for \"current\" to print the same message (the advice\nshould be identical in both cases).\n\n> >      For the \"matching\" case, we don't want to error\n> >      out, but it might be worth printing a warning to say \"by the way,\n> >      your HEAD is detached\", whether everything is up-to-date or not.\n> \n> Both \"matching\" and \"specific remote.$there.push\" cases are \"it does\n> not matter what branch happens to be checked out; I am giving you\n> the set of refs I want to push out by default\", so even though you\n> said you ignore the specific refspec case, they fall into the same\n> category here.\n\nYes, I think they do collapse to the same case. I omitted custom\nrefspecs out of simplicity in my analysis. But if they fall into the\nsame slots, then all the better.\n\n> I find the above an unnecessarily roundabout way to help people who\n> expect the current branch to always be involved in an unnamed push\n> to say \"your HEAD is detached\"; it requires them to be intelligent\n> enough to connect \"HEAD detached\", \"no current branch\" and \"hence\n> nothing pushed\".  A more direct way \"detached HEAD not pushed\" may\n> be better.\n\nAgreed. That is what I intended, but I obviously didn't say it very\nwell.\n\n> >   3. We are on a branch; the user expects some other branch X to be\n> >      pushed, but it is not.\n> >      ... So I think the right solution is to just\n> >      be more specific; say \"X is up-to-date\", or just show the\n> >      single-line status table.\n> [...]\n> >      For the \"matching\" case, it's much harder.\n> >\n> >      If we show them the whole description of what happened and hoping\n> >      they notice that their branch is not included.  When something\n> >      actually gets pushed, we show the status table already, and they\n> >      may or may not look through it to find the branch in question\n> >      (indeed, they may not even be trying to push X at the time, but\n> >      rather may later say \"Hey, I thought I pushed everything; why is X\n> >      not here?).\n> \n> We can cover both the \"here are the list\" and the \"everything\n> up-to-date\" cases with \"(current branch not pushed)\" (or \"detached\n> HEAD not pushed)\".\n\nThat helps with only the current branch. The point of this scenario is\nthat it is some random branch. Like:\n\n  git checkout topic\n  hack hack hack\n  git checkout master\n  hack hack hack\n  git -c push.default=matching push\n\nGit really has no way of knowing that it's interesting to you that\n\"topic\" didn't get pushed.\n\nThe right answer might be to simply discount this scenario. I think it's\nprobably less common than the \"I thought I was pushing my current HEAD\"\nconfusion which comes up.\n\n> >   1. For a single-ref push, always mention the ref name, even if it is\n> >      up-to-date. My previous patch showed the status table, but we could\n> >      also just tweak the \"Everything up-to-date\" to say \"Ref X is\n> >      up-to-date\".\n> \n> I think this is a sane thing to do in any case.\n\nHere, do you mean when there is a single ref attempted, or do you really\nmean \"when we invoked current, simple, or upstream push.default?\"\n\n> >   2. Introduce a \"push.warnMatch\" config option, which can be set to one\n> >      of:\n> >\n> >        - \"none\"; the current behavior\n> >\n> >        - \"branches\"; mention all unmatched refs which are in refs/heads\n> \n> Doesn't this assume that among many existing branches, what are not\n> pushed are minority (hence it is easier to spot the presense of the\n> interesting branch in the output, than to spot the absense of the\n> list of updated ones)? I am not convinced if that is the case, and I\n> doubt it would be very useful.\n\nYes, which is why it is configurable. For some workflows, you will push\nmost of your branches, and hold back only a few as private. In that\ncase, warning on unmatched branches would be helpful. For somebody like\nyou, pushing to ko would look awful, because you hold back all of the\ntopic branches (even though you push them elsewhere, it is not relevant\nto the ko \"matching\" push).\n\nSo I would certainly never make \"branches\" the default. I am somewhat\nlukewarm on it as a concept anyway; these possible directions were not\n\"we should definitely do this\" but just \"here is an initial sketch of\nsome ideas I had\".\n\n> An alternative might be to show the usual list of refs with [up to date]\n> marks even when we currently say \"Everything up-to-date\", like \"push -v\"\n> does.  I.e. instead of:\n> \n>         $ git push ko\n>         Everything up-to-date\n> \n> we can say\n> \n> \t$ git push ko\n> \tTo: kernel.org:/pub/scm/git/git.git\n>         = [up to date]      maint -> maint\n>         = [up to date]      master -> master\n>         = [up to date]      next -> next\n>         = [up to date]      pu -> pu\n> \n> omitting \"Pushing to $where\" at the beginning and \"Everything up-to-date\"\n> at the end of the \"push -v\" output.\n\nBut that has the opposite verbosity problem as above. If you have a lot\nof branches, most of which have not been updated, then we will print a\nlot of useless noise, hiding the actual interesting ref updates.\n\nIf you are proposing to do it only when everything is up-to-date, that\nis slightly better. In that case, you are not hiding real ref updates\namidst the noise. But it is still very noisy. And it does not really\naccomplish much, if your point is to show the user that the thing they\nmight have wanted to push was omitted.\n\n> >        - \"head\"; mention the current HEAD if it is unmatched\n> \n> This might be a sane thing to do unconditionally, especially if it\n> can be done without taking too much screen real estate.\n\nYeah. Of the three values, I would probably suggest \"head\" as the\ndefault. With \"none\" for people who want to say \"shut up git, I am fully\naware of how matching works\", and \"branches\" for people who want to be\nverbosely informed.\n\nBut if we drop the \"branches\" setting, and the message is unobtrusive,\nit may not be worth having it configurable at all.\n\n-Peff\n"}]}