Recuperar confirmación específica de un repositorio Git remoto


¿Hay alguna forma de recuperar solo un commit específico de un repositorio Git remoto sin clonarlo en mi PC? La estructura del repositorio remoto es absolutamente la misma que la mía y, por lo tanto, no habrá ningún conflicto, pero no tengo idea de cómo hacer esto y no quiero clonar ese enorme repositorio.

Soy nuevo en git, ¿hay alguna manera?

 166
Author: Daniel, 2013-02-14

7 answers

A partir de la versión 2.5+ de Git (Q2 2015), obtener un solo commit (sin clonar el repositorio completo) es realmente posible.

Véase commit 68ee628por Fredrik Medley (moroten), 21 Mayo de 2015.
(Merged by Junio C Hamano -- gitster -- in commit a9d3493 , 01 Jun 2015)

Ahora tiene una nueva configuración (en el lado del servidor)

uploadpack.allowReachableSHA1InWant

Permitir upload-pack aceptar una solicitud de búsqueda que pide un objeto que es accesible desde cualquier punta de referencia. Sin embargo, tenga en cuenta que calcular la accesibilidad de los objetos es computacionalmente costoso.
El valor predeterminado es false.

Si combina esa configuración del lado del servidor con un clon superficial(git fetch --depth=1), puedes pedir un solo commit (ver t/t5516-fetch-push.sh:

git fetch --depth=1 ../testrepo/.git $SHA1

Puede usar el comando git cat-file para ver que la confirmación ha sido recuperada:

git cat-file commit $SHA1

"git upload-pack" que sirve "git fetch " puede ser dicho para servir confirmaciones que no están en la punta de cualquier ref, siempre y cuando sean accesible desde un ref, con uploadpack.allowReachableSHA1InWant variable de configuración.


La documentación completa es:

upload-pack: opcionalmente permitir la obtención de sha1 alcanzable

Con la opción de configuración uploadpack.allowReachableSHA1InWant establecida en el lado del servidor, "git fetch" puede hacer una solicitud con una línea "want" que nombra un objeto que no ha sido anunciado (probablemente obtenido fuera de banda o de un puntero de submódulo).
Solo objetos se procesará la unión de las sucursales anunciadas y las sucursales ocultas por transfer.hideRefs.
Tenga en cuenta que hay un costo asociado de tener que caminar hacia atrás el historial para comprobar la accesibilidad.

Esta característica se puede utilizar al obtener el contenido de un determinado commit, por lo que el sha1 es conocido, sin la necesidad de clonar el todo repositorio, especialmente si se usa una búsqueda superficial .

Los casos útiles son por ejemplo,

  • repositorios que contienen archivos grandes en el historial,
  • obteniendo solo los datos necesarios para una comprobación de submódulos,
  • al compartir un sha1 sin decir a qué rama exacta pertenece y en Gerrit, si piensas en términos de commits en lugar de cambiar números.
    (El caso Gerrit ya ha sido resuelto a través de allowTipSHA1InWant ya que cada cambio de Gerrit tiene una ref.)

Git 2.6 (T3 2015) mejorará eso modelo.
Véase commit 2bc31d1, commit cc118a6 (28 Jul 2015) por Jeff King (peff).
(Merged by Junio C Hamano -- gitster -- in commit 824a0be , 19 Aug 2015)

refs: soporte negativo transfer.hideRefs

Si oculta una jerarquía de referencias usando la configuración transfer.hideRefs, no hay forma de anular posteriormente esa configuración para "mostrarla".
Este parche implementa un hide "negativo" que hace que las coincidencias se marquen inmediatamente como no ocultas, incluso si otra coincidencia la ocultara.
Nos encargamos de aplicar las coincidencias en orden inverso a la forma en que nos las alimenta la maquinaria de configuración, ya que eso permite que nuestra habitual precedencia de configuración "last one wins" funcione (y las entradas en .git/config, por ejemplo, anularán /etc/gitconfig).

Así que ahora puedes hacer: {[56]]}

git config --system transfer.hideRefs refs/secret
git config transfer.hideRefs '!refs/secret/not-so-secret'

Para ocultar refs/secret en todos los repositorios, excepto en un bit público en un específico repo.


Git 2.7 (Nov/Dec 2015) mejorará de nuevo:

Ver a cometer 948bfa2, cometer 00b293e (05 de Noviembre de 2015), cometer 78a766a, cometer 92cab49, cometer 92cab49, cometer 92cab49 (03 de Noviembre de 2015), cometer 00b293e, cometer 00b293e (05 de Noviembre de 2015), y cometer 92cab49, cometer 92cab49, cometer 92cab49, cometer 92cab49 (03 Nov 2015) de Lukas Fleischer (lfos).
Ayuda-por: Eric Sunshine (sunshineco).
(Merged by Jeff King -- peff -- in commit dbba85e , 20 Nov 2015)

config.txt: documenta la semántica de hideRefs con espacios de nombres

En este momento, no hay una definición clara de cómo transfer.hideRefs debe comportarse cuando se establece un espacio de nombres.
Explique que hideRefs los prefijos coinciden con los nombres despojados en ese caso. Así es como hideRefs los patrones son actualmente manipulado en envase receptor.

HideRefs: agregar soporte para emparejar refs completos

Además de hacer coincidir refs despojados, ahora se puede agregar hideRefs patrones con los que se hace coincidir la ref completa (sin cortar).
Para distinguir entre coincidencias despojadas y completas, esos nuevos patrones deben ir precedidos por un circunflejo (^).

De ahí la nueva documentación :

transfer.hideRefs:

