¿Cuál es la diferencia entre estas syntax `git fetch`?

He clonado desnudo un repository ( git clone --bare ) y aparentemente git fetch no lo actualiza, pero git fetch origin master:master does. No entiendo todos los matices entre estas syntax:

  • git fetch
  • git fetch origin
  • git fetch origin master
  • git fetch origin master:master

origin es mi único control remoto y el master es mi única twig, y ​​la ayuda dice:

Cuando no se especifica ningún control remoto, de manera pnetworkingeterminada se usará el control remoto de origen.

Entonces, ¿por qué estas cuatro líneas no son lo mismo?

Editar: los tres primeros commands parecen captar en una twig temporal llamada FEATCH_HEAD . Pero dado que estoy usando un clon desnudo, no puedo usar git merge para get los resultados obtenidos.

Edit2: A partir de la respuesta de @ torek, realicé una pequeña testing y diferencié los directorys de clones –bare y a – mirror. Aquí está el resultado:

 diff -ru table.bare.git/config table.mirror.git/config --- table.bare.git/config 2014-10-14 20:01:42.812226509 -0400 +++ table.mirror.git/config 2014-10-14 20:00:53.994985222 -0400 @@ -4,3 +4,5 @@ bare = true [remote "origin"] url = git://anongit.freedesktop.org/table/table + fetch = +refs/*:refs/* + mirror = true Only in table.bare.git/objects/pack: pack-17005b7e1020d291eb86d778a174ecf0d60d92a9.idx Only in table.bare.git/objects/pack: pack-17005b7e1020d291eb86d778a174ecf0d60d92a9.pack Only in table.mirror.git/objects/pack: pack-c08b44b7f290ef0bc9abe3a0b974695c85a69342.idx Only in table.mirror.git/objects/pack: pack-c08b44b7f290ef0bc9abe3a0b974695c85a69342.pack 

¡Gracias!

El comentario de Andrew C contiene la key aquí, pero voy a exponer un poco:

  • git fetch , sin arguments adicionales, elige un nombre remoto mirando la twig actual, o usa el origin (ver la documentation para más detalles). Después de haber elegido un control remoto, continúa con el siguiente formulario.

  • git fetch remote , nuevamente sin arguments adicionales, usa el control remoto dado, y extrae las líneas fetch = para ese control remoto para get un set de "refspecs". Luego procede de manera similar al último caso.

  • git fetch remote refspec usa el control remoto dado y el refspec dado (puedes dar múltiples references aquí) para elegir las references a actualizar.

Una vez que git fetch tiene un control remoto o URL dado el nombre de un control remoto, extrae la url = línea para get la URL, contacta a los otros commands git en el server remoto y les pide una list de todas las references del repository remoto (twigs, tags y otras references, todas en los espacios de nombres refs/* , con una adición especial para HEAD que también se puede get pero no se usa generalmente aquí; está ahí para el paso de clonación inicial).

Para cada reference así obtenida, git fetch ve si le ha pedido que traiga esa reference, y de ser así, qué nombre le pidió a git usar en su repository.

Una vez más, los nombres disponibles se obtienen del control remoto. Los nombres buscados se obtienen de sus refspecs, y los nombres que se les dará en su repository también se obtienen de sus refspecs.

Un refspec de la forma a:b significa "tomar reference a , pero llamarlo b localmente".

Un refspec que falta la parte b significa "tomar reference a , pero ponerlo en el file especial FETCH_HEAD ". ( FETCH_HEAD luego se convierte en una reference normal, como MERGE_HEAD y ORIG_HEAD y así sucesivamente, excepto que tiene text adicional escrito para el script de pull , por lo que a veces solo funciona de la manera que cabría esperar).

Un refspec puede contener un carácter comodín: refs/heads/* significa "tomar todas las twigs" (las twigs son, por definición, references que comienzan con refs/heads/ ). Normalmente, la línea fetch = en su configuration de git dice refs/heads/*:refs/remotes/origin/* . 1 Como antes, esto significa cambiar el nombre de la twig coincidente, con el * a la derecha expandiéndose a lo que el * a la izquierda del colon coincida. Así que esto trae todas las twigs, pero los renombra como origin/master y similares. Normalmente, eso es lo que quiere para un repository no – --bare .

A veces eso también es lo que quieres para un repository --bare , y a veces no lo es. En particular, a veces quieres un repository "espejo", que es un clon desnudo que simplemente copy de forma esclava otro repository. Para cambiar un repository común ordinario en un espejo, simplemente necesita modificar el fetch = line: en lugar de refs/heads/*:refs/remotes/origin/* la línea debería leer fetch = refs/heads/*:refs/heads/* . De hecho, es posible que desee traer todo (tags e incluso notas) con fetch = refs/*:refs/* . Si realmente quiere esto, es algo que usted puede decidir, por supuesto.

Tenga en count que esto es lo suficientemente común como para que git clone tenga una bandera para configurarlo automáticamente: clone con --mirror y obtendrá un clon desnudo con la fetch = línea modificada.


1 En realidad, la línea lee +refs/heads/*:refs/remotes/origin/* , es decir, también hay un carácter principal + . Este signo más establece la "bandera de fuerza", como si hubiera usado git fetch --force , para esa actualización de reference en particular. Esto no es particularmente relevante para los problemas de ortografía aquí, pero señalaré que generalmente desea una actualización forzada para sucursales remotas como la que se muestra aquí, y también para repositorys de réplica puros.

Si está duplicando tags, probablemente quiera hacer una actualización forzada. Idealmente, por supuesto, las tags nunca cambian (ni se eliminan), por lo que en un mundo ideal esto no importaría, pero en el mundo real a veces cambian o se eliminan.

Para manejar la eliminación de reference, debe indicarle a git fetch que --prune a --prune (o, de manera similar, a la fuente --prune a git remote update ). No hay syntax en refspecs para la poda automática (aunque sería razonable, no he visto ninguna propuesta para ello).