Como configurar o git push para configurar o upstream automaticamente sem -u?

100

eu quero git push origin definir automaticamente a referência upstream quando envio um branch criado localmente pela primeira vez.

Eu sei git push -u, mas não quero ter que pensar se já usei -uou não antes ou se de outra forma defini uma referência upstream. Em outras palavras, quero git pushter automaticamente o efeito de git push -uem qualquer push de um branch que ainda não tenha um upstream.

Isso é possível? Se for necessário um alias ou script de utilitário, tudo bem.

John
fonte
2
Você verificou se é possível usar as opções push.defaulte branch.<name>.mergeem git-config (1) ?
5
Eu push.defaultconfigurei para current- é como posso dizer git push originsem um refspec ou upstream. Mas isso não ajuda com a configuração automática do upstream.
John

Respostas:

61

Você pode configurá-lo git configusando git config --global push.default current.

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

Andrea Bergonzo
fonte
8
Eu tenho esse conjunto - é como posso dizer git push originsem um refspec ou upstream. Mas isso não ajuda com a configuração automática do upstream.
João
Funciona para mim: +1:
Tim Strijdhorst
Sim, como @John diz, é importante ter em mente que isso não faz com que a filial local rastreie a remota; ele apenas cria o branch remoto com o mesmo nome do local.
waldyrious de
Bom o suficiente se você só precisar push, por exemplo, apenas um desenvolvedor está em seu branch, que edita apenas uma cópia de um repo.
superarts.org
26

Como não acho que isso seja possível usando git config, aqui está o que você pode fazer no bash:

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

Se a filial atual tem uma filial de rastreamento remoto, ele chama, git pushcaso contrário, chama git push -u

peixe mecânico
fonte
24
Agora você pode fazer git config --global push.default current.
Andrea Bergonzo
2
@AndreaBergonzo esta é a única boa resposta para mim, você pode adicioná-la como uma resposta?
pdem
6
@AndreaBergonzo, @pdem - observe que push.default=currentapenas cria um branch no repositório remoto com o mesmo nome do branch local, mas não define o branch local para rastrear o remoto. Não sei por que esse é o caso, mas vale a pena ter em mente.
waldyrious de
22

Nota: o fato de que a nova política de push padrão " simple" depende de um branch ter um upstream significa que: a
configuração de um branch upstream é vista como uma etapa voluntária, não uma automatizada oculta

Quando " git push [$there]" não diz o que enviar, usamos a semântica tradicional de "correspondência" até agora (todos os seus branches foram enviados para o remoto contanto que já existam branches com o mesmo nome lá).

Usaremos a simplesemântica " " que empurra o branch atual para o branch com o mesmo nome, somente quando o branch atual está configurado para integração com aquele branch remoto .
Existe uma variável de configuração de preferência do usuário " push.default" para alterar isso.


Portanto, a partir da resposta do Mechanicalfish , você pode definir um alias, com as aspas duplas corretas ( ) escaped ( ):"\"

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

git pu origin

Sc0ttyD propõe nos comentários o seguinte alias:

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

Em várias linhas:

alias gpu='[[ -z $(git config "branch.$(git symbolic-ref --short HEAD).merge") ]] && 
           git push -u origin $(git symbolic-ref --short HEAD) || 
           git push'
VonC
fonte
1
Obrigado por mostrar como configurar o alias. Não estou claro sobre a conexão ou relevância da primeira parte de sua resposta.
John
2
@John, meu ponto é: você contornaria uma etapa que deveria ser intencional. Você pode configurar esse alias, mas eu queria deixar claro para outros leitores porque essa -uopção explícita existe e porque não há uma configuração para tornar essa opção automática (daí o alias).
VonC
2
Eu tenho uma lista de aliases de zsh em meu .zshrc. alias gpu='[[ -z $(git config "branch.$(git symbolic-ref --short HEAD).merge") ]] && git push -u origin $(git symbolic-ref --short HEAD) || git push'
Modifiquei
2
@ Sc0ttyD Interessante, obrigado. Eu incluí seu comentário na resposta para mais visibilidade.
VonC
17

Eu tive o mesmo problema. Encontrei este alias (.gitconfig)

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

Uso: git trackuma vez por nova filial (atualmente em check-out). Em seguida, basta empurrar normalmente :)

Frexuz
fonte
15

As respostas de @VonC e @Frexuz são úteis, mas ambas as soluções geram um erro para mim. Usando ambas as respostas, eu construí algo que funciona para mim:

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

Isso resulta na execução de git push -u origin $BRANCHNAMEou git push, dependendo se seu upstream (propriedade branch.$BRANCHNAME.merge) está definido.

Inserir este alias na linha de comando exigirá códigos de escape, então provavelmente é mais fácil usar um editor para inserir no arquivo correto ( $HOME/.gitconfig(global), .git/config(local) ou /etc/gitconfig(sistema))

