Jer
Jer

Reputation: 5648

How can I create a branch and new remote tracking branch at once?

I normally create a new branch via git checkout -b ... and the first time I push to it I'm prompted to use the --set-upstream argument to create a new remote tracking branch. Can I do this in one command when I create the branch? I have tried the following (per instructions here):

   % git checkout -b mybranch20200423 --track origin/mybranch20200423                          
fatal: 'origin/mybranch20200423' is not a commit and a branch 'mybranch20200423' cannot be created from it

   % git checkout -b mybranch20200423 origin/mybranch20200423        
fatal: 'origin/mybranch20200423' is not a commit and a branch 'mybranch20200423' cannot be created from it

Am I doing something wrong? Why does git think that 'origin/mybranch20200423' is supposed to be a commit?

Upvotes: 1

Views: 1051

Answers (2)

torek
torek

Reputation: 489828

See LeGEC's answer.

As an alternative, consider creating the branch on the remote first:

git fetch origin            # update origin/master if/as needed
git push origin origin/master:newbranch

The first step, which you only need if your remote-tracking branches may be out of date (but it's safe to use any time), has your Git call up their Git, get any new commits from them, save them in your clone, and update all your origin/* names. (I like to use --prune here too, but I do that with git config fetch.prune true so that Git just does it automatically.)

The git push step has your Git call up the Git over at origin and asks them to create-or-update their branch-name newbranch based on your origin/master, which—if you have updated recently enough—is in sync now with their master. That is, you're asking them to create their branch newbranch based on (your copy of) their master, since newbranch does not yet exist in their repository.

Assuming they obey this polite "create or update" request, newbranch now exists on origin. Now that newbranch does exist on origin, your own Git creates origin/newbranch.

Now you can simply run:

git checkout newbranch

which will discover that, gosh, you don't have a branch named newbranch, but you do have origin/newbranch, so it should create newbranch from origin/newbranch. If your Git predates Git 2.23, you might want to use git checkout --track origin/newbranch to avoid an ambiguity, and if it's 2.23 or later, you might want to use git switch newbranch, but in general this mostly works.

I don't do any of the above: I just create the branch locally myself as appropriate. Then, on the first git push, I use the shorthand git push -u origin HEAD (after double checking, with git status, that I'm on the right branch and everything is ready).

Upvotes: 1

LeGEC
LeGEC

Reputation: 52176

I do not have all the details of the git branch command, but it looks like the --track and --set-upstream options only expect existing branch names :

$ git branch --set-upstream origin/foo/bar
error: the requested upstream branch 'origin/foo/bar' does not exist
hint: 
hint: If you are planning on basing your work on an upstream
hint: branch that already exists at the remote, you may need to
hint: run "git fetch" to retrieve it.
hint: 
hint: If you are planning to push out a new local branch that
hint: will track its remote counterpart, you may want to use
hint: "git push -u" to set the upstream config as you push.

Providing a remote branch name can be done when pushing using git push -u <branchname>.


To handle the "push a new branch" case, I use the following command :

git push origin -u $(git rev-parse --abbrev-ref HEAD)
  • git rev-parse --abbrev-ref HEAD will give the name of the current active branch,
  • $(...) injects it as an argument to the outer command,
  • git push -u <branchname> will push current commit to remote branch <branchname> and add origin/branchname as the tracked upstream branch.

I added an alias for it :

git config --global config.pushnew '! git push origin -u $(git rev-parse --abbrev-ref HEAD)'

so that typing :

git pushnew

in a terminal from a new branch pushes my new branch without needing to repeat the branch name.

Upvotes: 3

Related Questions