Diferença entre git checkout --track origin / branch e git checkout -b branch origin / branch

209

Alguém sabe a diferença entre esses dois comandos para alternar e rastrear uma ramificação remota?

git checkout -b branch origin/branch
git checkout --track origin/branch

Eu acho que os dois acompanham o ramo remoto para poder enviar minhas alterações ao ramo na origem, certo?

Existe alguma diferença prática ??

Obrigado!

yorch
fonte

Respostas:

282

Os dois comandos têm o mesmo efeito ( graças à resposta de Robert Siemer por apontá-lo ).

A diferença prática ocorre ao usar um ramo local chamado de forma diferente :

  • git checkout -b mybranch origin/abranchcriará mybranche acompanharáorigin/abranch
  • git checkout --track origin/abranchcriará apenas ' abranch', não um ramo com um nome diferente.

(Ou seja, como comentado por Sebastian Graf , se a filial local já não existisse.
Se existisse , você precisaria git checkout -B abranch origin/abranch)


Nota: com o Git 2.23 (terceiro trimestre de 2019), isso usaria o novo comandogit switch :

git switch -c <branch> --track <remote>/<branch>

Se a ramificação existir em vários controles remotos e um deles for nomeado pela checkout.defaultRemotevariável de configuração, usaremos esse para fins de desambiguação, mesmo que <branch>não seja exclusivo em todos os controles remotos.
Configure-o como, por exemplo, checkout.defaultRemote=originpara sempre fazer check-out de filiais remotas a partir daí, se <branch>for ambíguo, mas existir no controle remoto 'origem'.

Aqui, ' -c' é o novo ' -b'.


Primeiro, alguns antecedentes: Rastrear significa que uma filial local tem seu upstream definido como uma filial remota:

# git config branch.<branch-name>.remote origin
# git config branch.<branch-name>.merge refs/heads/branch

git checkout -b branch origin/branch vai:

  • criar / redefinir branchpara o ponto referenciado por origin/branch.
  • crie a ramificação branch(com git branch) e acompanhe a ramificação de rastreamento remoto origin/branch.

Quando uma ramificação local é iniciada em uma ramificação de rastreamento remoto, o Git configura a ramificação (especificamente as entradas branch.<name>.remotee de branch.<name>.mergeconfiguração) para que git pullse fundam adequadamente a partir da ramificação de rastreamento remoto.
Esse comportamento pode ser alterado através do branch.autosetupmergesinalizador de configuração global . Essa configuração pode ser substituído usando o --tracke --no-trackopções, e mudou mais tarde usando git branch --set-upstream-to.


E git checkout --track origin/branchfará o mesmo que git branch --set-upstream-to):

 # or, since 1.7.0
 git branch --set-upstream upstream/branch branch
 # or, since 1.8.0 (October 2012)
 git branch --set-upstream-to upstream/branch branch
 # the short version remains the same:
 git branch -u upstream/branch branch

Também definiria o upstream para ' branch'.

(Nota: o git1.8.0 será descontinuado git branch --set-upstreame substituirá por git branch -u|--set-upstream-to: consulte anúncio do git1.8.0-rc1 )


Ter uma filial upstream registrada para uma filial local:

  • diga ao git para mostrar a relação entre os dois ramos em git statusegit branch -v .
  • direciona git pull sem argumentos para extrair do upstream quando o novo ramo é retirado .

Consulte " Como você faz com que uma ramificação git existente rastreie uma ramificação remota? " Para obter mais informações.

