I was wondering whether the master is even necessary because doesn't origin already mean the master branch on the remote repo?
Thank you so much for your help, you are awesome.
CodePudding user response:
The premise of your question is wrong: origin
does not mean a particular branch. More specifically, the word origin
in git push origin
or git fetch origin
(or any similar command) appears in the place where the command wants something called a remote, not in the place where the command wants a branch name.
A remote is ... well, it has multiple purposes, but the main one is that it is a short name for a URL. Suppose the URL is:
https://github.com/someverylongusername/anotherverylongrepositoryname.git
Which is easier to type, the above, or origin
? Git lets you use origin
to mean https://...
, without having to type in https://...
.
Now, if you run:
git push
and leave off both origin
and the branch name, Git makes two assumptions:1
- "I, Git, should find the remote associated with the current branch name."
- "I, Git, should use the current branch name as the branch name."
Note that both of these use (and thus require) the current branch name. The current branch name is the one you have checked out now, because you ran:
git switch foobranch
or:
git checkout barbranch
or whatever. If your most recent switch or checkout was to master
, then the current branch name is master
, and you're probably all set. You can run git push
, or git push origin
: including origin
tells Git that the remote in question is origin
, so it can skip step 1, but it still executes step 2 here.
Now, there are several cases where you can't omit the remote and/or the branch name. And, because the remote name always comes first, if you must provide the branch name, you must also provide the remote name. For instance, if you're currently on your feature/new
, but you want to push your feature/old
, you have two options:
- switch to
feature/old
and rungit push
with no arguments, or - run
git push origin feature/old
—you can't omit theorigin
or thefeature/old
here, even though you really should only need to specifyfeature/old
.
Where this all gets very confusing is the fact that when you have a remote, you have remote-tracking names.2 That is, if you have a remote named origin
, you probably also have the names origin/master
or origin/main
, plus origin/feature/new
and so on. These names all start with origin/
, which helps you remember that these are your own Git repository's copy of the names your Git software saw over in the GitHub Git repository when your Git called up the GitHub software and said to look into the GitHub repository.
(Does that all make sense? You might have to read it through a few times. With clones being so similar, it's like being at a party where everyone is named Bruce. Bruce told Bruce to tell Bruce that Bruce was looking for Bruce. That's clear and obvious, right? Those are five different people.)
Now, there's a place where you can use origin
where Git is looking for a branch or similar name, and in this case, origin
means origin/HEAD
, and origin/HEAD
is what Git calls a symbolic reference. But that's not the case with your basic git push
here.
1These two assumptions are only the default since Git 2.0, but Git 1.x is now more than a decade old and only a few systems still have it. But you can configure Git to act the old way. It's also worth mentioning here that git push
with no arguments, when push.default
is set to simple
as it is since Git 2.0, this only works if the current branch has an upstream set. But this is getting into another—albeit related—question entirely.
2Git documentation officially calls these remote-tracking branch names. I like to leave out the word branch since these are demonstrably not actual branch names. They're just copied from branch names, as seen in some other repository. Old Git documentation is squirrelly about what to call them, too, so people tend to use a lot of mixed terms here.