{"thread":{"id":"57017","subject":"[RFC PATCH 0/1] making --set-upstream have default arguments","startedAt":"2021-12-02T14:45:32Z","lastAt":"2022-01-04T20:35:55Z","messageCount":21,"participants":["Abhradeep Chakraborty","Junio C Hamano","Philip Oakley","Eric Sunshine"],"isPatch":true,"patchVersion":1,"patchTotal":1},"messages":[{"id":"442867","messageId":"20211202144354.17416-1-chakrabortyabhradeep79@gmail.com","threadId":"57017","inReplyTo":null,"subject":"[RFC PATCH 0/1] making --set-upstream have default arguments","fromName":"Abhradeep Chakraborty","fromEmail":"chakrabortyabhradeep79@gmail.com","sentAt":"2021-12-02T14:43:53Z","receivedAt":"2021-12-02T14:45:32Z","isPatch":true,"sender":{"key":"chakrabortyabhradeep79@gmail.com","avatar":"https://avatars.githubusercontent.com/u/75240995?v=4"},"body":"To track a upstream branch from a local branch we need to pass\n<repository> and <refspec> to --set-upstream (in case of git push)\nor to --set-upstream-to (in case of git branch). In most cases,\nusers track the upstream branch with the same name as the local\nbranch they are currently on. For example, users most of the time\ndo 'git push <repository> <current_branch_refspec>'.\n\nSo, it would be great if 'git push -u' by default do this. This\npatch series address this. The patches of this patch-set set\nsome default values for <repository> and <refspec> if they are\nnot given. It first tries to get the value of <repository> from\n'branch.<current_branch>.remote'. If not then it will set the\nvalue of <repository> as 'origin'. <refspec>'s value would be\nthe short name of the current branch.\n\nThe first patch implements it for push command. However, before\nmoving to the 'git branch' part, it would be great to have\ndiscussions about the proposed changes in this patch and whether\nthe current changes are the best way to address it or not.\n\nAbhradeep Chakraborty (1):\n  push: make '-u' have default arguments\n\n Documentation/git-push.txt |  6 +++++\n builtin/push.c             | 48 ++++++++++++++++++++++++++++----------\n t/t5523-push-upstream.sh   | 11 +++++++++\n 3 files changed, 53 insertions(+), 12 deletions(-)\n\n-- \n2.17.1\n\n"},{"id":"442868","messageId":"20211202144354.17416-2-chakrabortyabhradeep79@gmail.com","threadId":"57017","inReplyTo":"20211202144354.17416-1-chakrabortyabhradeep79@gmail.com","subject":"[RFC PATCH 1/1] push: make '-u' have default arguments","fromName":"Abhradeep Chakraborty","fromEmail":"chakrabortyabhradeep79@gmail.com","sentAt":"2021-12-02T14:43:54Z","receivedAt":"2021-12-02T14:45:42Z","isPatch":true,"sender":{"key":"chakrabortyabhradeep79@gmail.com","avatar":"https://avatars.githubusercontent.com/u/75240995?v=4"},"body":"For now, -u in 'push' command requires two arguments (<repository>\nand <refspec>) to successfully track upstream branch. In most cases,\nusers want to set an upstream branch for the local branch they are\ncurrently on and the short names of these two branches are same in\nmost of the cases. There are plenty of configurations to set default\nbranches for push but again users can't run argumentless pull, rebase\netc. So it will be good to have '-u' having default arguments.\n\nThis commit gives ability to '-u' to have default arguments. 'git push\n-u' runs normally if <repository> and <refspec> are given. But\nif those are not given then it tries to get the value of <repository>\nfrom 'branch.<current_branch>.remote'. If not found, it sets 'origin'\nas the value of <repository>. <refspec> would be the current branch's\nshort name.\n\nHowever 'git push -u --all' work normally as before.\n\nSigned-off-by: Abhradeep Chakraborty <chakrabortyabhradeep79@gmail.com>\n---\n Documentation/git-push.txt |  6 +++++\n builtin/push.c             | 48 ++++++++++++++++++++++++++++----------\n t/t5523-push-upstream.sh   | 11 +++++++++\n 3 files changed, 53 insertions(+), 12 deletions(-)\n\ndiff --git a/Documentation/git-push.txt b/Documentation/git-push.txt\nindex 2f25aa3a29..e1a8b41818 100644\n--- a/Documentation/git-push.txt\n+++ b/Documentation/git-push.txt\n@@ -375,6 +375,12 @@ Specifying `--no-force-if-includes` disables this behavior.\n \tupstream (tracking) reference, used by argument-less\n \tlinkgit:git-pull[1] and other commands. For more information,\n \tsee `branch.<name>.merge` in linkgit:git-config[1].\n++\n+If you use -u without any arguments (i.e. no <repository> and <refspec>),\n+it will first try to get the <repository> from current branch's remote\n+configuration (i.e. from `branch.<name>.remote`). If not found, it will set\n+`origin` as the value of <repository> and <refspec> will be the current\n+branch's refspec.\n \n --[no-]thin::\n \tThese options are passed to linkgit:git-send-pack[1]. A thin transfer\ndiff --git a/builtin/push.c b/builtin/push.c\nindex 4b026ce6c6..2e417a06ad 100644\n--- a/builtin/push.c\n+++ b/builtin/push.c\n@@ -527,6 +527,25 @@ static int git_push_config(const char *k, const char *v, void *cb)\n \treturn git_default_config(k, v, NULL);\n }\n \n+static struct remote *pushremote_get_remote(const char *repo)\n+{\n+\tstruct remote *remote = pushremote_get(repo);\n+\tif (!remote) {\n+\t\tif (repo)\n+\t\t\tdie(_(\"bad repository '%s'\"), repo);\n+\t\tdie(_(\"No configured push destination.\\n\"\n+\t\t    \"Either specify the URL from the command-line or configure a remote repository using\\n\"\n+\t\t    \"\\n\"\n+\t\t    \"    git remote add <name> <url>\\n\"\n+\t\t    \"\\n\"\n+\t\t    \"and then push using the remote name\\n\"\n+\t\t    \"\\n\"\n+\t\t    \"    git push <name>\\n\"));\n+\t}\n+\n+\treturn remote;\n+}\n+\n int cmd_push(int argc, const char **argv, const char *prefix)\n {\n \tint flags = 0;\n@@ -537,6 +556,7 @@ int cmd_push(int argc, const char **argv, const char *prefix)\n \tstruct string_list push_options_cmdline = STRING_LIST_INIT_DUP;\n \tstruct string_list *push_options;\n \tconst struct string_list_item *item;\n+\tstruct remote *default_remote = NULL;\n \tstruct remote *remote;\n \n \tstruct option options[] = {\n@@ -603,23 +623,27 @@ int cmd_push(int argc, const char **argv, const char *prefix)\n \tif (tags)\n \t\trefspec_append(&rs, \"refs/tags/*\");\n \n+\tif ((argc == 0) && (flags & TRANSPORT_PUSH_SET_UPSTREAM) && !(flags & TRANSPORT_PUSH_ALL)) {\n+\t\tstruct branch *branch = branch_get(NULL);\n+\t\tif (branch) {\n+\t\t\targc += 2;\n+\t\t\tdefault_remote = pushremote_get_remote(repo);\n+\t\t\targv[0] = default_remote->name;\n+\t\t\targv[1] = branch->name;\n+\t\t}\n+\t}\n+\n \tif (argc > 0) {\n \t\trepo = argv[0];\n \t\tset_refspecs(argv + 1, argc - 1, repo);\n \t}\n \n-\tremote = pushremote_get(repo);\n-\tif (!remote) {\n-\t\tif (repo)\n-\t\t\tdie(_(\"bad repository '%s'\"), repo);\n-\t\tdie(_(\"No configured push destination.\\n\"\n-\t\t    \"Either specify the URL from the command-line or configure a remote repository using\\n\"\n-\t\t    \"\\n\"\n-\t\t    \"    git remote add <name> <url>\\n\"\n-\t\t    \"\\n\"\n-\t\t    \"and then push using the remote name\\n\"\n-\t\t    \"\\n\"\n-\t\t    \"    git push <name>\\n\"));\n+\tif (default_remote) {\n+\t\tremote = default_remote;\n+\t\tdefault_remote = NULL;\n+\t}\n+\telse {\n+\t\tremote = pushremote_get_remote(repo);\n \t}\n \n \tif (remote->mirror)\ndiff --git a/t/t5523-push-upstream.sh b/t/t5523-push-upstream.sh\nindex fdb4292056..69970b6263 100755\n--- a/t/t5523-push-upstream.sh\n+++ b/t/t5523-push-upstream.sh\n@@ -60,6 +60,17 @@ test_expect_success 'push -u :topic_2' '\n \tcheck_config topic_2 upstream refs/heads/other2\n '\n \n+test_expect_success 'push -u' '\n+\tgit push -u &&\n+\tcheck_config main upstream refs/heads/main\n+'\n+\n+test_expect_success 'push -u --dry-run' '\n+\tgit push -u upstream main:other &&\n+\tgit push -u --dry-run &&\n+\tcheck_config main upstream refs/heads/other\n+'\n+\n test_expect_success 'push -u --all' '\n \tgit branch all1 &&\n \tgit branch all2 &&\n-- \n2.17.1\n\n"},{"id":"442897","messageId":"xmqqbl1yvpa0.fsf@gitster.g","threadId":"57017","inReplyTo":"20211202144354.17416-2-chakrabortyabhradeep79@gmail.com","subject":"Re: [RFC PATCH 1/1] push: make '-u' have default arguments","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-12-02T18:24:07Z","receivedAt":"2021-12-02T18:24:15Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Abhradeep Chakraborty <chakrabortyabhradeep79@gmail.com> writes:\n\n> For now, -u in 'push' command requires two arguments (<repository>\n\nDrop \"For now\"; we start our log message by explaining the current\nsystem without the proposed change in the present tense, so it is\nunneeded.  Spelling out the option name \"--set-upstream\" in full, or\nat least \"-u\" in quotes, would make it more readable.\n\n> and <refspec>) to successfully track upstream branch. In most cases,\n> users want to set an upstream branch for the local branch they are\n> currently on and the short names of these two branches are same in\n> most of the cases.\n>\n> There are plenty of configurations to set default\n> branches for push but again users can't run argumentless pull, rebase\n> etc. So it will be good to have '-u' having default arguments.\n\nDon't judge what's \"most\" common without a survey.  A casual \"Often\"\nis acceptable.\n\nTaking all together, something like\n\n    \"git push -u\" (set-upstream) requires where to push to and what\n    to push.  Often people push only the current branch to update\n    the branch of the same name at the 'origin' repository.  For\n    them, it would be convenient if \"git push -u\" without repository\n    or refspec defaulted to push to the branch of the same name at\n    the remote repository that is used by default.\n\n> This commit gives ability to '-u' to have default arguments. 'git push\n\ncf. Documentation/SubmittingPatches[[imperative-mood]]\n\n> -u' runs normally if <repository> and <refspec> are given. But\n> if those are not given then it tries to get the value of <repository>\n> from 'branch.<current_branch>.remote'. If not found, it sets 'origin'\n> as the value of <repository>. <refspec> would be the current branch's\n> short name.\n\nDo not invent an undefined word \"short name\".  The name of the\n'main' branch is 'main', and it is not a short name.  When people\nencounter multi-level names, like ac/push-u-default, use of an\nundefined word \"short name\" will mislead readers that you meant\nthe leaf level, 'push-u-default', but I do not think that is what\nyou meant (this is not the only instance of \"short name\" in this\nsubmission; all need to be fixed).\n\n> However 'git push -u --all' work normally as before.\n\nIs this even necessary?  --all is to push all branches to the\ndefault repository, so clearly it is outside the \"we need default\nbecause the user did not tell us what to push to where\" case.\n\nTaking the above together, perhaps something along this line,\n\n    Teach \"git push -u\" not to require repository and refspec.  When\n    the user did not give what repository to push to, or which\n    branch(es) to push, behave as if the default remote repository\n    and the name of the current branch are given.  Note that use of\n    \"--all\" option, together with \"-u\", behaves as before, since the\n    user is telling us to push all the branches to the default\n    remote repository and there is no need for this new behaviour to\n    kick in.\n\nperhaps?\n\nOne thing that bothers me is that unlike your assumption, not\neverybody uses push.default set to simple or upstream.  I am not\nconvinced that the \"git push -u\" that defaults to do the 'current'\npush with TRANSPORT_PUSH_SET_UPSTREAM for them is an improvement\nfor them.  If the new feature does not kick in for them, that should\nbe explained in the proposed log message when you sell the patch to\nreviewers and documented for the users.\n\n> @@ -375,6 +375,12 @@ Specifying `--no-force-if-includes` disables this behavior.\n>  \tupstream (tracking) reference, used by argument-less\n>  \tlinkgit:git-pull[1] and other commands. For more information,\n>  \tsee `branch.<name>.merge` in linkgit:git-config[1].\n> ++\n> +If you use -u without any arguments (i.e. no <repository> and <refspec>),\n\nBe careful to quote `-u` and things like that by studyng the text\naround what you are changing.\n\n> +it will first try to get the <repository> from current branch's remote\n> +configuration (i.e. from `branch.<name>.remote`). If not found, it will set\n> +`origin` as the value of <repository> and <refspec> will be the current\n> +branch's refspec.\n\nThis makes it sound as if the push will only affect the current\nbranch even for folks who use the matching push.  As I said, I do\nnot know if that is desirable.\n\n> diff --git a/builtin/push.c b/builtin/push.c\n> index 4b026ce6c6..2e417a06ad 100644\n> --- a/builtin/push.c\n> +++ b/builtin/push.c\n> @@ -527,6 +527,25 @@ static int git_push_config(const char *k, const char *v, void *cb)\n>  \treturn git_default_config(k, v, NULL);\n>  }\n>  \n> +static struct remote *pushremote_get_remote(const char *repo)\n> +{\n> +\tstruct remote *remote = pushremote_get(repo);\n> +\tif (!remote) {\n> +\t\tif (repo)\n> +\t\t\tdie(_(\"bad repository '%s'\"), repo);\n> +\t\tdie(_(\"No configured push destination.\\n\"\n> +\t\t    \"Either specify the URL from the command-line or configure a remote repository using\\n\"\n> +\t\t    \"\\n\"\n> +\t\t    \"    git remote add <name> <url>\\n\"\n> +\t\t    \"\\n\"\n> +\t\t    \"and then push using the remote name\\n\"\n> +\t\t    \"\\n\"\n> +\t\t    \"    git push <name>\\n\"));\n> +\t}\n> +\n> +\treturn remote;\n> +}\n> +\n>  int cmd_push(int argc, const char **argv, const char *prefix)\n>  {\n>  \tint flags = 0;\n> @@ -537,6 +556,7 @@ int cmd_push(int argc, const char **argv, const char *prefix)\n>  \tstruct string_list push_options_cmdline = STRING_LIST_INIT_DUP;\n>  \tstruct string_list *push_options;\n>  \tconst struct string_list_item *item;\n> +\tstruct remote *default_remote = NULL;\n>  \tstruct remote *remote;\n>  \n>  \tstruct option options[] = {\n> @@ -603,23 +623,27 @@ int cmd_push(int argc, const char **argv, const char *prefix)\n>  \tif (tags)\n>  \t\trefspec_append(&rs, \"refs/tags/*\");\n>  \n> +\tif ((argc == 0) && (flags & TRANSPORT_PUSH_SET_UPSTREAM) && !(flags & TRANSPORT_PUSH_ALL)) {\n> +\t\tstruct branch *branch = branch_get(NULL);\n> +\t\tif (branch) {\n> +\t\t\targc += 2;\n> +\t\t\tdefault_remote = pushremote_get_remote(repo);\n> +\t\t\targv[0] = default_remote->name;\n> +\t\t\targv[1] = branch->name;\n\nThis does look like it breaks unless the user is a novice without\ncustom configuration.  For example, if the current branch has a\nconfiguration to integrate with a branch at the default remote of a\ndifferent name already, this (1) clobbers the tip of a wrong branch\nby pushing to it, and (2) overrites the upstream configuration.  If\nthe user uses push.default set to 'current' or 'simple', this would\nbe OK, but for all other users, I doubt this would be an improvement.\n\n\n> diff --git a/t/t5523-push-upstream.sh b/t/t5523-push-upstream.sh\n> index fdb4292056..69970b6263 100755\n> --- a/t/t5523-push-upstream.sh\n> +++ b/t/t5523-push-upstream.sh\n> @@ -60,6 +60,17 @@ test_expect_success 'push -u :topic_2' '\n>  \tcheck_config topic_2 upstream refs/heads/other2\n>  '\n>  \n> +test_expect_success 'push -u' '\n\nWe may want to future-proof by checking the current tracking info\n(or lack of it) before doing \"git push -u\" here?  You cannot control\nwhat other developers would do in the future to tests before this\none.\n\n> +\tgit push -u &&\n> +\tcheck_config main upstream refs/heads/main\n> +'\n\nAnd we make sure \"-u\" without the repository or branch works\nin the basic case, which is a good \"positive\" test.\n\n> +test_expect_success 'push -u --dry-run' '\n> +\tgit push -u upstream main:other &&\n> +\tgit push -u --dry-run &&\n> +\tcheck_config main upstream refs/heads/other\n> +'\n\nThis verifies that under '--dry-run' the upstream configuration does\nnot get changed.  It is a good \"negative\" test to have, but there\nprobably are a lot more \"negative\" tests to ensure that the new\nfeature does not kick in in cases where it should not.  Various\nsettings of push.default is probably a good place to start and with\nor without existing upstream info already set up.\n\nThanks for working on this topic.  I suspect that the implementation\nand design covers too broadly to hurt some users while helping\nothers, and needs tightening up to fix that, but I think the users\nappreciate the part that helps some users ;-)\n"},{"id":"442948","messageId":"20211203081446.17596-1-chakrabortyabhradeep79@gmail.com","threadId":"57017","inReplyTo":"xmqqbl1yvpa0.fsf@gitster.g","subject":"Re: [RFC PATCH 1/1] push: make '-u' have default arguments","fromName":"Abhradeep Chakraborty","fromEmail":"chakrabortyabhradeep79@gmail.com","sentAt":"2021-12-03T08:14:46Z","receivedAt":"2021-12-03T08:18:00Z","isPatch":true,"sender":{"key":"chakrabortyabhradeep79@gmail.com","avatar":"https://avatars.githubusercontent.com/u/75240995?v=4"},"body":"Junio C Hamano <gitster@pobox.com> wrote:\n\n> Taking all together, something like\n>\n>    \"git push -u\" (set-upstream) requires where to push to and what\n>    to push.  Often people push only the current branch to update\n>    the branch of the same name at the 'origin' repository.  For\n>    them, it would be convenient if \"git push -u\" without repository\n>    or refspec defaulted to push to the branch of the same name at\n>    the remote repository that is used by default.\n\nThanks for the guidance. Improving the cover-letter and commit message\nnow. :)\n\n> Do not invent an undefined word \"short name\".  The name of the\n> 'main' branch is 'main', and it is not a short name.  When people\n> encounter multi-level names, like ac/push-u-default, use of an\n> undefined word \"short name\" will mislead readers that you meant\n> the leaf level, 'push-u-default', but I do not think that is what\n> you meant (this is not the only instance of \"short name\" in this\n> submission; all need to be fixed).\n\nSorry for that, I was referring 'branch->name' as 'short name' (and\n'branch->refname' as the 'long name' :| ). Will fix it.\n\n> One thing that bothers me is that unlike your assumption, not\n> everybody uses push.default set to simple or upstream.  I am not\n> convinced that the \"git push -u\" that defaults to do the 'current'\n> push with TRANSPORT_PUSH_SET_UPSTREAM for them is an improvement\n> for them.\n\nMay be you're right. It may not be an improvement for all. But I\nthink they also would be happy seeing this 'default' case of \n'set-upstream'.\n\n> If the new feature does not kick in for them, that should\n> be explained in the proposed log message when you sell the patch to\n> reviewers and documented for the users.\n\nOk.\n\n> This makes it sound as if the push will only affect the current\n> branch even for folks who use the matching push.  As I said, I do\n> not know if that is desirable.\n\nYeah, this only affects the current branch. In that case they may\nnot use 'git push -u'. As you said previously, this would not be\nan improvement in this case ( not a deterioration also).\n\n> This does look like it breaks unless the user is a novice without\n> custom configuration.  For example, if the current branch has a\n> configuration to integrate with a branch at the default remote of a\n> different name already, this (1) clobbers the tip of a wrong branch\n> by pushing to it, and (2) overrites the upstream configuration.  If\n> the user uses push.default set to 'current' or 'simple', this would\n> be OK, but for all other users, I doubt this would be an improvement.\n\nI don't think so. When an user use '--set-upstream' in push command,\nit means he/she want to set the upstream to a different branch (if\nthe specified <repository> and <refspec> are not same as the current\none) rather than the current upstream branch (if exists). So, I think\nit would be safe for '--set-upstream' to have default values. Isn't it?\nIf you are fearing for those two points you specified, should we add\na safety permission before proceeding? e.g. like this -\n \n     this would change the upstream branch \"%s\" to \"%s\" for this local branch\n     would you like to continue? [y]es [n]no\n\n> We may want to future-proof by checking the current tracking info\n> (or lack of it) before doing \"git push -u\" here?  You cannot control\n> what other developers would do in the future to tests before this\n> one.\n\nOh yeah, you're right. Will surely add it.\n\n> Various settings of push.default is probably a good place to start and\n> with or without existing upstream info already set up.\n\nThanks for the suggestion, I will add more tests to address these things.\n\n> Thanks for working on this topic.  I suspect that the implementation\n> and design covers too broadly to hurt some users while helping\n> others, and needs tightening up to fix that, but I think the users\n> appreciate the part that helps some users ;-)\n\nThanks.\n"},{"id":"442969","messageId":"b9bfd60b-9e4e-caa6-9836-e0f0e984a997@iee.email","threadId":"57017","inReplyTo":"20211202144354.17416-1-chakrabortyabhradeep79@gmail.com","subject":"Re: [RFC PATCH 0/1] making --set-upstream have default arguments","fromName":"Philip Oakley","fromEmail":"philipoakley@iee.email","sentAt":"2021-12-03T11:32:25Z","receivedAt":"2021-12-03T11:32:28Z","isPatch":true,"sender":{"key":"philipoakley@iee.email","avatar":"https://avatars.githubusercontent.com/u/914343?v=4"},"body":"On 02/12/2021 14:43, Abhradeep Chakraborty wrote:\n> To track a upstream branch from a local branch we need to pass\n> <repository> and <refspec> to --set-upstream (in case of git push)\n> or to --set-upstream-to (in case of git branch). In most cases,\n> users track the upstream branch with the same name as the local\n> branch they are currently on. For example, users most of the time\n> do 'git push <repository> <current_branch_refspec>'.\n>\n> So, it would be great if 'git push -u' by default do this. This\n> patch series address this. The patches of this patch-set set\n> some default values for <repository> and <refspec> if they are\n> not given. It first tries to get the value of <repository> from\n> 'branch.<current_branch>.remote'. If not then it will set the\n> value of <repository> as 'origin'. <refspec>'s value would be\n> the short name of the current branch.\n\nCan we protect the expectations of a user with a `pushDefault` setting?\nIf the user has one set, then the upstream won't be where they push in a\ntriangular repo workflow.\n\nPhilip\n>\n> The first patch implements it for push command. However, before\n> moving to the 'git branch' part, it would be great to have\n> discussions about the proposed changes in this patch and whether\n> the current changes are the best way to address it or not.\n>\n> Abhradeep Chakraborty (1):\n>   push: make '-u' have default arguments\n>\n>  Documentation/git-push.txt |  6 +++++\n>  builtin/push.c             | 48 ++++++++++++++++++++++++++++----------\n>  t/t5523-push-upstream.sh   | 11 +++++++++\n>  3 files changed, 53 insertions(+), 12 deletions(-)\n>\n\n"},{"id":"443006","messageId":"20211203160346.18221-1-chakrabortyabhradeep79@gmail.com","threadId":"57017","inReplyTo":"b9bfd60b-9e4e-caa6-9836-e0f0e984a997@iee.email","subject":"Re: [RFC PATCH 0/1] making --set-upstream have default arguments","fromName":"Abhradeep Chakraborty","fromEmail":"chakrabortyabhradeep79@gmail.com","sentAt":"2021-12-03T16:03:46Z","receivedAt":"2021-12-03T16:06:00Z","isPatch":true,"sender":{"key":"chakrabortyabhradeep79@gmail.com","avatar":"https://avatars.githubusercontent.com/u/75240995?v=4"},"body":"Philip Oakley wrote:\n\n> Can we protect the expectations of a user with a `pushDefault` setting?\n\nAre you talking about 'push.default'? If so, then I think, the proposed\nchange would not affect the working of 'push.default' (if the idea is\nimplemented in the right way). I am adding tests to be sure about it. \n\n> If the user has one set, then the upstream won't be where they push in a\n> triangular repo workflow.\n\nPardon me, I am unable to understand what you are trying to say. Could you\nplease explain a little bit?\n\nThanks.\n\n"},{"id":"443008","messageId":"90007c1b-9183-d7f4-f7d0-6a90c5f6e247@iee.email","threadId":"57017","inReplyTo":"20211203160346.18221-1-chakrabortyabhradeep79@gmail.com","subject":"Re: [RFC PATCH 0/1] making --set-upstream have default arguments","fromName":"Philip Oakley","fromEmail":"philipoakley@iee.email","sentAt":"2021-12-03T16:46:17Z","receivedAt":"2021-12-03T16:46:20Z","isPatch":true,"sender":{"key":"philipoakley@iee.email","avatar":"https://avatars.githubusercontent.com/u/914343?v=4"},"body":"On 03/12/2021 16:03, Abhradeep Chakraborty wrote:\n> Philip Oakley wrote:\n>\n>> Can we protect the expectations of a user with a `pushDefault` setting?\n> Are you talking about 'push.default'? If so, then I think, the proposed\n> change would not affect the working of 'push.default' (if the idea is\n> implemented in the right way). I am adding tests to be sure about it. \n>\n>> If the user has one set, then the upstream won't be where they push in a\n>> triangular repo workflow.\n> Pardon me, I am unable to understand what you are trying to say. Could you\n> please explain a little bit?\n>\n> Thanks.\n>\nIn my scenario I am tracking various upstream repositories, none of\nwhich I have push permission for. This means I have set up a\n`remote.pushDefault` [1] to the remote \"my\", which is mapped to my\nGitHub repo where I can publish work (i.e. push). \n\nSo when I push, I am pushing to \"my\" remote, but when rebasing, the\nupstream is not that destination, and in a collaboration environment,\nmay not even be the place I first forked from (e.g. the distinction\nbetween 'git.git' [git], 'git-for-windows.git' [gfw], and Junio's repo\n[gitster], all with the same root). I can then either send PRs (if\nacceptable) or send patches (cover letter link to my publish repo).\n\nIn the case where a user has set their remote.pushDefault, then it's not\nclear that there should be a default at all, though I maybe\nmisunderstanding the approach here.\n\nPhilip\n\n[1]\nhttps://git-scm.com/docs/git-config#Documentation/git-config.txt-remotepushDefault\n"},{"id":"443011","messageId":"20211203172819.18343-1-chakrabortyabhradeep79@gmail.com","threadId":"57017","inReplyTo":"b9bfd60b-9e4e-caa6-9836-e0f0e984a997@iee.email","subject":"Re: [RFC PATCH 0/1] making --set-upstream have default arguments","fromName":"Abhradeep Chakraborty","fromEmail":"chakrabortyabhradeep79@gmail.com","sentAt":"2021-12-03T17:28:19Z","receivedAt":"2021-12-03T17:29:04Z","isPatch":true,"sender":{"key":"chakrabortyabhradeep79@gmail.com","avatar":"https://avatars.githubusercontent.com/u/75240995?v=4"},"body":"Philip Oakley wrote:\n\n> Can we protect the expectations of a user with a `pushDefault` setting? \n> If the user has one set, then the upstream won't be where they push in a\n> triangular repo workflow.\n\nOhh, sorry! now I understand. You are talking about 'remote.pushDefault'.\nI didn't think about it. Checking if the proposed change is affecting it.\nThanks for pointing out!\n"},{"id":"443012","messageId":"xmqqtufpsikp.fsf@gitster.g","threadId":"57017","inReplyTo":"20211203081446.17596-1-chakrabortyabhradeep79@gmail.com","subject":"Re: [RFC PATCH 1/1] push: make '-u' have default arguments","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2021-12-03T17:29:26Z","receivedAt":"2021-12-03T17:29:31Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Abhradeep Chakraborty <chakrabortyabhradeep79@gmail.com> writes:\n\n>> One thing that bothers me is that unlike your assumption, not\n>> everybody uses push.default set to simple or upstream.  I am not\n>> convinced that the \"git push -u\" that defaults to do the 'current'\n>> push with TRANSPORT_PUSH_SET_UPSTREAM for them is an improvement\n>> for them.\n>\n> May be you're right. It may not be an improvement for all. But I\n> think they also would be happy seeing this 'default' case of \n> 'set-upstream'.\n\nNot at all.  \n\nThe argument for the \"good\" case is for \"simple\" or \"current\" users,\nthey want their \"git push\" without repo and branch arguments to\npush their current branch to the branch with the same name at the\ndefault remote repository, and if we arrange \"git push -u\" to do the\nsameand set up \"branch.$current.merge\", they will find it convenient.\n\nThe same reasoning applies for other users who do *not* want their\n\"git push\" without repo and branch arguments to push as if they are\ndoing the push.default=current push.  If we make \"git push -u\" push\nthe current (and only the current) branch to the branch of the same\nname at the default remote repository by overwriting argv[] like the\npatch under discussion does, we would be giving these users a\nconvenient way to do what they do not want to do.  Besides, I think\nwith the current code\n\n    $ git -c push.default=matching push -u\n\nalready does the right thing by pushing the matching branches and\nsets up upstream for the branches that get pushed without the patch\nin question.  With the patch, because it blindly mucks with argv[]\nto force pushing only the current branch to the default remote, the\nestablished expectation by existing users is broken.\n\nThat of course is not an improvement but actively hurts them.  We\nshouldn't be making it easier for our users to hurt themselves.\n\nSo, no.  The patch in its current form is totally unacceptable.\n\nShouldn't the rule be something like \"if 'git push $args' (where\n$args may be nothing, or any options other than '-u') pushes a\nbranch (or a set of branches) to a repository, 'git push -u $args'\n(with the same $args) should set the branch.*.{remote,merge} for the\nbranch(es) to the same repository\" for the introduction of default\nto be truly an improvement?  Or is it too strict and makes the rule\nnot to trigger even for the intended audience?\n"},{"id":"443018","messageId":"20211203192716.18444-1-chakrabortyabhradeep79@gmail.com","threadId":"57017","inReplyTo":"xmqqtufpsikp.fsf@gitster.g","subject":"Re: [RFC PATCH 1/1] push: make '-u' have default arguments","fromName":"Abhradeep Chakraborty","fromEmail":"chakrabortyabhradeep79@gmail.com","sentAt":"2021-12-03T19:27:16Z","receivedAt":"2021-12-03T19:27:46Z","isPatch":true,"sender":{"key":"chakrabortyabhradeep79@gmail.com","avatar":"https://avatars.githubusercontent.com/u/75240995?v=4"},"body":"Junio C Hamano <gitster@pobox.com> wrote:\n\n> That of course is not an improvement but actively hurts them.  We\n> shouldn't be making it easier for our users to hurt themselves.\n\nHmm. In the scenario you mentioned, the proposed change is clearly\nbreaking. Thanks for notifying.\n\n> Shouldn't the rule be something like \"if 'git push $args' (where\n> $args may be nothing, or any options other than '-u') pushes a\n> branch (or a set of branches) to a repository, 'git push -u $args'\n> (with the same $args) should set the branch.*.{remote,merge} for the\n> branch(es) to the same repository\" for the introduction of default\n> to be truly an improvement?  Or is it too strict and makes the rule\n> not to trigger even for the intended audience?\n\nSounds good to me. But what if 'push.default' set to 'nothing'? Do the\nproposed default arguments (I am saying about only the default arguments;\nnot the changes in code) are right fit for that case?\n"},{"id":"443324","messageId":"20211207182300.4361-1-chakrabortyabhradeep79@gmail.com","threadId":"57017","inReplyTo":"20211202144354.17416-1-chakrabortyabhradeep79@gmail.com","subject":"[PATCH v2 0/1] making --set-upstream have default arguments","fromName":"Abhradeep Chakraborty","fromEmail":"chakrabortyabhradeep79@gmail.com","sentAt":"2021-12-07T18:22:59Z","receivedAt":"2021-12-07T18:23:48Z","isPatch":true,"sender":{"key":"chakrabortyabhradeep79@gmail.com","avatar":"https://avatars.githubusercontent.com/u/75240995?v=4"},"body":"The changes regarding 'git push -u' in the previous patch version\nwere hurting the intention of using 'push.default'. This patch version\nfixes that.\n\nArgumentless 'git push -u' sets the default remote as '<repository>'.\n'<refspec>' depends on the 'push.default' configuration. For\n'push.default'=matching, it pushes refs to those branches that it\nshould and sets them as the upstream of their respective local\nbranches. For all other values of 'push.default', it uses the\ncurrent branch for the refspec.\n\n'<repository>' value depends on 'branch.*.remote' and 'remote.pushDefault'\n(if 'branch.*.remote' not found). If none of them are set then it\ndefaults to 'origin'.\n\nAbhradeep Chakraborty (1):\n  push: make '-u' have default arguments\n\n Documentation/git-push.txt |  10 ++++\n builtin/push.c             |  11 +++-\n t/t5523-push-upstream.sh   | 114 +++++++++++++++++++++++++++++++++++++\n 3 files changed, 133 insertions(+), 2 deletions(-)\n\n-- \n2.17.1\n\n"},{"id":"443325","messageId":"20211207182300.4361-2-chakrabortyabhradeep79@gmail.com","threadId":"57017","inReplyTo":"20211207182300.4361-1-chakrabortyabhradeep79@gmail.com","subject":"[PATCH v2 1/1] push: make '-u' have default arguments","fromName":"Abhradeep Chakraborty","fromEmail":"chakrabortyabhradeep79@gmail.com","sentAt":"2021-12-07T18:23:00Z","receivedAt":"2021-12-07T18:23:57Z","isPatch":true,"sender":{"key":"chakrabortyabhradeep79@gmail.com","avatar":"https://avatars.githubusercontent.com/u/75240995?v=4"},"body":"\"git push -u\" (set-upstream) requires where to push to and what\nto push.  Often people push only the current branch to update\nthe branch of the same name at the 'origin' repository.  For\nthem, it would be convenient if \"git push -u\" without repository\nor refspec, defaulted to push and set upstream to the branch as\nconfigured by the \"push.default\" setting, of the remote repository\nthat is used by default.\n\nTeach \"git push -u\" not to require repository and refspec.  When\nthe user do not give what repository to push to, or which\nbranch(es) to push, behave as if the default remote repository\nand a refspec (depending on the \"push.default\" configuration)\nare given.\n\nIf \"push.default\"=matching, push all the branches matched on both\nremote and local side and set those remote branches as the upstream\nof their respective local matched branches. Otherwise, set the\nrefspec to the refspec for current branch.\n\nSigned-off-by: Abhradeep Chakraborty <chakrabortyabhradeep79@gmail.com>\n---\n Documentation/git-push.txt |  10 ++++\n builtin/push.c             |  11 +++-\n t/t5523-push-upstream.sh   | 114 +++++++++++++++++++++++++++++++++++++\n 3 files changed, 133 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/git-push.txt b/Documentation/git-push.txt\nindex 2f25aa3a29..048c087e23 100644\n--- a/Documentation/git-push.txt\n+++ b/Documentation/git-push.txt\n@@ -375,6 +375,16 @@ Specifying `--no-force-if-includes` disables this behavior.\n \tupstream (tracking) reference, used by argument-less\n \tlinkgit:git-pull[1] and other commands. For more information,\n \tsee `branch.<name>.merge` in linkgit:git-config[1].\n++\n+`-u` can also work with zero arguments( i.e. no `<repository>` and\n+`<refspec>` are given). In that case, it tries to get the `<repository>`\n+value from `branch.*.remote` configuration. If not found, it defaults to\n+`origin`. If `remote.pushDefault` is set then it uses that instead. The\n+value of `<refspec>` depends on the current `push.default` configuration.\n+If `push.default` is set to `matching`, all remote branches to which\n+local branches pushed, will be set as upstream of respective local\n+branches. For all other values of `push.default`, current branch's\n+`<refspec>` will be used as the `<refspec>`.\n \n --[no-]thin::\n \tThese options are passed to linkgit:git-send-pack[1]. A thin transfer\ndiff --git a/builtin/push.c b/builtin/push.c\nindex 4b026ce6c6..8bc206c9d8 100644\n--- a/builtin/push.c\n+++ b/builtin/push.c\n@@ -202,11 +202,12 @@ static const char *get_upstream_ref(struct branch *branch, const char *remote_na\n \treturn branch->merge[0]->src;\n }\n \n-static void setup_default_push_refspecs(struct remote *remote)\n+static void setup_default_push_refspecs(struct remote *remote, int flags)\n {\n \tstruct branch *branch;\n \tconst char *dst;\n \tint same_remote;\n+\tint is_default_u = (flags & TRANSPORT_PUSH_SET_UPSTREAM);\n \n \tswitch (push_default) {\n \tcase PUSH_DEFAULT_MATCHING:\n@@ -214,6 +215,8 @@ static void setup_default_push_refspecs(struct remote *remote)\n \t\treturn;\n \n \tcase PUSH_DEFAULT_NOTHING:\n+\t\tif (is_default_u)\n+\t\t\tbreak;\n \t\tdie(_(\"You didn't specify any refspecs to push, and \"\n \t\t    \"push.default is \\\"nothing\\\".\"));\n \t\treturn;\n@@ -234,11 +237,15 @@ static void setup_default_push_refspecs(struct remote *remote)\n \tcase PUSH_DEFAULT_SIMPLE:\n \t\tif (!same_remote)\n \t\t\tbreak;\n+\t\tif (is_default_u)\n+\t\t\tbreak;\n \t\tif (strcmp(branch->refname, get_upstream_ref(branch, remote->name)))\n \t\t\tdie_push_simple(branch, remote);\n \t\tbreak;\n \n \tcase PUSH_DEFAULT_UPSTREAM:\n+\t\tif (is_default_u)\n+\t\t\tbreak;\n \t\tif (!same_remote)\n \t\t\tdie(_(\"You are pushing to remote '%s', which is not the upstream of\\n\"\n \t\t\t      \"your current branch '%s', without telling me what to push\\n\"\n@@ -401,7 +408,7 @@ static int do_push(int flags,\n \t\tif (remote->push.nr) {\n \t\t\tpush_refspec = &remote->push;\n \t\t} else if (!(flags & TRANSPORT_PUSH_MIRROR))\n-\t\t\tsetup_default_push_refspecs(remote);\n+\t\t\tsetup_default_push_refspecs(remote, flags);\n \t}\n \terrs = 0;\n \turl_nr = push_url_of_remote(remote, &url);\ndiff --git a/t/t5523-push-upstream.sh b/t/t5523-push-upstream.sh\nindex fdb4292056..fbcdf303ef 100755\n--- a/t/t5523-push-upstream.sh\n+++ b/t/t5523-push-upstream.sh\n@@ -60,6 +60,75 @@ test_expect_success 'push -u :topic_2' '\n \tcheck_config topic_2 upstream refs/heads/other2\n '\n \n+default_u_setup() {\n+\tgit checkout main\n+\tremote=$(git config --get branch.main.remote)\n+\tif [ ! -z \"$remote\" ]; then\n+\t\tgit branch --unset-upstream\n+\tfi\n+\tgit config push.default $1\n+\tgit config remote.pushDefault upstream\n+}\n+\n+test_expect_success 'push -u with push.default=simple' '\n+\tdefault_u_setup simple &&\n+\tgit push -u &&\n+\tcheck_config main upstream refs/heads/main &&\n+\tgit push -u upstream main:other &&\n+\tgit push -u &&\n+\tcheck_config main upstream refs/heads/main\n+'\n+\n+test_expect_success 'push -u with push.default=current' '\n+\tdefault_u_setup current &&\n+\tgit push -u &&\n+\tcheck_config main upstream refs/heads/main &&\n+\tgit push -u upstream main:other &&\n+\tgit push -u &&\n+\tcheck_config main upstream refs/heads/main\n+'\n+\n+test_expect_success 'push -u with push.default=upstream' '\n+\tdefault_u_setup upstream &&\n+\tgit push -u &&\n+\tcheck_config main upstream refs/heads/main &&\n+\tgit push -u upstream main:other &&\n+\tgit push -u &&\n+\tcheck_config main upstream refs/heads/main\n+'\n+\n+check_empty_config() {\n+\ttest_expect_code 1 git config \"branch.$1.remote\"\n+\ttest_expect_code 1 git config \"branch.$1.merge\"\n+}\n+\n+test_expect_success 'push -u with push.default=matching' '\n+\tdefault_u_setup matching &&\n+\tgit branch test_u &&\n+\tgit branch test_u2 &&\n+\tgit push upstream main:test_u2 &&\n+\tgit push -u &&\n+\tcheck_config main upstream refs/heads/main &&\n+\tcheck_config test_u2 upstream refs/heads/test_u2 &&\n+\tcheck_empty_config test_u\n+'\n+\n+test_expect_success 'push -u with push.default=nothing' '\n+\tdefault_u_setup nothing &&\n+\tgit push -u &&\n+\tcheck_config main upstream refs/heads/main &&\n+\tgit push -u upstream main:other &&\n+\tgit push -u &&\n+\tcheck_config main upstream refs/heads/main\n+'\n+\n+test_expect_success 'push -u --dry-run' '\n+\tgit checkout main &&\n+\tgit push -u upstream main:other &&\n+\tgit push -u --dry-run &&\n+\tcheck_config main upstream refs/heads/other\n+'\n+\n test_expect_success 'push -u --all' '\n \tgit branch all1 &&\n \tgit branch all2 &&\n@@ -81,6 +150,13 @@ test_expect_success TTY 'progress messages go to tty' '\n \ttest_i18ngrep \"Writing objects\" err\n '\n \n+test_expect_success TTY 'progress messages go to tty with default -u' '\n+\tensure_fresh_upstream &&\n+\n+\ttest_terminal git push -u >out 2>err &&\n+\ttest_i18ngrep \"Writing objects\" err\n+'\n+\n test_expect_success 'progress messages do not go to non-tty' '\n \tensure_fresh_upstream &&\n \n@@ -89,6 +165,14 @@ test_expect_success 'progress messages do not go to non-tty' '\n \ttest_i18ngrep ! \"Writing objects\" err\n '\n \n+test_expect_success 'progress messagesdo not go to non-tty (default -u)' '\n+\tensure_fresh_upstream &&\n+\n+\t# skip progress messages, since stderr is non-tty\n+\tgit push -u >out 2>err &&\n+\ttest_i18ngrep ! \"Writing objects\" err\n+'\n+\n test_expect_success 'progress messages go to non-tty (forced)' '\n \tensure_fresh_upstream &&\n \n@@ -97,6 +181,14 @@ test_expect_success 'progress messages go to non-tty (forced)' '\n \ttest_i18ngrep \"Writing objects\" err\n '\n \n+test_expect_success 'progress messages go to non-tty with default -u (forced)' '\n+\tensure_fresh_upstream &&\n+\n+\t# force progress messages to stderr, even though it is non-tty\n+\tgit push -u --progress >out 2>err &&\n+\ttest_i18ngrep \"Writing objects\" err\n+'\n+\n test_expect_success TTY 'push -q suppresses progress' '\n \tensure_fresh_upstream &&\n \n@@ -104,6 +196,13 @@ test_expect_success TTY 'push -q suppresses progress' '\n \ttest_i18ngrep ! \"Writing objects\" err\n '\n \n+test_expect_success TTY 'push -q suppresses progress (with default -u)' '\n+\tensure_fresh_upstream &&\n+\n+\ttest_terminal git push -u -q >out 2>err &&\n+\ttest_i18ngrep ! \"Writing objects\" err\n+'\n+\n test_expect_success TTY 'push --no-progress suppresses progress' '\n \tensure_fresh_upstream &&\n \n@@ -112,6 +211,14 @@ test_expect_success TTY 'push --no-progress suppresses progress' '\n \ttest_i18ngrep ! \"Writing objects\" err\n '\n \n+test_expect_success TTY 'push --no-progress suppresses progress (default -u)' '\n+\tensure_fresh_upstream &&\n+\n+\ttest_terminal git push -u --no-progress >out 2>err &&\n+\ttest_i18ngrep ! \"Unpacking objects\" err &&\n+\ttest_i18ngrep ! \"Writing objects\" err\n+'\n+\n test_expect_success TTY 'quiet push' '\n \tensure_fresh_upstream &&\n \n@@ -126,4 +233,11 @@ test_expect_success TTY 'quiet push -u' '\n \ttest_must_be_empty output\n '\n \n+test_expect_success TTY 'quiet push -u (default -u)' '\n+\tensure_fresh_upstream &&\n+\n+\ttest_terminal git push --quiet -u --no-progress 2>&1 | tee output &&\n+\ttest_must_be_empty output\n+'\n+\n test_done\n-- \n2.17.1\n\n"},{"id":"443380","messageId":"CAPig+cRxU=pT-qCp-xpHcoae45oxz1d-eRh+QF-SJFM3B-6KyQ@mail.gmail.com","threadId":"57017","inReplyTo":"20211207182300.4361-2-chakrabortyabhradeep79@gmail.com","subject":"Re: [PATCH v2 1/1] push: make '-u' have default arguments","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2021-12-07T22:14:15Z","receivedAt":"2021-12-07T22:14:28Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Tue, Dec 7, 2021 at 4:11 PM Abhradeep Chakraborty\n<chakrabortyabhradeep79@gmail.com> wrote:\n> [...]\n> Teach \"git push -u\" not to require repository and refspec.  When\n> the user do not give what repository to push to, or which\n> branch(es) to push, behave as if the default remote repository\n> and a refspec (depending on the \"push.default\" configuration)\n> are given.\n> [...]\n> Signed-off-by: Abhradeep Chakraborty <chakrabortyabhradeep79@gmail.com>\n\nThis is not a proper review... just some superficial comments from\nscanning my eye over the patch...\n\n> diff --git a/t/t5523-push-upstream.sh b/t/t5523-push-upstream.sh\n> @@ -60,6 +60,75 @@ test_expect_success 'push -u :topic_2' '\n> +default_u_setup() {\n> +       git checkout main\n> +       remote=$(git config --get branch.main.remote)\n> +       if [ ! -z \"$remote\" ]; then\n> +               git branch --unset-upstream\n> +       fi\n> +       git config push.default $1\n> +       git config remote.pushDefault upstream\n> +}\n\nA few issues...\n\n* since callers of this function incorporate it into their &&-chains,\nthe body of the function itself should probably also have an intact\n&&-chain\n\n* use `test` rather than `[`\n\n* `then` goes on its own line\n\n* probably want to use test_config() here rather than raw `git config`\n\n* `! -z` can be written more simply as `-n`\n\nTaking the above into account, gives:\n\n    default_u_setup() {\n        git checkout main &&\n        remote=$(git config --default '' --get branch.main.remote) &&\n        if test -n \"$remote\"\n        then\n            git branch --unset-upstream\n        fi &&\n        test_config push.default $1 &&\n        test_config remote.pushDefault upstream\n    }\n\nThe `--default` ensures that `git config` will exit with a success\ncode which is important now that it's part of the &&-chain.\nAlternatively, you could skip the dance of checking for\n`branch.main.remote` and just call `git branch --unset-upstream`\nunconditionally, but wrap it with test_might_fail() so it can be part\nof the &&-chain without worrying about whether that command succeeds\nor fails:\n\n    default_u_setup() {\n        git checkout main &&\n        test_might_fail git branch --unset-upstream &&\n        test_config push.default $1 &&\n        test_config remote.pushDefault upstream\n    }\n\n> +test_expect_success 'push -u with push.default=simple' '\n> +       default_u_setup simple &&\n> +       git push -u &&\n> +       check_config main upstream refs/heads/main &&\n> +       git push -u upstream main:other &&\n> +       git push -u &&\n> +       check_config main upstream refs/heads/main\n> +'\n> +\n> +test_expect_success 'push -u with push.default=current' '\n> +       default_u_setup current &&\n> +       git push -u &&\n> +       check_config main upstream refs/heads/main &&\n> +       git push -u upstream main:other &&\n> +       git push -u &&\n> +       check_config main upstream refs/heads/main\n> +'\n> +\n> +test_expect_success 'push -u with push.default=upstream' '\n> +       default_u_setup upstream &&\n> +       git push -u &&\n> +       check_config main upstream refs/heads/main &&\n> +       git push -u upstream main:other &&\n> +       git push -u &&\n> +       check_config main upstream refs/heads/main\n> +'\n\nWhen a number of tests have nearly identical bodies like this, it is\nsometimes clearer and more convenient to turn them into a for-loop\nlike this:\n\n    for i in simple current upstream\n    do\n        test_expect_success \"push -u with push.default=$i\" '\n            default_u_setup $i &&\n            git push -u &&\n            check_config main upstream refs/heads/main &&\n            git push -u upstream main:other &&\n            git push -u &&\n            check_config main upstream refs/heads/main\n        '\n    done\n\n> +check_empty_config() {\n> +       test_expect_code 1 git config \"branch.$1.remote\"\n> +       test_expect_code 1 git config \"branch.$1.merge\"\n> +}\n\nAs above, because calls to this function are part of the &&-chain in\ntest bodies, it is important for the &&-chain to be intact in the\nfunction too. It's especially important in this case since this\nfunction is actually checking for specific conditions. As it's\ncurrently written -- with a broken &&-chain -- if the first\ntest_expect_code() fails, we'll never know about it since that exit\ncode gets lost; only the exit code from the second test_expect_code()\nhas any bearing on the overall result of the test.\n\n> +test_expect_success 'progress messagesdo not go to non-tty (default -u)' '\n\ns/messagesdo/messages do/\n\n> +       ensure_fresh_upstream &&\n> +\n> +       # skip progress messages, since stderr is non-tty\n> +       git push -u >out 2>err &&\n> +       test_i18ngrep ! \"Writing objects\" err\n> +'\n\nThe captured stdout in `out` doesn't seem to be used, so it's probably\nbetter to drop that redirection.\n\n> +test_expect_success 'progress messages go to non-tty with default -u (forced)' '\n> +       ensure_fresh_upstream &&\n> +\n> +       # force progress messages to stderr, even though it is non-tty\n> +       git push -u --progress >out 2>err &&\n> +       test_i18ngrep \"Writing objects\" err\n> +'\n\nDitto. And repeat for the remaining tests.\n"},{"id":"443407","messageId":"20211208061221.133-1-chakrabortyabhradeep79@gmail.com","threadId":"57017","inReplyTo":"CAPig+cRxU=pT-qCp-xpHcoae45oxz1d-eRh+QF-SJFM3B-6KyQ@mail.gmail.com","subject":"Re: [PATCH v2 1/1] push: make '-u' have default argument","fromName":"Abhradeep Chakraborty","fromEmail":"chakrabortyabhradeep79@gmail.com","sentAt":"2021-12-08T06:12:21Z","receivedAt":"2021-12-08T06:12:40Z","isPatch":true,"sender":{"key":"chakrabortyabhradeep79@gmail.com","avatar":"https://avatars.githubusercontent.com/u/75240995?v=4"},"body":"Eric Sunshine <sunshine@sunshineco.com> wrote:\n\n> As above, because calls to this function are part of the &&-chain in\n> test bodies, it is important for the &&-chain to be intact in the\n> function too. It's especially important in this case since this\n> function is actually checking for specific conditions. As it's\n> currently written -- with a broken &&-chain -- if the first\n> test_expect_code() fails, we'll never know about it since that exit\n> code gets lost; only the exit code from the second test_expect_code()\n> has any bearing on the overall result of the test.\n\nThanks so much for all the suggestions! I am little beginner in shell\nscripting. It would help me a lot!\n\n> s/messagesdo/messages do/\n\noops :|\n\n> The captured stdout in `out` doesn't seem to be used, so it's probably\n> better to drop that redirection.\n\nokay.\n"},{"id":"443625","messageId":"20211209101550.19582-1-chakrabortyabhradeep79@gmail.com","threadId":"57017","inReplyTo":"20211207182300.4361-1-chakrabortyabhradeep79@gmail.com","subject":"[PATCH v3 0/1] making --set-upstream have default arguments","fromName":"Abhradeep Chakraborty","fromEmail":"chakrabortyabhradeep79@gmail.com","sentAt":"2021-12-09T10:15:49Z","receivedAt":"2021-12-09T10:16:28Z","isPatch":true,"sender":{"key":"chakrabortyabhradeep79@gmail.com","avatar":"https://avatars.githubusercontent.com/u/75240995?v=4"},"body":"This patch series tries to make the 'set-upstream' option for\n'git push' have default arguments.\n\nIn v0: argumentless 'git push -u' was blindly passing default remote\nname and current branch's name as argv[0] and argv[1] respectively.\nThis was affecting `push.default` setting.\n\nFrom v1: The default remote is still used for the <repository> value.\nBut <refspec> depends on the current push configurations. If\n`push.default`='matching', it pushes to the upstream as it should and\nsets upstream respectively. For other values of 'push.default', it\npushes to the remote branch with the same name as the current\nbranch and sets that branch as the upstream.\n\nIn this version, the tests are improved.\n\nAbhradeep Chakraborty (1):\n  push: make '-u' have default arguments\n\n Documentation/git-push.txt | 10 +++++\n builtin/push.c             | 11 ++++-\n t/t5523-push-upstream.sh   | 87 ++++++++++++++++++++++++++++++++++++++\n 3 files changed, 106 insertions(+), 2 deletions(-)\n\nRange-diff against v2:\n1:  6567327900 ! 1:  376ba6cb8f push: make '-u' have default arguments\n    @@ Documentation/git-push.txt: Specifying `--no-force-if-includes` disables this be\n     +If `push.default` is set to `matching`, all remote branches to which\n     +local branches pushed, will be set as upstream of respective local\n     +branches. For all other values of `push.default`, current branch's\n    -+`<refspec>` will be used as the `<refspec>`.\n    ++refspec will be used as the `<refspec>`.\n      \n      --[no-]thin::\n      \tThese options are passed to linkgit:git-send-pack[1]. A thin transfer\n    @@ t/t5523-push-upstream.sh: test_expect_success 'push -u :topic_2' '\n      '\n      \n     +default_u_setup() {\n    -+\tgit checkout main\n    -+\tremote=$(git config --get branch.main.remote)\n    -+\tif [ ! -z \"$remote\" ]; then\n    -+\t\tgit branch --unset-upstream\n    -+\tfi\n    -+\tgit config push.default $1\n    -+\tgit config remote.pushDefault upstream\n    ++\tgit checkout main &&\n    ++\ttest_might_fail\tgit branch --unset-upstream &&\n    ++\ttest_config push.default $1 &&\n    ++\ttest_config remote.pushDefault upstream\n     +}\n     +\n    -+test_expect_success 'push -u with push.default=simple' '\n    -+\tdefault_u_setup simple &&\n    -+\tgit push -u &&\n    -+\tcheck_config main upstream refs/heads/main &&\n    -+\tgit push -u upstream main:other &&\n    -+\tgit push -u &&\n    -+\tcheck_config main upstream refs/heads/main\n    -+'\n    -+\n    -+test_expect_success 'push -u with push.default=current' '\n    -+\tdefault_u_setup current &&\n    -+\tgit push -u &&\n    -+\tcheck_config main upstream refs/heads/main &&\n    -+\tgit push -u upstream main:other &&\n    -+\tgit push -u &&\n    -+\tcheck_config main upstream refs/heads/main\n    -+'\n    -+\n    -+test_expect_success 'push -u with push.default=upstream' '\n    -+\tdefault_u_setup upstream &&\n    -+\tgit push -u &&\n    -+\tcheck_config main upstream refs/heads/main &&\n    -+\tgit push -u upstream main:other &&\n    -+\tgit push -u &&\n    -+\tcheck_config main upstream refs/heads/main\n    -+'\n    ++for i in simple current upstream nothing\n    ++do\n    ++\ttest_expect_success 'push -u with push.default=$i' '\n    ++\t\tdefault_u_setup $i &&\n    ++\t\tgit push -u &&\n    ++\t\tcheck_config main upstream refs/heads/main &&\n    ++\t\tgit push -u upstream main:other &&\n    ++\t\tgit push -u &&\n    ++\t\tcheck_config main upstream refs/heads/main\n    ++\t'\n    ++done\n     +\n     +check_empty_config() {\n    -+\ttest_expect_code 1 git config \"branch.$1.remote\"\n    ++\ttest_expect_code 1 git config \"branch.$1.remote\" &&\n     +\ttest_expect_code 1 git config \"branch.$1.merge\"\n     +}\n     +\n    @@ t/t5523-push-upstream.sh: test_expect_success 'push -u :topic_2' '\n     +\tcheck_empty_config test_u\n     +'\n     +\n    -+test_expect_success 'push -u with push.default=nothing' '\n    -+\tdefault_u_setup nothing &&\n    -+\tgit push -u &&\n    -+\tcheck_config main upstream refs/heads/main &&\n    -+\tgit push -u upstream main:other &&\n    -+\tgit push -u &&\n    -+\tcheck_config main upstream refs/heads/main\n    -+'\n    -+\n     +test_expect_success 'push -u --dry-run' '\n     +\tgit checkout main &&\n     +\tgit push -u upstream main:other &&\n    @@ t/t5523-push-upstream.sh: test_expect_success TTY 'progress messages go to tty'\n     +test_expect_success TTY 'progress messages go to tty with default -u' '\n     +\tensure_fresh_upstream &&\n     +\n    -+\ttest_terminal git push -u >out 2>err &&\n    ++\ttest_terminal git push -u 2>err &&\n     +\ttest_i18ngrep \"Writing objects\" err\n     +'\n     +\n    @@ t/t5523-push-upstream.sh: test_expect_success 'progress messages do not go to no\n      \ttest_i18ngrep ! \"Writing objects\" err\n      '\n      \n    -+test_expect_success 'progress messagesdo not go to non-tty (default -u)' '\n    ++test_expect_success 'progress messages do not go to non-tty (default -u)' '\n     +\tensure_fresh_upstream &&\n     +\n     +\t# skip progress messages, since stderr is non-tty\n    -+\tgit push -u >out 2>err &&\n    ++\tgit push -u 2>err &&\n     +\ttest_i18ngrep ! \"Writing objects\" err\n     +'\n     +\n    @@ t/t5523-push-upstream.sh: test_expect_success 'progress messages go to non-tty (\n     +\tensure_fresh_upstream &&\n     +\n     +\t# force progress messages to stderr, even though it is non-tty\n    -+\tgit push -u --progress >out 2>err &&\n    ++\tgit push -u --progress 2>err &&\n     +\ttest_i18ngrep \"Writing objects\" err\n     +'\n     +\n    @@ t/t5523-push-upstream.sh: test_expect_success TTY 'push -q suppresses progress'\n     +test_expect_success TTY 'push -q suppresses progress (with default -u)' '\n     +\tensure_fresh_upstream &&\n     +\n    -+\ttest_terminal git push -u -q >out 2>err &&\n    ++\ttest_terminal git push -u -q 2>err &&\n     +\ttest_i18ngrep ! \"Writing objects\" err\n     +'\n     +\n    @@ t/t5523-push-upstream.sh: test_expect_success TTY 'push --no-progress suppresses\n     +test_expect_success TTY 'push --no-progress suppresses progress (default -u)' '\n     +\tensure_fresh_upstream &&\n     +\n    -+\ttest_terminal git push -u --no-progress >out 2>err &&\n    ++\ttest_terminal git push -u --no-progress 2>err &&\n     +\ttest_i18ngrep ! \"Unpacking objects\" err &&\n     +\ttest_i18ngrep ! \"Writing objects\" err\n     +'\n-- \n2.34.1\n\n"},{"id":"443626","messageId":"20211209101550.19582-2-chakrabortyabhradeep79@gmail.com","threadId":"57017","inReplyTo":"20211209101550.19582-1-chakrabortyabhradeep79@gmail.com","subject":"[PATCH v3 1/1] push: make '-u' have default arguments","fromName":"Abhradeep Chakraborty","fromEmail":"chakrabortyabhradeep79@gmail.com","sentAt":"2021-12-09T10:15:50Z","receivedAt":"2021-12-09T10:17:11Z","isPatch":true,"sender":{"key":"chakrabortyabhradeep79@gmail.com","avatar":"https://avatars.githubusercontent.com/u/75240995?v=4"},"body":"\"git push -u\" (set-upstream) requires where to push to and what\nto push.  Often people push only the current branch to update\nthe branch of the same name at the 'origin' repository.  For\nthem, it would be convenient if \"git push -u\" without repository\nor refspec, defaulted to push and set upstream to the branch as\nconfigured by the \"push.default\" setting, of the remote repository\nthat is used by default.\n\nTeach \"git push -u\" not to require repository and refspec.  When\nthe user do not give what repository to push to, or which\nbranch(es) to push, behave as if the default remote repository\nand a refspec (depending on the \"push.default\" configuration)\nare given.\n\nIf \"push.default\"=matching, push all the branches matched on both\nremote and local side and set those remote branches as the upstream\nof their respective local matched branches. Otherwise, set the\nrefspec to the refspec for current branch.\n\nSigned-off-by: Abhradeep Chakraborty <chakrabortyabhradeep79@gmail.com>\n---\n Documentation/git-push.txt | 10 +++++\n builtin/push.c             | 11 ++++-\n t/t5523-push-upstream.sh   | 87 ++++++++++++++++++++++++++++++++++++++\n 3 files changed, 106 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/git-push.txt b/Documentation/git-push.txt\nindex 2f25aa3a29..6fd474441f 100644\n--- a/Documentation/git-push.txt\n+++ b/Documentation/git-push.txt\n@@ -375,6 +375,16 @@ Specifying `--no-force-if-includes` disables this behavior.\n \tupstream (tracking) reference, used by argument-less\n \tlinkgit:git-pull[1] and other commands. For more information,\n \tsee `branch.<name>.merge` in linkgit:git-config[1].\n++\n+`-u` can also work with zero arguments( i.e. no `<repository>` and\n+`<refspec>` are given). In that case, it tries to get the `<repository>`\n+value from `branch.*.remote` configuration. If not found, it defaults to\n+`origin`. If `remote.pushDefault` is set then it uses that instead. The\n+value of `<refspec>` depends on the current `push.default` configuration.\n+If `push.default` is set to `matching`, all remote branches to which\n+local branches pushed, will be set as upstream of respective local\n+branches. For all other values of `push.default`, current branch's\n+refspec will be used as the `<refspec>`.\n \n --[no-]thin::\n \tThese options are passed to linkgit:git-send-pack[1]. A thin transfer\ndiff --git a/builtin/push.c b/builtin/push.c\nindex 4b026ce6c6..8bc206c9d8 100644\n--- a/builtin/push.c\n+++ b/builtin/push.c\n@@ -202,11 +202,12 @@ static const char *get_upstream_ref(struct branch *branch, const char *remote_na\n \treturn branch->merge[0]->src;\n }\n \n-static void setup_default_push_refspecs(struct remote *remote)\n+static void setup_default_push_refspecs(struct remote *remote, int flags)\n {\n \tstruct branch *branch;\n \tconst char *dst;\n \tint same_remote;\n+\tint is_default_u = (flags & TRANSPORT_PUSH_SET_UPSTREAM);\n \n \tswitch (push_default) {\n \tcase PUSH_DEFAULT_MATCHING:\n@@ -214,6 +215,8 @@ static void setup_default_push_refspecs(struct remote *remote)\n \t\treturn;\n \n \tcase PUSH_DEFAULT_NOTHING:\n+\t\tif (is_default_u)\n+\t\t\tbreak;\n \t\tdie(_(\"You didn't specify any refspecs to push, and \"\n \t\t    \"push.default is \\\"nothing\\\".\"));\n \t\treturn;\n@@ -234,11 +237,15 @@ static void setup_default_push_refspecs(struct remote *remote)\n \tcase PUSH_DEFAULT_SIMPLE:\n \t\tif (!same_remote)\n \t\t\tbreak;\n+\t\tif (is_default_u)\n+\t\t\tbreak;\n \t\tif (strcmp(branch->refname, get_upstream_ref(branch, remote->name)))\n \t\t\tdie_push_simple(branch, remote);\n \t\tbreak;\n \n \tcase PUSH_DEFAULT_UPSTREAM:\n+\t\tif (is_default_u)\n+\t\t\tbreak;\n \t\tif (!same_remote)\n \t\t\tdie(_(\"You are pushing to remote '%s', which is not the upstream of\\n\"\n \t\t\t      \"your current branch '%s', without telling me what to push\\n\"\n@@ -401,7 +408,7 @@ static int do_push(int flags,\n \t\tif (remote->push.nr) {\n \t\t\tpush_refspec = &remote->push;\n \t\t} else if (!(flags & TRANSPORT_PUSH_MIRROR))\n-\t\t\tsetup_default_push_refspecs(remote);\n+\t\t\tsetup_default_push_refspecs(remote, flags);\n \t}\n \terrs = 0;\n \turl_nr = push_url_of_remote(remote, &url);\ndiff --git a/t/t5523-push-upstream.sh b/t/t5523-push-upstream.sh\nindex fdb4292056..ea5d1ae914 100755\n--- a/t/t5523-push-upstream.sh\n+++ b/t/t5523-push-upstream.sh\n@@ -60,6 +60,48 @@ test_expect_success 'push -u :topic_2' '\n \tcheck_config topic_2 upstream refs/heads/other2\n '\n \n+default_u_setup() {\n+\tgit checkout main &&\n+\ttest_might_fail\tgit branch --unset-upstream &&\n+\ttest_config push.default $1 &&\n+\ttest_config remote.pushDefault upstream\n+}\n+\n+for i in simple current upstream nothing\n+do\n+\ttest_expect_success 'push -u with push.default=$i' '\n+\t\tdefault_u_setup $i &&\n+\t\tgit push -u &&\n+\t\tcheck_config main upstream refs/heads/main &&\n+\t\tgit push -u upstream main:other &&\n+\t\tgit push -u &&\n+\t\tcheck_config main upstream refs/heads/main\n+\t'\n+done\n+\n+check_empty_config() {\n+\ttest_expect_code 1 git config \"branch.$1.remote\" &&\n+\ttest_expect_code 1 git config \"branch.$1.merge\"\n+}\n+\n+test_expect_success 'push -u with push.default=matching' '\n+\tdefault_u_setup matching &&\n+\tgit branch test_u &&\n+\tgit branch test_u2 &&\n+\tgit push upstream main:test_u2 &&\n+\tgit push -u &&\n+\tcheck_config main upstream refs/heads/main &&\n+\tcheck_config test_u2 upstream refs/heads/test_u2 &&\n+\tcheck_empty_config test_u\n+'\n+\n+test_expect_success 'push -u --dry-run' '\n+\tgit checkout main &&\n+\tgit push -u upstream main:other &&\n+\tgit push -u --dry-run &&\n+\tcheck_config main upstream refs/heads/other\n+'\n+\n test_expect_success 'push -u --all' '\n \tgit branch all1 &&\n \tgit branch all2 &&\n@@ -81,6 +123,13 @@ test_expect_success TTY 'progress messages go to tty' '\n \ttest_i18ngrep \"Writing objects\" err\n '\n \n+test_expect_success TTY 'progress messages go to tty with default -u' '\n+\tensure_fresh_upstream &&\n+\n+\ttest_terminal git push -u 2>err &&\n+\ttest_i18ngrep \"Writing objects\" err\n+'\n+\n test_expect_success 'progress messages do not go to non-tty' '\n \tensure_fresh_upstream &&\n \n@@ -89,6 +138,14 @@ test_expect_success 'progress messages do not go to non-tty' '\n \ttest_i18ngrep ! \"Writing objects\" err\n '\n \n+test_expect_success 'progress messages do not go to non-tty (default -u)' '\n+\tensure_fresh_upstream &&\n+\n+\t# skip progress messages, since stderr is non-tty\n+\tgit push -u 2>err &&\n+\ttest_i18ngrep ! \"Writing objects\" err\n+'\n+\n test_expect_success 'progress messages go to non-tty (forced)' '\n \tensure_fresh_upstream &&\n \n@@ -97,6 +154,14 @@ test_expect_success 'progress messages go to non-tty (forced)' '\n \ttest_i18ngrep \"Writing objects\" err\n '\n \n+test_expect_success 'progress messages go to non-tty with default -u (forced)' '\n+\tensure_fresh_upstream &&\n+\n+\t# force progress messages to stderr, even though it is non-tty\n+\tgit push -u --progress 2>err &&\n+\ttest_i18ngrep \"Writing objects\" err\n+'\n+\n test_expect_success TTY 'push -q suppresses progress' '\n \tensure_fresh_upstream &&\n \n@@ -104,6 +169,13 @@ test_expect_success TTY 'push -q suppresses progress' '\n \ttest_i18ngrep ! \"Writing objects\" err\n '\n \n+test_expect_success TTY 'push -q suppresses progress (with default -u)' '\n+\tensure_fresh_upstream &&\n+\n+\ttest_terminal git push -u -q 2>err &&\n+\ttest_i18ngrep ! \"Writing objects\" err\n+'\n+\n test_expect_success TTY 'push --no-progress suppresses progress' '\n \tensure_fresh_upstream &&\n \n@@ -112,6 +184,14 @@ test_expect_success TTY 'push --no-progress suppresses progress' '\n \ttest_i18ngrep ! \"Writing objects\" err\n '\n \n+test_expect_success TTY 'push --no-progress suppresses progress (default -u)' '\n+\tensure_fresh_upstream &&\n+\n+\ttest_terminal git push -u --no-progress 2>err &&\n+\ttest_i18ngrep ! \"Unpacking objects\" err &&\n+\ttest_i18ngrep ! \"Writing objects\" err\n+'\n+\n test_expect_success TTY 'quiet push' '\n \tensure_fresh_upstream &&\n \n@@ -126,4 +206,11 @@ test_expect_success TTY 'quiet push -u' '\n \ttest_must_be_empty output\n '\n \n+test_expect_success TTY 'quiet push -u (default -u)' '\n+\tensure_fresh_upstream &&\n+\n+\ttest_terminal git push --quiet -u --no-progress 2>&1 | tee output &&\n+\ttest_must_be_empty output\n+'\n+\n test_done\n-- \n2.34.1\n\n"},{"id":"445312","messageId":"20220101143748.2582-1-chakrabortyabhradeep79@gmail.com","threadId":"57017","inReplyTo":"20211209101550.19582-1-chakrabortyabhradeep79@gmail.com","subject":"[PATCH v4 0/1] making --set-upstream have default arguments","fromName":"Abhradeep Chakraborty","fromEmail":"chakrabortyabhradeep79@gmail.com","sentAt":"2022-01-01T14:37:47Z","receivedAt":"2022-01-01T14:39:20Z","isPatch":true,"sender":{"key":"chakrabortyabhradeep79@gmail.com","avatar":"https://avatars.githubusercontent.com/u/75240995?v=4"},"body":"Often developers want to set a remote branch (i.e. upstream branch)\nfor the local branch according to their `push.default` settings. For\nexample, beginners often (may be most of the beginners) run\n\n\tgit push -u origin <current_branch_name>\n\nIf the `push.default` configuration is set, people may want to set\nthe upstream to that branch that satisfies the `push.default`\nconfiguration. For example, if the `push.default` is set to\n'current', developer may want to do like this -\n\n\tgit push -u <default_repo> <current_branch>\n\nSo, it would be great if 'git push -u' (i.e. without <repo> and\n<refspec>) by default do this. If `push.default` is not set or has\na value other than 'matching', it would do this - \n\n\tgit push -u <default_repo> <current_branch>\n\nAnd for `push.default`= 'matching', it would set all the remote\nmaching branch as upstream of their respective matching local\nbranches. E.g. if 'branch1' and 'branch2' branches both exist in\nthe local as well as remote repo, 'git push -u' would set the remote\n'branch1' as the upstream of local 'branch1' branch and remote\n'branch2' branch would be set as the upstream of local 'branch2'\nbranch.\n\nNote, 'git push -u' for push.default=matching, already works. \n\nThis patch series addresses this.\n\nIn v0: argumentless 'git push -u' was blindly passing default remote\nname and current branch's name as argv[0] and argv[1] respectively.\nThis was affecting `push.default` setting.\n\nFrom v1: The default remote is still used for the <repository> value.\nBut <refspec> depends on the current push configurations. If\n`push.default`='matching', it pushes to the upstream as it should and\nsets upstream respectively. For other values of 'push.default', it\npushes to the remote branch with the same name as the current\nbranch and sets that branch as the upstream.\n\nIn v2 and v3: various test cases were added and improved\n\nIn current version: tests for 'git push -u' with other options are\nadded. This includes '-f', '--prune', '-d', '--mirror'.\n\n\nAbhradeep Chakraborty (1):\n  push: make 'set-upstream' have dafault arguments\n\n Documentation/git-push.txt |  10 +++\n builtin/push.c             |  11 +++-\n t/t5523-push-upstream.sh   | 125 +++++++++++++++++++++++++++++++++++++\n 3 files changed, 144 insertions(+), 2 deletions(-)\n\nRange-diff against v3:\n1:  64655de6ca ! 1:  d154c7d1f6 push: make '-u' have default arguments\n    @@ Metadata\n     Author: Abhradeep Chakraborty <chakrabortyabhradeep79@gmail.com>\n     \n      ## Commit message ##\n    -    push: make '-u' have default arguments\n    +    push: make 'set-upstream' have dafault arguments\n     \n         \"git push -u\" (set-upstream) requires where to push to and what\n         to push.  Often people push only the current branch to update\n    @@ t/t5523-push-upstream.sh: test_expect_success 'push -u :topic_2' '\n     +\ttest_config remote.pushDefault upstream\n     +}\n     +\n    ++check_empty_config() {\n    ++\ttest_expect_code 1 git config \"branch.$1.remote\" &&\n    ++\ttest_expect_code 1 git config \"branch.$1.merge\"\n    ++}\n    ++\n     +for i in simple current upstream nothing\n     +do\n     +\ttest_expect_success 'push -u with push.default=$i' '\n    @@ t/t5523-push-upstream.sh: test_expect_success 'push -u :topic_2' '\n     +\t\tgit push -u &&\n     +\t\tcheck_config main upstream refs/heads/main\n     +\t'\n    ++\n    ++\ttest_expect_success 'push -u -f with push.default=$i' '\n    ++\t\tdefault_u_setup $i &&\n    ++\t\tgit push -u -f &&\n    ++\t\tcheck_config main upstream refs/heads/main\n    ++\t'\n     +done\n     +\n    -+check_empty_config() {\n    -+\ttest_expect_code 1 git config \"branch.$1.remote\" &&\n    -+\ttest_expect_code 1 git config \"branch.$1.merge\"\n    -+}\n    ++for i in simple current upstream nothing matching\n    ++do\n    ++\ttest_expect_success 'push -u --prune with push.default=$i' '\n    ++\t\tdefault_u_setup $i &&\n    ++\t\tgit push upstream main:test_u215 &&\n    ++\t\tgit push -u --prune >out &&\n    ++\t\tcheck_config main upstream refs/heads/main &&\n    ++\t\ttest_i18ngrep \"[deleted]\" out &&\n    ++\t\ttest_i18ngrep ! \"Branch '\"'\"'test_u215'\"'\"' set up to track\" out\n    ++\t'\n    ++\n    ++\ttest_expect_success 'push -u --mirror with push.default=$i' '\n    ++\t\tdefault_u_setup $i &&\n    ++\t\ttest_might_fail git branch mirror1 &&\n    ++\t\ttest_might_fail git branch mirror2 &&\n    ++\t\tgit push -u --mirror &&\n    ++\t\tcheck_config main upstream  refs/heads/main &&\n    ++\t\tcheck_config mirror1 upstream refs/heads/mirror1 &&\n    ++\t\tcheck_config mirror2 upstream refs/heads/mirror2\n    ++\t'\n    ++done\n     +\n    -+test_expect_success 'push -u with push.default=matching' '\n    -+\tdefault_u_setup matching &&\n    -+\tgit branch test_u &&\n    -+\tgit branch test_u2 &&\n    -+\tgit push upstream main:test_u2 &&\n    -+\tgit push -u &&\n    -+\tcheck_config main upstream refs/heads/main &&\n    -+\tcheck_config test_u2 upstream refs/heads/test_u2 &&\n    -+\tcheck_empty_config test_u\n    ++for i in '' '-f'\n    ++do\n    ++\n    ++\ttest_expect_success 'push -u $i with push.default=matching' '\n    ++\t\tdefault_u_setup matching &&\n    ++\t\ttest_might_fail git branch test_u &&\n    ++\t\ttest_might_fail git branch test_u2 &&\n    ++\t\tgit push upstream main:test_u2 &&\n    ++\t\tgit push -u $i &&\n    ++\t\tcheck_config main upstream refs/heads/main &&\n    ++\t\tcheck_config test_u2 upstream refs/heads/test_u2 &&\n    ++\t\tcheck_empty_config test_u\n    ++\t'\n    ++done\n    ++\n    ++test_expect_success 'push -u -d will fail' '\n    ++\tgit checkout main &&\n    ++\ttest_might_fail git branch --unset-upstream &&\n    ++\ttest_must_fail git push -u -d\n     +'\n     +\n     +test_expect_success 'push -u --dry-run' '\n-- \n2.34.1\n\n"},{"id":"445313","messageId":"20220101143748.2582-2-chakrabortyabhradeep79@gmail.com","threadId":"57017","inReplyTo":"20220101143748.2582-1-chakrabortyabhradeep79@gmail.com","subject":"[PATCH v4 1/1] push: make 'set-upstream' have dafault arguments","fromName":"Abhradeep Chakraborty","fromEmail":"chakrabortyabhradeep79@gmail.com","sentAt":"2022-01-01T14:37:48Z","receivedAt":"2022-01-01T14:39:26Z","isPatch":true,"sender":{"key":"chakrabortyabhradeep79@gmail.com","avatar":"https://avatars.githubusercontent.com/u/75240995?v=4"},"body":"\"git push -u\" (set-upstream) requires where to push to and what\nto push.  Often people push only the current branch to update\nthe branch of the same name at the 'origin' repository.  For\nthem, it would be convenient if \"git push -u\" without repository\nor refspec, defaulted to push and set upstream to the branch as\nconfigured by the \"push.default\" setting, of the remote repository\nthat is used by default.\n\nTeach \"git push -u\" not to require repository and refspec.  When\nthe user do not give what repository to push to, or which\nbranch(es) to push, behave as if the default remote repository\nand a refspec (depending on the \"push.default\" configuration)\nare given.\n\nIf \"push.default\"=matching, push all the branches matched on both\nremote and local side and set those remote branches as the upstream\nof their respective local matched branches. Otherwise, set the\nrefspec to the refspec for current branch.\n\nSigned-off-by: Abhradeep Chakraborty <chakrabortyabhradeep79@gmail.com>\n---\n Documentation/git-push.txt |  10 +++\n builtin/push.c             |  11 +++-\n t/t5523-push-upstream.sh   | 125 +++++++++++++++++++++++++++++++++++++\n 3 files changed, 144 insertions(+), 2 deletions(-)\n\ndiff --git a/Documentation/git-push.txt b/Documentation/git-push.txt\nindex 2f25aa3a29..6fd474441f 100644\n--- a/Documentation/git-push.txt\n+++ b/Documentation/git-push.txt\n@@ -375,6 +375,16 @@ Specifying `--no-force-if-includes` disables this behavior.\n \tupstream (tracking) reference, used by argument-less\n \tlinkgit:git-pull[1] and other commands. For more information,\n \tsee `branch.<name>.merge` in linkgit:git-config[1].\n++\n+`-u` can also work with zero arguments( i.e. no `<repository>` and\n+`<refspec>` are given). In that case, it tries to get the `<repository>`\n+value from `branch.*.remote` configuration. If not found, it defaults to\n+`origin`. If `remote.pushDefault` is set then it uses that instead. The\n+value of `<refspec>` depends on the current `push.default` configuration.\n+If `push.default` is set to `matching`, all remote branches to which\n+local branches pushed, will be set as upstream of respective local\n+branches. For all other values of `push.default`, current branch's\n+refspec will be used as the `<refspec>`.\n \n --[no-]thin::\n \tThese options are passed to linkgit:git-send-pack[1]. A thin transfer\ndiff --git a/builtin/push.c b/builtin/push.c\nindex 4b026ce6c6..8bc206c9d8 100644\n--- a/builtin/push.c\n+++ b/builtin/push.c\n@@ -202,11 +202,12 @@ static const char *get_upstream_ref(struct branch *branch, const char *remote_na\n \treturn branch->merge[0]->src;\n }\n \n-static void setup_default_push_refspecs(struct remote *remote)\n+static void setup_default_push_refspecs(struct remote *remote, int flags)\n {\n \tstruct branch *branch;\n \tconst char *dst;\n \tint same_remote;\n+\tint is_default_u = (flags & TRANSPORT_PUSH_SET_UPSTREAM);\n \n \tswitch (push_default) {\n \tcase PUSH_DEFAULT_MATCHING:\n@@ -214,6 +215,8 @@ static void setup_default_push_refspecs(struct remote *remote)\n \t\treturn;\n \n \tcase PUSH_DEFAULT_NOTHING:\n+\t\tif (is_default_u)\n+\t\t\tbreak;\n \t\tdie(_(\"You didn't specify any refspecs to push, and \"\n \t\t    \"push.default is \\\"nothing\\\".\"));\n \t\treturn;\n@@ -234,11 +237,15 @@ static void setup_default_push_refspecs(struct remote *remote)\n \tcase PUSH_DEFAULT_SIMPLE:\n \t\tif (!same_remote)\n \t\t\tbreak;\n+\t\tif (is_default_u)\n+\t\t\tbreak;\n \t\tif (strcmp(branch->refname, get_upstream_ref(branch, remote->name)))\n \t\t\tdie_push_simple(branch, remote);\n \t\tbreak;\n \n \tcase PUSH_DEFAULT_UPSTREAM:\n+\t\tif (is_default_u)\n+\t\t\tbreak;\n \t\tif (!same_remote)\n \t\t\tdie(_(\"You are pushing to remote '%s', which is not the upstream of\\n\"\n \t\t\t      \"your current branch '%s', without telling me what to push\\n\"\n@@ -401,7 +408,7 @@ static int do_push(int flags,\n \t\tif (remote->push.nr) {\n \t\t\tpush_refspec = &remote->push;\n \t\t} else if (!(flags & TRANSPORT_PUSH_MIRROR))\n-\t\t\tsetup_default_push_refspecs(remote);\n+\t\t\tsetup_default_push_refspecs(remote, flags);\n \t}\n \terrs = 0;\n \turl_nr = push_url_of_remote(remote, &url);\ndiff --git a/t/t5523-push-upstream.sh b/t/t5523-push-upstream.sh\nindex fdb4292056..c2d11c3f2a 100755\n--- a/t/t5523-push-upstream.sh\n+++ b/t/t5523-push-upstream.sh\n@@ -60,6 +60,86 @@ test_expect_success 'push -u :topic_2' '\n \tcheck_config topic_2 upstream refs/heads/other2\n '\n \n+default_u_setup() {\n+\tgit checkout main &&\n+\ttest_might_fail\tgit branch --unset-upstream &&\n+\ttest_config push.default $1 &&\n+\ttest_config remote.pushDefault upstream\n+}\n+\n+check_empty_config() {\n+\ttest_expect_code 1 git config \"branch.$1.remote\" &&\n+\ttest_expect_code 1 git config \"branch.$1.merge\"\n+}\n+\n+for i in simple current upstream nothing\n+do\n+\ttest_expect_success 'push -u with push.default=$i' '\n+\t\tdefault_u_setup $i &&\n+\t\tgit push -u &&\n+\t\tcheck_config main upstream refs/heads/main &&\n+\t\tgit push -u upstream main:other &&\n+\t\tgit push -u &&\n+\t\tcheck_config main upstream refs/heads/main\n+\t'\n+\n+\ttest_expect_success 'push -u -f with push.default=$i' '\n+\t\tdefault_u_setup $i &&\n+\t\tgit push -u -f &&\n+\t\tcheck_config main upstream refs/heads/main\n+\t'\n+done\n+\n+for i in simple current upstream nothing matching\n+do\n+\ttest_expect_success 'push -u --prune with push.default=$i' '\n+\t\tdefault_u_setup $i &&\n+\t\tgit push upstream main:test_u215 &&\n+\t\tgit push -u --prune >out &&\n+\t\tcheck_config main upstream refs/heads/main &&\n+\t\ttest_i18ngrep \"[deleted]\" out &&\n+\t\ttest_i18ngrep ! \"Branch '\"'\"'test_u215'\"'\"' set up to track\" out\n+\t'\n+\n+\ttest_expect_success 'push -u --mirror with push.default=$i' '\n+\t\tdefault_u_setup $i &&\n+\t\ttest_might_fail git branch mirror1 &&\n+\t\ttest_might_fail git branch mirror2 &&\n+\t\tgit push -u --mirror &&\n+\t\tcheck_config main upstream  refs/heads/main &&\n+\t\tcheck_config mirror1 upstream refs/heads/mirror1 &&\n+\t\tcheck_config mirror2 upstream refs/heads/mirror2\n+\t'\n+done\n+\n+for i in '' '-f'\n+do\n+\n+\ttest_expect_success 'push -u $i with push.default=matching' '\n+\t\tdefault_u_setup matching &&\n+\t\ttest_might_fail git branch test_u &&\n+\t\ttest_might_fail git branch test_u2 &&\n+\t\tgit push upstream main:test_u2 &&\n+\t\tgit push -u $i &&\n+\t\tcheck_config main upstream refs/heads/main &&\n+\t\tcheck_config test_u2 upstream refs/heads/test_u2 &&\n+\t\tcheck_empty_config test_u\n+\t'\n+done\n+\n+test_expect_success 'push -u -d will fail' '\n+\tgit checkout main &&\n+\ttest_might_fail git branch --unset-upstream &&\n+\ttest_must_fail git push -u -d\n+'\n+\n+test_expect_success 'push -u --dry-run' '\n+\tgit checkout main &&\n+\tgit push -u upstream main:other &&\n+\tgit push -u --dry-run &&\n+\tcheck_config main upstream refs/heads/other\n+'\n+\n test_expect_success 'push -u --all' '\n \tgit branch all1 &&\n \tgit branch all2 &&\n@@ -81,6 +161,13 @@ test_expect_success TTY 'progress messages go to tty' '\n \ttest_i18ngrep \"Writing objects\" err\n '\n \n+test_expect_success TTY 'progress messages go to tty with default -u' '\n+\tensure_fresh_upstream &&\n+\n+\ttest_terminal git push -u 2>err &&\n+\ttest_i18ngrep \"Writing objects\" err\n+'\n+\n test_expect_success 'progress messages do not go to non-tty' '\n \tensure_fresh_upstream &&\n \n@@ -89,6 +176,14 @@ test_expect_success 'progress messages do not go to non-tty' '\n \ttest_i18ngrep ! \"Writing objects\" err\n '\n \n+test_expect_success 'progress messages do not go to non-tty (default -u)' '\n+\tensure_fresh_upstream &&\n+\n+\t# skip progress messages, since stderr is non-tty\n+\tgit push -u 2>err &&\n+\ttest_i18ngrep ! \"Writing objects\" err\n+'\n+\n test_expect_success 'progress messages go to non-tty (forced)' '\n \tensure_fresh_upstream &&\n \n@@ -97,6 +192,14 @@ test_expect_success 'progress messages go to non-tty (forced)' '\n \ttest_i18ngrep \"Writing objects\" err\n '\n \n+test_expect_success 'progress messages go to non-tty with default -u (forced)' '\n+\tensure_fresh_upstream &&\n+\n+\t# force progress messages to stderr, even though it is non-tty\n+\tgit push -u --progress 2>err &&\n+\ttest_i18ngrep \"Writing objects\" err\n+'\n+\n test_expect_success TTY 'push -q suppresses progress' '\n \tensure_fresh_upstream &&\n \n@@ -104,6 +207,13 @@ test_expect_success TTY 'push -q suppresses progress' '\n \ttest_i18ngrep ! \"Writing objects\" err\n '\n \n+test_expect_success TTY 'push -q suppresses progress (with default -u)' '\n+\tensure_fresh_upstream &&\n+\n+\ttest_terminal git push -u -q 2>err &&\n+\ttest_i18ngrep ! \"Writing objects\" err\n+'\n+\n test_expect_success TTY 'push --no-progress suppresses progress' '\n \tensure_fresh_upstream &&\n \n@@ -112,6 +222,14 @@ test_expect_success TTY 'push --no-progress suppresses progress' '\n \ttest_i18ngrep ! \"Writing objects\" err\n '\n \n+test_expect_success TTY 'push --no-progress suppresses progress (default -u)' '\n+\tensure_fresh_upstream &&\n+\n+\ttest_terminal git push -u --no-progress 2>err &&\n+\ttest_i18ngrep ! \"Unpacking objects\" err &&\n+\ttest_i18ngrep ! \"Writing objects\" err\n+'\n+\n test_expect_success TTY 'quiet push' '\n \tensure_fresh_upstream &&\n \n@@ -126,4 +244,11 @@ test_expect_success TTY 'quiet push -u' '\n \ttest_must_be_empty output\n '\n \n+test_expect_success TTY 'quiet push -u (default -u)' '\n+\tensure_fresh_upstream &&\n+\n+\ttest_terminal git push --quiet -u --no-progress 2>&1 | tee output &&\n+\ttest_must_be_empty output\n+'\n+\n test_done\n-- \n2.34.1\n\n"},{"id":"445388","messageId":"xmqqy23wduxp.fsf@gitster.g","threadId":"57017","inReplyTo":"20220101143748.2582-2-chakrabortyabhradeep79@gmail.com","subject":"Re: [PATCH v4 1/1] push: make 'set-upstream' have dafault arguments","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-01-04T03:46:42Z","receivedAt":"2022-01-04T03:46:48Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Abhradeep Chakraborty <chakrabortyabhradeep79@gmail.com> writes:\n\n> Teach \"git push -u\" not to require repository and refspec.  When\n> the user do not give what repository to push to, or which\n> branch(es) to push, behave as if the default remote repository\n> and a refspec (depending on the \"push.default\" configuration)\n> are given.\n\nThat means if the user says push.default==nothing, we should error\nout \"git push -u\" as before, but that is not what the change to\nsetup_default_push_refspecs() function does, is it?\n\n> -static void setup_default_push_refspecs(struct remote *remote)\n> +static void setup_default_push_refspecs(struct remote *remote, int flags)\n>  {\n>  \tstruct branch *branch;\n>  \tconst char *dst;\n>  \tint same_remote;\n> +\tint is_default_u = (flags & TRANSPORT_PUSH_SET_UPSTREAM);\n>  \n>  \tswitch (push_default) {\n>  \tcase PUSH_DEFAULT_MATCHING:\n> @@ -214,6 +215,8 @@ static void setup_default_push_refspecs(struct remote *remote)\n>  \t\treturn;\n>  \n>  \tcase PUSH_DEFAULT_NOTHING:\n> +\t\tif (is_default_u)\n> +\t\t\tbreak;\n>  \t\tdie(_(\"You didn't specify any refspecs to push, and \"\n>  \t\t    \"push.default is \\\"nothing\\\".\"));\n>  \t\treturn;\n> @@ -234,11 +237,15 @@ static void setup_default_push_refspecs(struct remote *remote)\n>  \tcase PUSH_DEFAULT_SIMPLE:\n>  \t\tif (!same_remote)\n>  \t\t\tbreak;\n> +\t\tif (is_default_u)\n> +\t\t\tbreak;\n>  \t\tif (strcmp(branch->refname, get_upstream_ref(branch, remote->name)))\n>  \t\t\tdie_push_simple(branch, remote);\n>  \t\tbreak;\n>  \n>  \tcase PUSH_DEFAULT_UPSTREAM:\n> +\t\tif (is_default_u)\n> +\t\t\tbreak;\n>  \t\tif (!same_remote)\n>  \t\t\tdie(_(\"You are pushing to remote '%s', which is not the upstream of\\n\"\n>  \t\t\t      \"your current branch '%s', without telling me what to push\\n\"\n\nSo, I am not sure if many of the above changes are sensible.  The\nfirst one certainly does not sound like sensible.\n\n> diff --git a/t/t5523-push-upstream.sh b/t/t5523-push-upstream.sh\n> index fdb4292056..c2d11c3f2a 100755\n> --- a/t/t5523-push-upstream.sh\n> +++ b/t/t5523-push-upstream.sh\n> @@ -60,6 +60,86 @@ test_expect_success 'push -u :topic_2' '\n>  \tcheck_config topic_2 upstream refs/heads/other2\n>  '\n>  \n> +default_u_setup() {\n\nStyle. (cf. Documentation/CodingGuildelines).\n\n> +\tgit checkout main &&\n> +\ttest_might_fail\tgit branch --unset-upstream &&\n> +\ttest_config push.default $1 &&\n> +\ttest_config remote.pushDefault upstream\n> +}\n> +\n> +check_empty_config() {\n\nLikewise.\n\n> +\ttest_expect_code 1 git config \"branch.$1.remote\" &&\n> +\ttest_expect_code 1 git config \"branch.$1.merge\"\n> +}\n> +\n> +for i in simple current upstream nothing\n> +do\n> +\ttest_expect_success 'push -u with push.default=$i' '\n> +\t\tdefault_u_setup $i &&\n> +\t\tgit push -u &&\n> +\t\tcheck_config main upstream refs/heads/main &&\n> +\t\tgit push -u upstream main:other &&\n> +\t\tgit push -u &&\n> +\t\tcheck_config main upstream refs/heads/main\n> +\t'\n> +\n> +\ttest_expect_success 'push -u -f with push.default=$i' '\n> +\t\tdefault_u_setup $i &&\n> +\t\tgit push -u -f &&\n> +\t\tcheck_config main upstream refs/heads/main\n> +\t'\n> +done\n> +\n> +for i in simple current upstream nothing matching\n> +do\n> +\ttest_expect_success 'push -u --prune with push.default=$i' '\n> +\t\tdefault_u_setup $i &&\n> +\t\tgit push upstream main:test_u215 &&\n> +\t\tgit push -u --prune >out &&\n> +\t\tcheck_config main upstream refs/heads/main &&\n> +\t\ttest_i18ngrep \"[deleted]\" out &&\n> +\t\ttest_i18ngrep ! \"Branch '\"'\"'test_u215'\"'\"' set up to track\" out\n> +\t'\n> +\n> +\ttest_expect_success 'push -u --mirror with push.default=$i' '\n> +\t\tdefault_u_setup $i &&\n> +\t\ttest_might_fail git branch mirror1 &&\n> +\t\ttest_might_fail git branch mirror2 &&\n> +\t\tgit push -u --mirror &&\n> +\t\tcheck_config main upstream  refs/heads/main &&\n> +\t\tcheck_config mirror1 upstream refs/heads/mirror1 &&\n> +\t\tcheck_config mirror2 upstream refs/heads/mirror2\n> +\t'\n> +done\n> +\n> +for i in '' '-f'\n> +do\n> +\n> +\ttest_expect_success 'push -u $i with push.default=matching' '\n\nDoesn't $i show in the output as-is here?  Quote the test title in\ndouble-quotes, while using single-qoutes around the test body.\n\n> +\t\tdefault_u_setup matching &&\n> +\t\ttest_might_fail git branch test_u &&\n> +\t\ttest_might_fail git branch test_u2 &&\n> +\t\tgit push upstream main:test_u2 &&\n> +\t\tgit push -u $i &&\n> +\t\tcheck_config main upstream refs/heads/main &&\n> +\t\tcheck_config test_u2 upstream refs/heads/test_u2 &&\n> +\t\tcheck_empty_config test_u\n> +\t'\n> +done\n> +\n"},{"id":"445412","messageId":"20220104132839.1209-1-chakrabortyabhradeep79@gmail.com","threadId":"57017","inReplyTo":"xmqqy23wduxp.fsf@gitster.g","subject":"Re: [PATCH v4 1/1] push: make 'set-upstream' have dafault arguments","fromName":"Abhradeep Chakraborty","fromEmail":"chakrabortyabhradeep79@gmail.com","sentAt":"2022-01-04T13:28:39Z","receivedAt":"2022-01-04T13:30:04Z","isPatch":true,"sender":{"key":"chakrabortyabhradeep79@gmail.com","avatar":"https://avatars.githubusercontent.com/u/75240995?v=4"},"body":"Junio C Hamano <gitster@pobox.com> wrote:\n\n> That means if the user says push.default==nothing, we should error\n> out \"git push -u\" as before, but that is not what the change to\n> setup_default_push_refspecs() function does, is it?\n\nYeah. You're right. The current change does not throw error for\npush.default=nothing. Because I thought that for all values of\n`push.default` (except matching), 'git push -u' should create a\nnew branch with the same name as the current local branch. Now, It\nseems that I was wrong.\n\n> So, I am not sure if many of the above changes are sensible.  The\n> first one certainly does not sound like sensible.\n\nActually, I didn't think deeply while commiting the changes. Today,\nI think about it deeply and I realized the following points.\n\n* if push.default='simple' or unspecified then it should not create\n  a new branch on the remote. So, my proposed change of 'git push -u'\n  for push.default='simple' is badly affecting the reason why\n  push.default='simple' was built for.\n\n* if push.default='nothing', It should throw error if no <refspec> is\n  provided. Again, my proposed change is hurting it.\n\n* For push.default=upstream, If an upstream is already defined then\n  'git push -u' should only set that branch as the upstream of the\n  local branch. This already works in git. But if an upstream is not\n  provied, it should throw error. So, I am not sure whether 'git push\n  -u' (with no upstream information) should create a new branch with\n  the same name or not. What do you think about that?\n\n* For push.default=matching, 'git push -u' should set all the existing\n  matching branches as upstream of their respective matching local\n  branches. It also already works. Same for 'push.default'=current also.\n\nSo, to put all in a nutshell, I think that the current behaviour of\n'git push -u' is okay. It also seems that he/she who built the\nsetup_default_push_refspecs() was aware of this.\n\nSorry for the patch request and thanks for reviewing.\n\n> Doesn't $i show in the output as-is here?  Quote the test title in\n> double-quotes, while using single-qoutes around the test body.\n\nYeah. I observed this while testing. But had no idea why this happend\n( as I am very beginner in shell scripting). I was waiting for the review\ncomment for it.\n\nThanks again for reviewing my patch request.\n"},{"id":"445469","messageId":"xmqq35m3ck7s.fsf@gitster.g","threadId":"57017","inReplyTo":"20220104132839.1209-1-chakrabortyabhradeep79@gmail.com","subject":"Re: [PATCH v4 1/1] push: make 'set-upstream' have dafault arguments","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2022-01-04T20:35:51Z","receivedAt":"2022-01-04T20:35:55Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Abhradeep Chakraborty <chakrabortyabhradeep79@gmail.com> writes:\n\n> * For push.default=upstream, If an upstream is already defined then\n>   'git push -u' should only set that branch as the upstream of the\n>   local branch. This already works in git. But if an upstream is not\n>   provied, it should throw error. So, I am not sure whether 'git push\n>   -u' (with no upstream information) should create a new branch with\n>   the same name or not. What do you think about that?\n\nI think erring on the side of caution is more sensible than blindly\nassuming that the user wants a new branch with the same name.\n\nThank you for working on the topic and thinking its ramifications\nthrough.\n\n\n"}]}