Diferencia entre git checkout --track origin / branch y git checkout -b branch origin / branch

209

¿Alguien sabe la diferencia entre estos dos comandos para cambiar y rastrear una rama remota?

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

Creo que ambos realizan un seguimiento de la rama remota para poder enviar mis cambios a la rama en origen, ¿verdad?

¿Hay alguna diferencia práctica?

¡Gracias!

yorch
fuente

Respuestas:

282

Los dos comandos tienen el mismo efecto ( gracias a la respuesta de Robert Siemer por señalarlo ).

La diferencia práctica viene cuando se usa una sucursal local con un nombre diferente :

  • git checkout -b mybranch origin/abranchcreará mybranchy rastrearáorigin/abranch
  • git checkout --track origin/abranchsolo creará ' abranch', no una rama con un nombre diferente.

(Es decir, como se ha comentado por Sebastián Graf , si la rama local hizo no existe.
Si lo hiciera, sería necesario git checkout -B abranch origin/abranch)


Nota: con Git 2.23 (Q3 2019), eso usaría el nuevo comandogit switch :

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

Si la rama existe en múltiples controles remotos y uno de ellos es nombrado por la checkout.defaultRemotevariable de configuración, usaremos ese para propósitos de desambiguación, incluso si <branch>no es único en todos los controles remotos.
Póngalo en, por ejemplo, checkout.defaultRemote=originpara retirar siempre ramas remotas desde allí si <branch>es ambiguo pero existe en el control remoto 'origen'.

Aquí, " -ces lo nuevo -b".


Primero, algunos antecedentes: el seguimiento significa que una sucursal local tiene su conjunto ascendente en una sucursal remota:

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

git checkout -b branch origin/branch será:

  • crear / restablecer branchal punto al que hace referencia origin/branch.
  • cree la rama branch(con git branch) y rastree la rama de seguimiento remoto origin/branch.

Cuando una rama local se ubicó en una rama a distancia de seguimiento, Git establece la rama (específicamente el branch.<name>.remotey branch.<name>.mergeentradas de configuración) para que git pullse apropiadamente combinar de la rama a distancia de seguimiento.
Este comportamiento puede modificarse mediante el branch.autosetupmergeindicador de configuración global . Esa configuración se puede anular mediante el uso de la --tracky --no-trackopciones, y cambió más tarde usando git branch --set-upstream-to.


Y git checkout --track origin/branchhará lo mismo 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

También establecería el flujo ascendente para ' branch'.

(Nota: git1.8.0 dejará de funcionar git branch --set-upstreamy lo reemplazará con git branch -u|--set-upstream-to: vea el anuncio de git1.8.0-rc1 )


Tener una sucursal aguas arriba registrada para una sucursal local:

  • dile a git muestre la relación entre las dos ramas en git statusygit branch -v .
  • dirige git pull sin argumentos para extraer del flujo ascendente cuando se extrae la nueva rama .

Consulte " ¿Cómo hacer que una rama git existente rastree una rama remota? " Para obtener más información.

VonC
fuente
1
@VonC He estado buscando ese pequeño detalle que mencionaste como información adicional. En mi caso, tenía curiosidad de por qué algunas de mis ramas me lo permitían git pull, mientras que algunas ramas me pedían una rama remota de la que sacar. Resulta que si usted, por primera vez, está revisando una rama remota que creó su par, git continúa y se agrega branch.<BNAME>.remote=original gitconfig local. Lo que luego te permite emitir git pull. Sin embargo, si usted es el que crea la rama git checkout -b BNAME, entonces git -por supuesto- no lo sabe. Por lo tanto, debe especificar su control remoto.
batilc
@batilc "Resulta que si usted, por primera vez, está revisando una rama remota que creó su compañero"; sí, al leer git-scm.com/docs/git-checkout , veo: " If <branch>no se encuentra pero existe una rama de seguimiento en exactamente un control remoto (llámalo <remote>) con un nombre coincidente, trata como equivalente a $ git checkout -b <branch> --track <remote>/<branch>"
VonC
@VonC Encontré una mejor configuración para esto. configurarbranch.autoSetupMerge para alwayssimplemente realizar lo que estamos hablando. Este valor predeterminado es true, lo que significa que el seguimiento se realizará solo al retirar una rama remota. trueno configura el seguimiento para sucursales creadas localmente.
batilc
@batilc Estoy de acuerdo. Tiendo a no usar siempre, ya que prefiero establecer explícitamente el seguimiento, pero en su caso, esa debería ser la configuración correcta.
VonC
1
"git branch --set-upstream-to branch upstream / branch" no es la sintaxis correcta. debería ser: "git branch --set-upstream-to upstream / branch branch"
maharvey67
33

¡No hay diferencia en absoluto!

1) git checkout -b branch origin/branch

Si no hay --tracky no --no-track, --trackse supone como predeterminado. El valor predeterminado se puede cambiar con la configuración branch.autosetupmerge.

En efecto, 1) se comporta como git checkout -b branch --track origin/branch.

2) git checkout --track origin/branch

"Como una conveniencia", --tracksin -bimplica -by el argumento de se -bsupone que es "rama". Las conjeturas son conducidas por la variable de configuración remote.origin.fetch.

En efecto, 2) se comporta como git checkout -b branch --track origin/branch.

Como puede ver: no hay diferencia.

Pero se pone aún mejor:

3) git checkout branch

también es equivalente a git checkout -b branch --track origin/branch si "rama" aún no existe pero "origen / rama" sí 1 .


Los tres comandos configuran el "flujo ascendente" de "rama" como "origen / rama" (o fallan).

Upstream se usa como punto de referencia sin argumentos git status , git push, git mergey por lo tantogit pull (si está configurado como que (que es el valor predeterminado o casi el valor predeterminado)).

P.ej git status le dice qué tan atrás o adelante se encuentra en sentido ascendente, si hay uno configurado.

git push está configurado para impulsar la rama actual hacia arriba de forma predeterminada 2 desde git 2.0.

1 ... y si "origen" es el único control remoto que tiene "rama"
2, el valor predeterminado (denominado "simple") también exige que ambos nombres de rama sean iguales

Robert Siemer
fuente
5

El libro parece indicar que esos comandos producen el mismo efecto:

El caso simple es el ejemplo que acaba de ver, ejecutando git checkout -b [branch] [remotename] / [branch]. Si tiene Git versión 1.6.2 o posterior, también puede usar la abreviatura --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 una sucursal local con un nombre diferente al de la sucursal remota, puede usar fácilmente la primera versión con un nombre de sucursal local diferente:

$ git checkout -b sf origin/serverfix

Eso es particularmente útil cuando las terminaciones de bash o oh-my-zsh git pueden obtener el origin/serverfixnombre por usted, solo agregue --track(o -t) y estará en camino.

Palmadita
fuente
-1

No puedes crear una nueva rama con este comando

git checkout --track origin/branch

si tiene cambios que no están organizados.

Aquí hay un ejemplo:

$ 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

Sin embargo, puede crear fácilmente una nueva rama con cambios sin etapas con el git checkout -bcomando:

$ git checkout -b new-branch
Switched to a new branch 'new-branch'
M       src/App.js
Verde
fuente
tenga en cuenta que ambos comandos en las preguntas son para rastrear una rama remota existente ( origin/branch)
yorch
@ Green La prueba que haces es con en origin/new-branchlugar de origin/branch. ¿Estas consciente de ello?
Robert Siemer el