[plt-dev] Q. about local branches

From: Eli Barzilay (eli at barzilay.org)
Date: Fri Apr 23 15:11:44 EDT 2010

On Apr 22, John Clements wrote:
> What I learned today: local branches don't get propagated to the master repository on a 'push' unless there's some remote tag that refers to them.  
> 
> I had heretofore assumed that I could use 'git push' in much the
> same way as 'svn commit' to guarantee, e.g., that when leaving work
> nothing was "trapped" on that machine.  IIUC, the behavior of local
> branches means that this isn't so.
> 
> Question: is there some easy way to ensure that the local repository
> is fully mirrored on the server?

Yes, see the `--all' flag in the `git-push' man page.  But this is not
something that should be used frequently, or even not ever used.  One
of the huge benefits of git is that you can create lots of branches
very quickly, for any kind of work -- and regardless of having user
branches on the server or not, you would not want to push such random
branches to the server.


On Apr 23, Noel Welsh wrote:
> I don't know of a way. You gotta adapt your thinking: git comes from
> a world where random beardos are hacking away on the Linux kernel
> and there is no concept of a master repository. People pull patches
> from multiple sources and distribute their changes to multiple
> unrelated groups. In this situation mirroring repositories doesn't
> make a great deal of sense. PLT's usage is much much much more
> centralised.

I'd drop a few "much"s there.  IMO, the "centralized" aspect of the
server is *not* fundamentally different than the way the linux kernel
or git are developed.  The only technical difference is that there
you get "central people" that pull changes into their repositories
whereas a server is a way to do it automatically.  If, for example,
I'd be manually maintaining the official plt repository and if I would
decide to *always* accept pushes from a set of known people, then the
result would be identical.


> If you want to create a branch that is propagated on the server you
> have to inform the server of this. This is known as a "remote branch".
> Eli and I had a discussion about the best way to do this. Here's the
> soln:
> 
> git checkout -b branch-name
> git push origin branch-name --set-upstream
> 
> First command creates a new branch. The second command sends the
> branch to the server called origin and tells the local repository to
> follow changes on the server's branch. Now any changes made on your
> local branch branch-name can be pushed to the server and git pull will
> get any changes from the server.

Here are some more options:

* git checkout foo
  If there is a remote `foo' branch, this will create a local `foo'
  branch and set it to track the remote one.  (If you already have a
  `foo' branch, then this will just check it out.)

* git checkout -t -b foo
  This creates a local `foo' branch that tracks whatever branch you
  were on.  If you were on the `master' branch, then this means that
  changes on the new branch will be pulled from/pushed to that master
  branch.  So you can have your own network of branches pulling and
  pushing from each other.

* git config --global push.default tracking
  It is probably a good idea to do this.  What Sam ran into a few days
  ago is that `git push' without an explicit remote and branch name
  will push all branches to the remote.  This configuration option
  makes it push the current branch only (if you do the above, then
  this would make it push the changes from your `foo' to your
  `master').  This option could also be set to "current", and the
  man page says that in this case `git push' will push the current
  branch to a branch of the same name -- so this seems fitting if you
  want your branches to usually track remote ones (that is, you don't
  like the above option).


On Apr 23, Michael Sperber wrote:
> [...]
>   remotes/origin/ryanc/sp-parser-tools
>   remotes/origin/samth/match-for
> [...]

Yes, the convention -- for now (see other thread on private clones on
the server) -- is "<user>/<branch>".  The "remotes/origin" prefix
means that you got these branches from a remote repository which you
labeled as "origin" (and on that repository there is no such prefix,
of course).


> I'm afraid to play with this, since I don't exactly how these names are
> constructed.  I'm guessing:
> 
> git checkout -b <whatever-branch-name-I-please>
> git push origin sperber/<a-branch-name-like-"mred-contracts"-above> --set-upstream
> 
> Correct?  

No -- you won't have a `sperber/...' branch to push.  You probably
want this instead:

  git checkout -b sperber/whatever-you-want
  git push origin sperber/whatever-you-want --set-upstream

It shouldn't be surprising now that you *could* have the branch in
your own repository use any name you like, but push it with a more
descriptive name out:

  git checkout -b mywork
  git push origin mywork:sperber/add-foo-feature-to-blah-package

But that's likely to be confusing later on.


On Apr 23, Kevin Tew wrote:
> If you create a branch on your local machine, you must explicitly push 
> it to the origin server, the first time.
> git push origin NEWBRANCHNAME

You could also create the remote branch first:

  git push origin master:eli/foo
  git checkout eli/foo

will create an `eli/foo' branch on the server from my `master', and
then check it out.


> 'git push' pushes all local branches to the remote origin, when a
> remote refspec(branch name) exists that matches the local
> refspec(branch name)

See the above setting.


> Just to further clarify:
> 
> git checkout NEWBRANCHNAME --track OTHER_REFSPEC creates a new
> branch called NEWBRANCHNAME that will, by default, pull from
> OTHER_REFSPEC when NEWBRANCHNAME is your current branch and you run
> 'git pull'

(I suspect that talking about "REFSPEC" is not helping anyone at this
point.)

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!


Posted on the dev mailing list.