How to configure git push to automatically set upstream without -u?

git
34,449

Solution 1

You can configure it with git config using git config --global push.default current.

Docs: https://git-scm.com/docs/git-config/#Documentation/git-config.txt-pushdefault

Solution 2

Since I don't think this is possible using git config, here is what you can do in bash:

[[ $(git config "branch.$(git rev-parse --abbrev-ref HEAD).merge") = '' ]] && git push -u || git push

If the current branch has a remote tracking branch, it calls git push otherwise it calls git push -u

Solution 3

2022: Git 2.37 proposes:

git config --global push.autoSetupRemote true

push.autoSetupRemote

If set to "true" assume --set-upstream on default push when no upstream tracking exists for the current branch;

This option takes effect with push.default options 'simple', 'upstream', and 'current'.

It is useful if by default you want new branches to be pushed to the default remote (like the behavior of 'push.default=current') and you also want the upstream tracking to be set.
Workflows most likely to benefit from this option are 'simple' central workflows where all branches are expected to have the same name on the remote.


2013: Note: the fact that the new default push policy "simple" relies on a branch having an upstream one means that:
setting an upstream branch is viewed as a voluntary step, not an hidden automated one

When "git push [$there]" does not say what to push, we have used the traditional "matching" semantics so far (all your branches were sent to the remote as long as there already are branches of the same name over there).

We will use the "simple" semantics that pushes the current branch to the branch with the same name, only when the current branch is set to integrate with that remote branch.
There is a user preference configuration variable "push.default" to change this.


So building up from mechanicalfish's answer, you can define an alias, with the right double quotes (") escaped (\"):

git config alias.pu "![[ $(git config \"branch.$(git rev-parse --abbrev-ref HEAD).merge\") = '' ]] && git push -u || git push"
git pu origin

Sc0ttyD proposes in the comments the following alias:

alias gpu='[[ -z $(git config "branch.$(git symbolic-ref --short HEAD).merge") ]] && git push -u origin $(git symbolic-ref --short HEAD) || git push'

In multiple lines:

alias gpu='[[ -z $(git config "branch.$(git symbolic-ref --short HEAD).merge") ]] && 
           git push -u origin $(git symbolic-ref --short HEAD) || 
           git push'

Solution 4

I've had the same problem. I've made this alias (from my .gitconfig)

[alias]
    track = "!git branch --set-upstream-to=origin/`git symbolic-ref --short HEAD`"

Usage:

  1. Once per new branch (currently checked out): git track
  2. Push as normal :)

Solution 5

The answers by @VonC and @Frexuz are helpful, but both of their solutions produce an error for me. Using both of their answers, I cobbled together something that works for me:

    [alias]
    pu = ![[ $(git config "branch.$(git symbolic-ref --short HEAD).merge") = '' ]] && git push -u origin $(git symbolic-ref --short HEAD) || git push

This results in executing either git push -u origin $BRANCHNAME or git push, depending on whether its upstream (property branch.$BRANCHNAME.merge) is defined.

Entering this alias on the command line will require escape codes, so it's probably easiest to use an editor to insert into the correct file ($HOME/.gitconfig (global), .git/config (local), or /etc/gitconfig (system) )

Share:
34,449
John
Author by

John

Updated on September 30, 2021

Comments

  • John
    John about 1 year

    I want git push origin to automatically set the upstream reference when I push a locally-created branch for the first time.

    I know about git push -u, but I don't want to have to think about whether or not I've used -u before or otherwise set an upstream reference. In other words, I want git push to automatically have the effect of git push -u on any push of a branch that doesn't already have an upstream.

    Is this possible? If it requires an alias or utility script, that's fine.

  • John
    John about 9 years
    Thanks for showing how to set up the alias. I'm not clear on the connection to or relevance of the first part of your answer though.
  • VonC
    VonC about 9 years
    @John my point is: you would circumvent a step which is supposed to be an intentional one. You can setup that alias, but I wanted to make clear to other readers why this explicit -u option exists, and why there isn't a config for making said option automatic (hence the alias).
  • John
    John over 6 years
    Question title: "How to configure git push to automatically set upstream without -u?" Description: "I know about git push -u, but ...". So this doesn't answer the question.
  • djanowski over 6 years
    @John I updated my answer to suggest a simple alias.
  • djanowski over 6 years
    @John Does it answer the question now?
  • Adam Tolley
    Adam Tolley almost 6 years
    This is the most straightforward and complete answer. To open up the default editor without hunting for the file, you can git config --global -e
  • Sc0ttyD
    Sc0ttyD about 5 years
    I have a list of zsh aliases in my .zshrc. I modified this answer to create the following zsh alias: alias gpu='[[ -z $(git config "branch.$(git symbolic-ref --short HEAD).merge") ]] && git push -u origin $(git symbolic-ref --short HEAD) || git push'
  • VonC
    VonC about 5 years
    @Sc0ttyD Interesting, thank you. I have included your comment in the answer for more visibility.
  • djanowski about 5 years
    @ILI4SK4RIM Thanks, it's crazy that my answer is the simplest one, yet it's -1 ¯_(ツ)_/¯
  • Andrea Bergonzo
    Andrea Bergonzo almost 5 years
    You can now do git config --global push.default current.
  • pdem
    pdem about 4 years
    @AndreaBergonzo this is the only good answer to me, may you add it as an answer?
  • John
    John about 4 years
    I have that set -- that's how I can just say git push origin without a refspec or upstream. But it doesn't help with automatically setting the upstream.
  • waldyrious
    waldyrious almost 4 years
    @AndreaBergonzo, @pdem -- note that push.default=current only creates a branch in the remote repository with the same name as the local branch, but does not set the local branch to track the remote one. I'm not sure why this is the case, but it's worth keeping in mind.
  • waldyrious
    waldyrious almost 4 years
    Yeah, as @John says, it's important to keep in mind that this does not make the local branch track the remote one; it just creates the remote branch with the same name as the local one.
  • superarts.org
    superarts.org over 3 years
    Good enough if you just need to push, e.g. only one developer is on his branch, who only edits one copy of a repo.
  • Ami over 2 years
    autocomplete? git doesn't have autocomplete. Your shell (bash? zsh?) has a set of autocomplete rules loaded. Can you provide information regarding which set of autocomplete rules you are using, and where to get them?
  • gazdagergo
    gazdagergo over 2 years
    Oh, in deed thanks. I've completed my answer with my autocomplete settings.
  • Ami over 2 years
    Without knowing the contents of your file ~/.git-completion.bash, your answer is not operationalizable.
  • gazdagergo
    gazdagergo over 2 years
    Good point. I found the source of my git-completition.bash and added to my answer.
  • Alex Weissnicht
    Alex Weissnicht over 1 year
    Exactly, with this alias one will also see the commits the branch is ahead/behind the upstream one.
  • mherzog
    mherzog about 1 year
    You actually can. See stackoverflow.com/a/53322776/11262633.
  • Tim Goodman
    Tim Goodman 10 months
    @mherzog push.default current does not actually set the upstream, it just pushes to a branch of the same name. So for example that means you won't get the "Your branch is up to date / behind / ahead" message when running git status.
  • Tim Goodman
    Tim Goodman 10 months
    That said, it will let you set the upstream with just git push -u instead of git push -u origin branch_name. But you still have to remember the -u on the first push if you want to set the upstream.