0

Now by git push docs ,

If git push [<repository>] without any <refspec> argument is set to update some ref at the destination with <src> with remote.<repository>.push configuration variable, :<dst> part can be omitted—​such a push will update a ref that <src> normally updates without any <refspec> on the command line. Otherwise, missing :<dst> means to update the same ref as the <src>.

I have problem understanding this.

What I understood is :

It will consult remote.origin.push value and try to resolve refspec.

But what does it mean ..​such a push will update a ref that <src> normally updates without any <refspec> on the command line.Otherwise, missing :<dst> means to update the same ref as the <src> ?

Can some one give an example of remote.origin.push and then explain what this clause (of git doc as highlighted above) really means to say ?

Edit : I understand how git push origin will behave but I am not able to relate that to above as how git doc wants to tell us by above paragraph.

Number945
  • 4,631
  • 8
  • 45
  • 83
  • _​such a push will update a ref that normally updates without any on the command line. Otherwise, missing : means to update the same ref as the _ - it will update the upstream branch. If there is no upstream branch, it will update the branch in the remote of the same name. – pishpish Sep 18 '18 at 16:33
  • `​such a push will update a ref that normally updates without any on the command line` - Are we explicitly providing or is it picking from `remote.origin.push` ? What does he mean by 'normally updates' ? – Number945 Sep 18 '18 at 16:44
  • Possible duplicate of [Run git push, pull and fetch without refspec argument](https://stackoverflow.com/questions/34523494/run-git-push-pull-and-fetch-without-refspec-argument) – phd Sep 18 '18 at 17:12
  • https://stackoverflow.com/search?q=%5Bgit%5D+push+without+refspec – phd Sep 18 '18 at 17:12
  • @phd , I have read the answer and I understand how git push will work without ref spec. I knew it earlier too. But my question is different. I am not able to relate that to the language used in git doc as mentioned above. My problem relate to the way ref spec parts are explained in above language. – Number945 Sep 19 '18 at 19:29

1 Answers1

1

For git push there are a lot of defaults. Let's start with clearly separating out the various pieces of syntax. The syntax, abbreviated a bit further to the parts of interest, goes like this:

git push [options] [repository [refspec ...]]

The repository argument is typically the name of a remote, such as origin, but could be a URL. If no repository argument is specified on the command line, no refspec can be specified either: the options are prefixed by dashes, and whatever's not dash-prefixed, the first word (as split into argv elements by whatever invokes C-compiled programs on the system in question) is the repository, and additional words are the refspecs. However, it is definitely possible to give a repository without giving a refspec. For instance, git push lacks both, while git push origin has a repository but lacks a refspec.

The case we are interested in here is when the refspec isn't on the command line. However, it works the same as when the refspec is on the command line—it's just that the places Git looks, in order to find some refspec or refspecs, can be set in the configuration.

Let's say that the repository specified on the command line was origin, i.e., you ran git push origin. Git will, as you said, check your configuration to see if you have a remote.origin.push setting. Let's say further that, initially:

git config --get remote.origin.push

prints the string develop:benjamin_develop.

This is a refspec that has both <src> and :<dst> parts, so Git treats it as develop:benjamin_develop.

Now let's say you run:

git config remote.origin.push develop

i.e., take away the :benjamin_develop part of the setting. You then run git push origin again. Now the implied refspec is just develop: it is missing its :<dst> part.

The paragraph you quoted is pretty confusing (it confused me), but after experimentation—see comments below—we found that it acts the same as:

git push origin develop

on the command line, which acts the same as:

git push origin develop:develop

i.e., the :<dst> part is just the same as the :<src> part, regardless of the current push.default setting.

(I think the documentation here could be clearer. The fundamental problem is that Git's behavior has grown and changed a lot over time. The remote.<remote>.push setting did not exist in older versions of Git, so at some point, when it was added, someone had to add a paragraph to the documentation to match. At this point, the documentation as a whole could be refactored to eliminate redundancy, but no one has done that.)

torek
  • 448,244
  • 59
  • 642
  • 775
  • Awesome but just one small doubt. according to [this answer](https://stackoverflow.com/a/50237713/2844702) , `push.default` will be used only as last resort when even `remote.origin.push` is not configured. Now in our example if `remote.origin.push` = develop , then why would git consult `push.default` for `git push origin develop` ? – Number945 Sep 19 '18 at 23:17
  • 1
    It's tricky because `push.default` controls multiple things. If there's no refspec at all, `push.default` has `simple`, `matching`, etc., and `matching` is not expressible as a refspec (well, no, it is: `:`). But here we have a refspec; it's just missing a `:`. So now we need to know: would `git push origin src` push to src's current upstream setting, or only to a branch literally named `src`? That's controlled—partly—by `push.default`. (So, now you get to enumerate all five `push.default` settings and see how they behave!) – torek Sep 19 '18 at 23:42
  • In my local , I tested this behaviour. My `push.default`=simple. Created a new branch from master , say `myBranch`, made some commits and then I did `git push origin myBranch` . It pushed it to github and created new branch at github. I think it is safe to conclude that `push.default` is not consulted and it is expanded to `myBranch:myBranch` ? I had set my remote repo to github. Just wanted to confirm once ? The new branch I created did not had any upstream initially. – Number945 Sep 20 '18 at 00:58
  • If you ran `git push orgin mybranch` you were not using the `remote.origin.push` setting. You could try configuring `push.default` to `upstream`, setting the upstream of `mybranch` to `origin/different`, set `remote.origin.push` to `mybranch`, check out `master`, and run `git push origin`. That way your *current* branch is `master` (so we find out if Git obeys `remote.origin.push`), and `mybranch` has `origin/different` as its upstream, so we find out of `git push` obeys `push.default` which is set to `upstream`. – torek Sep 20 '18 at 01:11
  • (btw I phrased "we need to know" in the 2nd comment badly: if we actually ran `git push origin src` we'd have given a refspec on the command line! We need to know what would happen if we were *on* `src`, or on some other branch, and ran `git push origin` with no refspec.) – torek Sep 20 '18 at 01:12
  • Okay. I did it. I did not considered the `origin/different`.this shows it did not took `push.default` in consideration. It pushed to `myBranch` only in remote repo. – Number945 Sep 20 '18 at 01:40
  • 1
    OK - so it seems like that line in the documentation is even worse than it looks. It could just say that if the `:` part is omitted, it means `:`. – torek Sep 20 '18 at 01:41