Qual é a diferença entre git push.default = current e push.default = upstream?

89

A página do manual para git-config lista essas opções para push.default:

nothing - do not push anything.
matching - push all matching branches. All branches having the same name in both ends are considered to be matching. This is the default.
upstream - push the current branch to its upstream branch.
tracking - deprecated synonym for upstream.
current - push the current branch to a branch of the same name.

Na maioria dos casos, eu assumiria que enviar para um branch upstream de um branch seria o mesmo que enviar para um branch com o mesmo nome, já que o branch upstream normalmente teria o mesmo nome, e já que o branch com o mesmo nome ("atual" ) normalmente (ou sempre, por definição?) estaria a montante. Qual é a diferença?

ATUALIZAÇÃO : a página de manual para git-config foi atualizada (como seria de se esperar), então as distinções feitas aqui podem ser muito mais claras agora.

iconoclasta
fonte
2
para os desenvolvedores, é realmente irritante diferenciá-los, então 'simples' é introduzido e será o comportamento padrão para git-push. na verdade, ele apareceu no git 1.7.11
xhlwill
14
Para mais informações sobre o aviso git recente push.default is unset; its implicit value is changing in Git 2.0e sobre matchingvs, simpleconsulte stackoverflow.com/questions/13148066/…
Nate
iconoclaust: Não acho que minha edição mudou a integridade da pergunta, e as informações desatualizadas só precisam ser corrigidas. Por que fazer o usuário fazer o trabalho extra de clicar no link?
Flimm de

Respostas:

72

Você resumiu a diferença em sua pergunta. upstreamempurra para o branch upstream configurado , enquanto currentassume que o branch upstream tem o mesmo nome do branch local atual e empurra para aquele nome específico. Na realidade, não há razão para presumir que o branch de rastreamento upstream de uma filial local tenha o mesmo nome da própria filial local.

Por exemplo, se você trabalha em vários repositórios ou em muitos controles remotos de desenvolvedor compartilhados, geralmente acaba rastreando diferentes garfos do mesmo ramo, como allen-masterou susan-master, ambos rastreando o ramo nos repositórios de masterAllen e Susan, respectivamente. Nesse caso, currentseria a configuração incorreta, porque esses nomes de ramificação não existem em seus remotos. upstream, no entanto, funcionaria muito bem.

Um exemplo mais prático pode ser o rastreamento de um repositório developmente production. Seu fluxo de trabalho pode usar uma ramificação da linha principal diferente para cada um, mas isso pode ficar confuso. Suponha que você seja um integrador de código e queira rastrear os masterramos de ambos os repositórios separadamente.

git checkout -b production --track production/master
git checkout -b development --track development/master

Agora você tem dois branches que controlam seus respectivos repositórios, nenhum dos quais usa a masterconvenção de nomenclatura. Há pouca confusão sobre os nomes dos ramos: eles descrevem explicitamente o que rastreiam. No entanto, push.default = currentnão faria sentido, já que nenhum controle remoto contém um branch developmentou production.

Christopher
fonte
6
Você está dando dois exemplos de quando upstreamé preferível current. Eu acho que é bastante óbvio, então você deveria dar um exemplo para o caso oposto.
AndreKR
1
@AndreKR AFAIK currenté melhor no caso de você ser um desenvolvedor novo, porque você não precisa de git configmuito, especialmente se você clonou de algum lugar. currentempurra para ou cria-então-empurra para branches homônimos no repositório remoto para você se eles ainda não existirem, enquanto simplese recusará a fazer isso imediatamente quando um branch com o mesmo nome ainda não existir. upstreamtem o mesmo comportamento neste caso, a menos que um branch upstream tenha sido definido explicitamente ou de outra forma definido como mencionado na resposta de Yawar .
SeldomNeedy
6

current irá enviar o branch atual para um branch com o mesmo nome no repositório remoto.

upstream irá enviar o branch atual para o branch upstream.

O branch upstream é um branch que foi explicitamente ou implicitamente definido como sendo o upstream de seu branch atual. Isso significa que push e pull por padrão serão sincronizados com este branch. O branch upstream pode estar no mesmo repositório do branch atual. Você pode fazer coisas interessantes como configurar seu branch master local como upstream de seu branch de recurso local (tópico) e enviar e receber entre eles.

A configuração upstream implícita é feita por meio do branch.autosetupmergevalor de configuração. Você pode encontrar a documentação na git configpágina de ajuda. A configuração explícita do upstream é feita com a -uopção do git branchcomando. Veja a página de ajuda para detalhes.

Yawar
fonte
Acho que não pensa branch.autoSetupMergeo mesmo que -u/ --set-upstream. Pelo menos, não vejo nada na documentação que implique que ele faça o git push se comportar como se fosse chamado -upor padrão, o que é o que me parece que você está dizendo. Você pode esclarecer o que você quis dizer?
waldyrious de
@waldyrious sure; quando você está fazendo check-out de um branch de rastreamento remoto, a branch.autoSetupMergeconfiguração por padrão cria um novo branch local e define seu upstream como o branch de rastreamento remoto. Essa ação implícita pode ser feita explicitamente usando os sinalizadores -t( --track) ou -u ...( --set-upstream-to=...), que fazem a mesma coisa com sintaxes ligeiramente diferentes.
Yawar
1
Eu vejo o que aconteceu aqui - já que esta questão é sobre git push, eu (erroneamente) assumi que você estava falando sobre a -uopção de git push, em vez da -uopção de git branch. Desculpem a confusão :)
waldyrious