On Thu, Oct 07, 2021 at 05:51:02PM +0200, Uwe Brauer wrote:

[...]
>> What command are you currently using to push "all main branches" or had you
>> also implicitly asked how to do that?

> No, I thought either 
> 
>  git push 
> 
> Or 
> 
> git push --all 
> 
> Does this
> 
>> The full form of the `git push` command is
> 
>>   $ git push <remote> <refspec> [<refspec> ...]
[...]
> >   $ git push origin 'refs/heads/pub/*:refs/heads/*'
[...]
>> The inconvenience is that you need to remember to create your local branches
>> using that convention (and rename current branches - which is easy to do by
>> using the `git branch -M` command).

> I admit I am confused: I thought I should use the same name as in
> remote, so master should be master and not pub_master
> 
> Most likely there is something fundamental I don't understand.

I think it's just your mindset: to assume the names of the branches should
match is a thought which comes naturally, I would admit. But in reality Git
maintans a rather asymmetrical model when it comes to communicating with
remote repositories, and this requires certain getting into.
I'll try to put things into som perspective for you.

I think the root cause of users not "getting" the asymmetry existing in
working with remote repositories is that they:

 * Begin considering the whole model starting at the central, rendez-vouz,
   repository - basically perceiving it as _the_ repository, while all the
   others - which are local clones of that central one, done by the
   developers - being its satellites, "downstreams".

 * Do not put much thought into the fact a Git repository is not bound
   to communicate with a single remote, and moreover - even with multiple
   remotes maintaining the same project.

Let's consider these things more closely.

First, in this age and time we're really accustomed to the workflow when you
clone some centrally-hosted repository and start pushing your work to it and
fetching the work done by others from it. Moreover, when it comes to creating
a repository for brand new object, people sort of automatically reach for one
or another Git hosting solution - it could be Github, Bitbucket etc for F/OSS
or private projects or, say, an on-premises corporate GitLab instance - to
first create an empty (or pre-populated from some template) repository through
the UI offerred by that solution, and that repository is - again -
subsequently cloned locally by those who intend to work on the project.
In other words, typically you end up cloning some repo in any case, and this
instills some warped mindset which makes you think that there is always some
main, reference, blueprint, master repository everyone sends their work to -
just like there was at the times of centralized VCS systems such as
Subversion, VSS etc.

But this is not really the case. Any Git repository is completely
self-sufficient (modulo some advanced black-magic facilities such as making
use of objects of another repository, but let's not digress) and
free-standing. It's perfectly possible to create and use locally a Git
repository which will never ever communicate with any remote repository.
Of course, when you run `git init` locally you end up with a repository with
these exact properties: it does not yet know about any remotes, and will
happily live without this knowledge.
Still, at any point in time, it's possible to teach a local repository about a
remote repository and start working with it.

Second, you can freely fetch objects from _any_ techincally accessible Git
repository into any local Git repository, and the same holds true for pushing.
And I really mean it: it's perfectly possible to fetch a branch from a Linus
Torvalds' Linux repository into your local repository containing your weekend
toy project. There are absolutely no restrictions here: Git repositories do
not somehow "know" which project's data they maintain - there's no
"identifier" which is checked when two instances of Git exchange data between
two Git repositories.

>From this, naturally comes the possibility to have any number of remote
repositories configured in a given local Git repository; and these
repositories - again - need not to maintain logically the same project.
The fact `git clone` automatically configures a single remote named "origin"
and pointing back to the repository which is cloned is just a useful feature
which is totally not required.
And to add to this, you do not even need to configure a remote repository to
fetch data from it or push data to it - `git fetch` and `git push` are
perfectly able to operate on URLs. A useful mind exercise based on this fact:
when you do

  $ git fetch https://github.com/torvalds/linux i915-bug-fix

what branch should Git create and/or update in your local clone?

I hope, a certain pucture should be emerging in your mind for now ;-)
A branch named "master" or "feature" or whatever in any given repository might
or might not have some relation to a same-named branch in your local
repository. Moreover, suppose you work on a certain project but your colleague
Joe pushes his work to github.com/jrhacker/project and another your colleague
Mary pushes her work to bitbucket.org/maryjane/project (such "triangle"
workflow is not actually uncommon for hard-core projects like Linux), and so
you have at least two remotes configured in your local Git repository - one
to communicate with the Joe's repo and another one - for Mary's. Now think of
the fact both those persons might have a branch named "master" in ther repos.
If you think that your local branch "master" tracks a same-named branch in a
remote repository, which "master" is that - Joe's or Mary's?
Now let's think of a more complicated case: your local repository communicates
with two repositories maintaining _different_ projects, and they both contain
a branch named "master". In the Joe and Mary case you could their "master"
branches should be "sort of the same" and so your branch "master" sort of
tracks them both, but if the projects are really disjoint, a branch in the
first of them having the same name as a branch in the second most probably
will have no semantic relation between each other.

OK, so all this brings us to the model implemented by Git, and it has the
following properties:

 * Your local branches are truly yours, they are never updated automatically
   when you fetch from remote repositories.
   Your local repository is completely free-standing and self-sufficient.

 * If you have named remotes - such as that well-known "origin", - fetching
   from such remote will automatically create and maintain so-called
   "remote branches" (the terminology is not too good, I know) which are
   "namespaced" to separate them from your local branches.

   This makes it possible to properly manage such branches - for instance,
   "master" fetched from "origin" ends up being remotes/origin/master
   in your local repo and "master" fetched from "joes" becomes
   remotes/joes/master. Note that this still have nothing to do with your
   local branch "master".

 * Only you decide what local branches you update with which data fetched
   from the remotes, and which local branches you push to which remote
   branches. Git sometimes helps you with setting such relations in a sensible
   way - for instance, when you `git clone` a repository, a configuration
   entry is added to the clone making plain `git clone origin` force-update
   all the remote branches tracking that remote repository in your local
   repo. But this setting can be removed or changed at will.

So all this leads us to what I have described in my first mail to this thread:
you can name your local branches in any way you see fit. This will rob you of
certain shorthands such as

  $ git push origin HEAD

(which means "push the tip of whatever local branch I have currently checked
out to the same-named branch on origin") but otherwise everything will work.

-- 
You received this message because you are subscribed to the Google Groups "Git 
for human beings" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to git-users+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/git-users/20211008105515.pmoyki24klj4mlzw%40carbon.

Reply via email to