Si un espacio de nombres está en uso, el prefijo del espacio de nombres se elimina de cada referencia antes de que coincida con los patrones transfer.hiderefs.
Por ejemplo, si refs/heads/master se especifica en transfer.hideRefs y el espacio de nombres actual es foo, luego refs/namespaces/foo/refs/heads/master se omite de los anuncios, pero refs/heads/master y refs/namespaces/bar/refs/heads/master todavía se anuncian como los llamados "tener" líneas.
Con el fin de que coincida con refs antes de pelar, añadir un ^ delante de el nombre del árbitro. Si combina ! y ^, ! debe especificarse primero.


R.. menciona en los comentarios la configuración uploadpack.allowAnySHA1InWant, que permite a upload-pack aceptar una solicitud fetch que pide cualquier objeto. (Por defecto es false).

See commit f8edeaa (Nov. 2016, Git v2. 11. 1) por David "novalis" Turner (novalis):

upload-pack: opcionalmente permite obtener cualquier sha1

Parece un poco tonto hacer un control de accesibilidad en el caso en que confíe en el usuario para acceder a absolutamente todo en el repositorio.

Además, es picante en un sistema distribuido perhaps tal vez un servidor anuncia un árbitro, pero otro ha tenido un empujón a ese árbitro, y tal vez las dos solicitudes HTTP terminan dirigidas a estos diferentes servidor.

 87
Author: VonC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-07-25 10:50:15

Solo clonas una vez, por lo que si ya tienes un clon del repositorio remoto, tirar de él no descargará todo de nuevo. Simplemente indique qué rama desea extraer, o obtenga los cambios y obtenga la confirmación que desea.

Buscar desde un nuevo repositorio es muy barato en ancho de banda, ya que solo descargará los cambios que no tenga. Piensa en términos de Git haciendo lo correcto, con una carga mínima.

Git almacena todo en la carpeta .git. Un commit no puede ser recogido y almacenado en aislamiento, necesita a todos sus antepasados. Están interrelacionados .


Para reducir el tamaño de la descarga, sin embargo, puede pedirle a git que obtenga solo objetos relacionados con una rama específica o commit:

git fetch origin refs/heads/branch:refs/remotes/origin/branch

Esto descargará solo las confirmaciones contenidas en la rama remota branch (y solo los que echas de menos), y guardarlo en origin/branch. A continuación, puede fusionar o checkout.

También puede especificar solo una confirmación SHA1:

git fetch origin 96de5297df870:refs/remotes/origin/foo-commit

Esta voluntad descargue solo el commit del SHA-1 96de5297df870 especificado (y sus ancestros que se pierda), y guárdelo como rama remota (inexistente) origin/foo-commit.

 92
Author: CharlesB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-06 14:46:37

Hice un pull en mi repositorio git:

git pull --rebase <repo> <branch>

Permitiendo a git extraer todo el código de la rama y luego fui a hacer un reset sobre el commit que me interesaba.

git reset --hard <commit-hash>

Espero que esto ayude.

 58
Author: Piu Sharma,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-12-03 12:43:17

Simplemente puede obtener un solo commit de un repositorio remoto con

git fetch <repo> <commit>

Donde

  • <repo> puede ser un nombre de repositorio remoto (por ejemplo, origin) o incluso una URL de repositorio remoto (por ejemplo, https://git.foo.com/myrepo.git)
  • <commit> puede ser la confirmación SHA1

Por ejemplo

git fetch https://git.foo.com/myrepo.git 0a071603d87e0b89738599c160583a19a6d95545

Después de obtener el commit (y los ancestros que faltan), simplemente puede comprobarlo con

git checkout FETCH_HEAD

Tenga en cuenta que esto lo llevará al estado de "cabeza desapegada".

 42
Author: Flow,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-06-06 14:50:35

Simplemente puede obtener el repositorio remoto con:

git fetch <repo>

Donde

  • <repo> puede ser un nombre de repositorio remoto (por ejemplo, origin) o incluso una URL de repositorio remoto (por ejemplo, https://git.foo.com/myrepo.git)

Por ejemplo:

git fetch https://git.foo.com/myrepo.git 

Después de obtener los repositorios, puede combinar las confirmaciones que desee (ya que la pregunta es sobre recuperar una confirmación, en su lugar puede usar cherry-pick para seleccionar solo una confirmación):

git merge <commit>
  • <commit> puede ser la confirmación SHA1

Para ejemplo:

git cherry-pick 0a071603d87e0b89738599c160583a19a6d95545

O

git merge 0a071603d87e0b89738599c160583a19a6d95545

Si es la última confirmación que desea combinar, también puede usar la variable FETCH_HEAD:

git cherry-pick (or merge) FETCH_HEAD
 13
Author: Sérgio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-02 10:43:07

Creo que 'git ls-remote' ( http://git-scm.com/docs/git-ls-remote ) debe hacer lo que quieras. Sin fuerza para buscar o tirar.

 1
Author: Hubbitus,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-28 15:42:04

Finalmente encontré una manera de clonar commit específico usando git cherry-pick. Suponiendo que no tiene ningún repositorio en local y está extrayendo una confirmación específica del remoto,

1) crear un repositorio vacío en local y git init

2) git remote añadir origen "url-of-repository "

3) git fetch origin [esto no moverá sus archivos a su espacio de trabajo local a menos que se fusionen]

4) git cherry-pick "Enter-long-commit-hash-that-you-need "

Hecho.De esta manera, solo tendrá los archivos de esa confirmación específica en su local.

Enter-long-commit-hash:

Puedes obtener esto usando - > git log pretty pretty = oneline

 1
Author: surya deepak,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-03 04:19:49