Marca
fonte
3
Esta é a resposta mais direta e completa. Para abrir o editor padrão sem procurar o arquivo, você podegit config --global -e
Adam Tolley
5

Resposta curta

Se você realmente gosta de ser explícito e usar a -uopção quando necessário, mas simplesmente não deseja digitar o todo:

git push -u origin foo

Então você pode usar o seguinte alias:

[alias]
    push-u = !git push -u origin $(git symbolic-ref --short HEAD)

E simplesmente digite:

git push-u

Resposta longa

Normalmente, a necessidade de -u(abreviação de --set-upstream) é quando acabamos de criar um novo branch local e commitar, e queremos colocá-lo no upstream. O repositório remoto ainda não tem o novo branch, então precisamos dizer ao git para criar e rastrear o branch remoto antes de enviar o commit. Isso é necessário apenas para o primeiro push no branch. Aqui está um cenário típico:

git checkout -b foo         # Create local branch
git commit -m "Foo"         # Create local commit
git push -u origin foo      # Create and track remote branch, and push commit
git commit -m "Bar"         # Create local commit
git push                    # Push commit

Pessoalmente, gosto da necessidade de ser explícito com git push -u ao criar o branch remoto: é uma operação bastante significativa, compartilhar um novo branch para o mundo.

No entanto, odeio que tenhamos que escrever explicitamente git push -u origin foo. Não só é difícil digitar, mas mais importante, é bastante sujeito a erros! É fácil cometer um erro ao digitar o nome do branch, e o novo branch remoto não terá o mesmo nome do seu branch local! Na maioria dos casos, realmente, você deseja que o repositório upstream sejaorigin , e o branch upstream tenha o mesmo nome do seu branch local.

Portanto, estou usando o seguinte alias no meu .gitconfig, que é um subconjunto da excelente resposta fornecida por Mark :

[alias]
    push-u = !git push -u origin $(git symbolic-ref --short HEAD)

Agora, podemos fazer o seguinte, que ainda é explícito, mas menos sujeito a erros:

git checkout -b foo         # Create local branch
git commit -m "Foo"         # Create local commit
git push-u                  # Create and track remote branch, and push commit
git commit -m "Bar"         # Create local commit
git push                    # Push commit
Boris Dalstein
fonte
4

Resolvi esse problema usando este script Bash simples. Não funcionará em branches existentes, mas se você criar todos os seus branches com esta função, você sempre terá seu branch upstream definido automaticamente.

function con { git checkout -b $1 && git push --set-upstream origin $1; }

O $ 1 representa o primeiro argumento que você passa depois, conentão é como fazer:

git checkout -b my-new-branch && git push -u my-new-branch

... apenas fazendo isso:

con my-new-branch
JT Jobe
fonte
2

Simplesmente:

$ alias gush="git push -u origin HEAD"
djanowski
fonte
2
Título da pergunta: "Como configurar git push para configurar automaticamente o upstream sem -u?" Descrição: "Eu sei git push -u, mas ...". Portanto, isso não responde à pergunta.
John
2
@John Eu atualizei minha resposta para sugerir um apelido simples.
djanowski
2
@John Ele responde à pergunta agora?
djanowski de
1
@ ILI4SK4RIM Obrigado, é uma loucura que minha resposta seja a mais simples, ainda é -1 ¯_ (ツ) _ / ¯
djanowski
1

Se você quiser usar os recursos integrados do git apenas com o menor número de chaves possíveis, basta digitar:

$ git push -u o tab H tab

e o autocompletar lhe dará $ git push -u origin HEAD

Para habilitar o autocomplate no OSX, configure um ~/.git-completition.basharquivo com este conteúdo e adicione as seguintes linhas ao seu ~/.bash_profilearquivo e reinicie o seu terminal:

# git branch autocomplete
if [ -f ~/.git-completion.bash ]; then
  . ~/.git-completion.bash
fi
eval "$(pyenv init -)"
eval "$(pyenv virtualenv-init -)"

Afeta terminais integrados também, como aquele em vscode etc.

Gazdagergo
fonte
autocompletar? git não tem autocomplete. Seu shell (bash? Zsh?) Possui um conjunto de regras de preenchimento automático carregadas. Você pode fornecer informações sobre qual conjunto de regras de preenchimento automático está usando e onde obtê-las?
vy32
Oh, de fato, obrigado. Concluí minha resposta com minhas configurações de preenchimento automático.
gazdagergo
Sem saber o conteúdo do seu arquivo ~ / .git-completed.bash, sua resposta não é operacionalizável.
vy32
1
Bom ponto. Eu encontrei a fonte do meu git-completition.bashe acrescentei à minha resposta.
gazdagergo