VonC
fonte
1
@VonC Eu estava procurando pelos pequenos detalhes que você mencionou como informações extras. No meu caso, fiquei curioso para saber por git pullque alguns galhos me permitiam , enquanto alguns pediam um galho remoto. Acontece que, se você, pela primeira vez, está verificando uma ramificação remota criada por seu colega, o git continua e adiciona branch.<BNAME>.remote=originao gitconfig local. O que lhe permite emitir git pull. No entanto, se você é o responsável pela criação da ramificação git checkout -b BNAME, o git, é claro, não sabe. Então você deve especificar seu controle remoto.
batilc
@batilc "Acontece que se você, pela primeira vez, estiver verificando uma ramificação remota criada por seus pares"; sim, lendo git-scm.com/docs/git-checkout , vejo: " If <branch>não foi encontrado, mas existe um ramo de rastreamento em exatamente um controle remoto (chame-o <remote>) com um nome correspondente, trate como equivalente a $ git checkout -b <branch> --track <remote>/<branch>"
VonC
@VonC Encontrei uma configuração melhor para isso. configurar branch.autoSetupMergepara alwayssimplesmente executar o que estamos falando. Essa configuração é padronizada como true, o que significa que o rastreamento será realizado apenas ao fazer check-out de uma filial remota. truenão configura o rastreamento para ramificações criadas localmente.
batilc
@batilc Eu concordo. Costumo não usar sempre, pois prefiro definir explicitamente o rastreamento, mas no seu caso, essa deve ser a configuração correta.
VonC
1
"git branch --set-upstream-to branch upstream / branch" não é a sintaxe correta. deveria ser: "git branch --set-upstream-to upstream / branch branch"
maharvey67 10/10
33

Não há nenhuma diferença!

1) git checkout -b branch origin/branch

Se não --tracke não --no-track, --tracké assumido como padrão. O padrão pode ser alterado com a configuração branch.autosetupmerge.

Com efeito, 1) se comporta como git checkout -b branch --track origin/branch.

2) git checkout --track origin/branch

"Como uma conveniência", --tracksem -bimplicar -be o argumento para -bé adivinhado como "ramo". A suposição é conduzida pela variável de configuração remote.origin.fetch.

Com efeito, 2) se comporta como git checkout -b branch --track origin/branch.

Como você pode ver: não há diferença.

Mas fica ainda melhor:

3) git checkout branch

também é equivalente a git checkout -b branch --track origin/branch se "ramificação" ainda não existir, mas "origem / ramificação" existir 1 .


Todos os três comandos definem o "upstream" de "branch" como "origin / branch" (ou eles falham).

Upstream é usado como ponto de referência de argumentos sem argumentos git status , git push, git mergee assim git pull(se configurado como que (que é o padrão ou quase o padrão)).

Por exemplo, git statusinforma a que distância você está atrás ou à frente do upstream, se um estiver configurado.

git push está configurado para enviar a filial atual a montante por padrão 2 desde o git 2.0.

1 ... e se "origin" for o único controle remoto com "branch"
2, o padrão (nomeado "simple") também impõe que ambos os nomes de branch sejam iguais

Robert Siemer
fonte
5

O livro parece indicar que esses comandos produzem o mesmo efeito:

O caso simples é o exemplo que você acabou de ver, executando o git checkout -b [branch] [remotename] / [branch]. Se você possui o Git versão 1.6.2 ou posterior, também pode usar a abreviação --track:

$ git checkout --track origin/serverfix 
Branch serverfix set up to track remote branch serverfix from origin. 
Switched to a new branch 'serverfix' 

Para configurar uma filial local com um nome diferente da filial remota, você pode facilmente usar a primeira versão com um nome de filial local diferente:

$ git checkout -b sf origin/serverfix

Isso é particularmente útil quando as conclusões do bash ou oh-my-zsh git são capazes de definir o origin/serverfixnome para você - basta acrescentar --track(ou -t) e você está a caminho.

Pat
fonte
-1

Você não pode criar uma nova ramificação com este comando

git checkout --track origin/branch

se você tiver alterações que não são preparadas.

Aqui está um exemplo:

$ git status
On branch master
Your branch is up to date with 'origin/master'.

Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   src/App.js

no changes added to commit (use "git add" and/or "git commit -a")

// TRY TO CREATE:

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

No entanto, você pode criar facilmente uma nova ramificação com alterações não faseadas com o git checkout -bcomando:

$ git checkout -b new-branch
Switched to a new branch 'new-branch'
M       src/App.js
Verde
fonte
ter em mente que ambos os comandos nas perguntas são para rastrear uma filial remota existente ( origin/branch)
yorch
@ Green O teste que você faz é em origin/new-branchvez de origin/branch. Você está ciente disso?
Robert Siemer