Criei uma filial local para testar o Solaris e o Sun Studio. Eu então empurrei o ramo a montante. Após confirmar uma alteração e tentar enviá-la:
$ git commit blake2.cpp -m "Add workaround for missing _mm_set_epi64x"
[solaris 7ad22ff] Add workaround for missing _mm_set_epi64x
1 file changed, 5 insertions(+)
$ git push
fatal: The current branch solaris has no upstream branch.
To push the current branch and set the remote as upstream, use
git push --set-upstream origin solaris
Por que tenho que fazer algo especial para isso?
Existe algum caso de uso razoável em que alguém criaria <branch>
, enviará o comando <branch>
para remoto e, em seguida, alegará que <branch>
não é para se comprometer <branch>
?
Eu segui esta pergunta e respondi no Stack Overflow: Envie uma nova ramificação local para um repositório Git remoto e rastreie-a também . Suponho que seja outra instância de uma resposta aceita incompleta ou errada. Ou, é outra instância do Git pegando uma tarefa simples e dificultando.
Aqui está a visão em uma máquina diferente. A ramificação existe claramente, portanto foi criada e enviada por push:
$ git branch -a
alignas
* master
remotes/origin/HEAD -> origin/master
remotes/origin/alignas
remotes/origin/arm-neon
remotes/origin/det-sig
remotes/origin/master
remotes/origin/solaris
git config --add push.default current
, o git push criará automaticamente a ramificação no repositório remoto, se necessário.Respostas:
TL; DR:
git branch --set-upstream-to origin/solaris
A resposta para a pergunta que você fez - que vou reformular um pouco como "preciso configurar um upstream" - é: não, você não precisa configurar um upstream.
Se você não possui upstream para a ramificação atual, o Git altera seu comportamento
git push
e também em outros comandos.A história completa do push aqui é longa e chata e remonta à história anterior à versão 1.5 do Git. Para encurtá-lo muito,
git push
foi mal implementado. 1 A partir da versão 2.0 do Git, o Git agora possui um botão de configuração escrito,push.default
que agora é o padrãosimple
. Para várias versões do Git antes e depois da 2.0, toda vez que você executavagit push
, o Git emitia muito ruído tentando convencê-lo a definirpush.default
apenas para segit push
calar.Você não menciona qual versão do Git está executando, nem se configurou
push.default
, portanto devemos adivinhar. Meu palpite é que você está usando a versão Git 2 pontos-alguma coisa, e que você definiupush.default
parasimple
obtê-lo calar a boca. Precisamente qual versão do Git você tem, e que se qualquer coisa que você tenhapush.default
definido para, não importa, devido a que a história longa e chata, mas no final, o fato de que você está recebendo ainda uma outra queixa de Git indica que o Git é configurado para evitar um dos erros do passado.O que é um upstream?
Um upstream é simplesmente outro nome de filial, geralmente uma filial de rastreamento remoto, associada a uma filial (regular, local).
Cada filial tem a opção de ter um (1) conjunto upstream. Ou seja, todas as ramificações possuem um montante ou um montante não. Nenhuma ramificação pode ter mais de um upstream.
O upstream deve , mas não precisa ser, uma ramificação válida (seja como rastreamento remoto ou local ). Ou seja, se o ramo atual B possuir U a montante , deve funcionar. Se não funcionar - se reclamar que U não existe -, a maioria do Git age como se o upstream não estivesse definido. Alguns comandos, como , mostrarão a configuração upstream, mas marcarão como "ido".
origin/B
master
git rev-parse U
git branch -vv
De que serve um montante?
Se você
push.default
estiver definido comosimple
ouupstream
, a configuração upstream farágit push
, usada sem argumentos adicionais, apenas funcionar.É isso - é tudo o que faz
git push
. Mas isso é bastante significativo, já quegit push
é um dos lugares onde um simples erro de digitação causa grandes dores de cabeça.Se você
push.default
estiver definido comonothing
,matching
oucurrent
, a configuração de um upstream não fará nadagit push
.(Tudo isso assume que sua versão do Git é pelo menos 2.0.)
A montante afeta
git fetch
Se você executar
git fetch
sem argumentos adicionais, o Git descobrirá de qual remoto buscar, consultando a filial atual da corrente. Se o upstream for um ramo de rastreamento remoto, o Git buscará nesse remoto. (Se o upstream não estiver definido ou for uma ramificação local, o Git tentará buscarorigin
.)A montante afeta
git merge
egit rebase
tambémSe você executar
git merge
ougit rebase
sem argumentos adicionais, o Git usará o upstream da ramificação atual. Portanto, reduz o uso desses dois comandos.A montante afeta
git pull
Você nunca deve usar 2 de
git pull
qualquer maneira, mas, se o fizer,git pull
usa a configuração de upstream para descobrir de qual controle remoto buscar e, em seguida, qual ramificação deve ser mesclada ou restaurada. Ou seja,git pull
faz o mesmo quegit fetch
- porque na verdade é executadogit fetch
- e depois faz o mesmo quegit merge
ougit rebase
, porque na verdade executagit merge
ougit rebase
.(Em geral, você deve executar essas duas etapas manualmente, pelo menos até conhecer o Git bem o suficiente para que, quando uma delas falhar, o que acabará por acontecer, você reconheça o que deu errado e saiba o que fazer a respeito.)
A montante afeta
git status
Isso pode realmente ser o mais importante. Depois de definir um conjunto upstream, é
git status
possível relatar a diferença entre sua filial atual e a upstream, em termos de confirmações.Se, como é o caso normal, você estiver na ramificação
B
com o upstream definido como e executar , verá imediatamente se você possui confirmações que pode enviar por push e / ou confirmações nas quais pode mesclar ou refazer.origin/B
git status
Isso ocorre porque é
git status
executado:git rev-list --count @{u}..HEAD
: quantos commits você temB
que não estão ?origin/B
git rev-list --count HEAD..@{u}
: quantos commits você tem que não estão ?origin/B
B
Definir um upstream fornece todas essas coisas.
Como
master
já tem um conjunto upstream?Quando você clona pela primeira vez de algum controle remoto, usando:
ou similar, o último passo que o Git executa é, essencialmente
git checkout master
,. Isso verifica sua filial localmaster
- apenas você não tem uma filial localmaster
.Por outro lado, você não tem um ramo de rastreamento remoto chamado
origin/master
, porque você só clonado lo.Git adivinha que você deve ter querido dizer: "Faça-me um novo local,
master
que aponta para o mesmo cometer tão remota-trackingorigin/master
, e, enquanto você está nisso, definir o montante paramaster
aorigin/master
."Isso acontece para todos os ramos
git checkout
que você ainda não possui. O Git cria o ramo e faz com que ele "rastreie" (tenha como montante) o ramo de rastreamento remoto correspondente.Mas isso não funciona para novas ramificações, ou seja, ramificações sem ramificação de rastreamento remoto ainda .
Se você criar uma nova ramificação:
ainda não existe
origin/solaris
. Seu localsolaris
não pode rastrear ramificações de rastreamento remotoorigin/solaris
porque elas não existem.Quando você pressiona o novo ramo pela primeira vez:
que cria
solaris
naorigin
, e, portanto, também criaorigin/solaris
em seu próprio repositório Git. Mas é tarde demais: você já tem um localsolaris
que não possui upstream . 3O Git não deveria apenas definir isso agora como o upstream automaticamente?
Provavelmente. Consulte "Implementado mal" e a nota de rodapé 1. É difícil mudar agora : existem milhões de scripts 4 que usam o Git e alguns podem depender do seu comportamento atual. Alterar o comportamento requer uma nova versão principal, o nag-ware para forçar você a definir algum campo de configuração e assim por diante. Em suma, o Git é vítima de seu próprio sucesso: quaisquer erros que ele possua, atualmente, só podem ser corrigidos se a mudança for na maior parte invisível, claramente muito melhor, ou realizada lentamente ao longo do tempo.
O fato é que não acontece hoje, a menos que você use
--set-upstream
ou-u
durante ogit push
. É isso que a mensagem está dizendo.Você não precisa fazer assim. Bem, como observamos acima, você não precisa fazer nada, mas digamos que você queira um upstream. Você já criou ramo
solaris
deorigin
, através de um impulso mais cedo, e como seusgit branch
shows de saída, você já temorigin/solaris
em seu repositório local.Você simplesmente não o define como o upstream para
solaris
.Para configurá-lo agora, e não durante o primeiro push, use
git branch --set-upstream-to
. O--set-upstream-to
subcomando pega o nome de qualquer ramificação existente, comoorigin/solaris
, e define a ramificação atual upstream para essa outra ramificação.É isso, é tudo o que faz, mas tem todas as implicações mencionadas acima. Isso significa que você pode simplesmente executar
git fetch
, olhar ao redor, executargit merge
ougit rebase
conforme apropriado, fazer novos commits e executargit push
, sem muita confusão.1 Para ser justo, não estava claro na época que a implementação inicial era propensa a erros. Isso ficou claro quando todos os novos usuários cometiam os mesmos erros todas as vezes. Agora é "menos pobre", o que não quer dizer "ótimo".
2 "Never" é um pouco forte, mas acho que os novatos do Git entendem muito melhor as coisas quando separo as etapas, especialmente quando posso mostrar o que
git fetch
realmente fez e elas podem ver o quegit merge
ou o quegit rebase
fará a seguir.3 Se você executar o seu primeiro
git push
como -git push -u origin solaris
ou seja, se você adicionar o-u
sinalizador - o Git definiráorigin/solaris
como o upstream da sua ramificação atual se (e somente se) o envio for bem-sucedido. Então você deve fornecer-u
no primeiro impulso. Na verdade, você pode fornecê-lo em qualquer push posterior, e ele definirá ou alterará o upstream nesse ponto. Mas acho quegit branch --set-upstream-to
é mais fácil, se você esqueceu.4 Medido pelo método Austin Powers / Dr Evil de simplesmente dizer "um MILLLL-YUN", de qualquer maneira.
fonte
--set-upstream /dev/null
? Por que o fardo é empurrado para o caso comum? Realmente não entendo algumas dessas decisões de engenharia e usabilidade.git push -u
, mas realmente parece quegit push -u
deve ser o padrão, ou pelo menos o padrão se não houver a montante ainda , e deve haver umgit push --no-set-upstream
quando não há atualmente um montante e que deseja manter dessa maneira (por qualquer motivo incompreensível :-)).git config --add push.default current
, o git push criará automaticamente a ramificação no repositório remoto, se necessário.A diferença entre
git push origin <branch>
e
git push --set-upstream origin <branch>
é que ambos enviam muito bem ao repositório remoto, mas é quando você puxa que percebe a diferença.
Se você faz:
git push origin <branch>
ao puxar, você deve fazer:
git pull origin <branch>
Mas se você faz:
git push --set-upstream origin <branch>
então, ao puxar, você só precisa fazer:
git pull
Portanto, adicionar no
--set-upstream
permite não precisar especificar qual ramificação você deseja extrair a cada vez que fazgit pull
.fonte
Um comando basicamente completo é como
git push <remote> <local_ref>:<remote_ref>
. Se você executar apenasgit push
, o git não sabe exatamente o que fazer, a menos que você tenha feito alguma configuração que ajude o git a tomar uma decisão. Em um repositório git, podemos configurar vários controles remotos. Também podemos enviar uma referência local para qualquer referência remota. O comando completo é a maneira mais direta de fazer um push. Se você quiser digitar menos palavras, terá que configurar primeiro, como --set-upstream.fonte