Git: ¿Cómo actualizar / retirar un solo archivo del maestro de origen remoto?

363

El escenario:

  1. Realizo algunos cambios en un solo archivo localmente y ejecuto git add, git commitygit push
  2. El archivo se envía al repositorio maestro de origen remoto.
  3. Tengo otro repositorio local que se implementa a través de Capistrano con el método "remote_cache" desde ese repositorio remoto
  4. Ahora no quiero implementar toda la aplicación, sino solo actualizar / retirar ese único archivo.

¿Es esto de alguna manera posible con git? No pude encontrar nada que funcionara ni pude resolverlo. Con SVN acabo de hacerlo svn up filey listo.

foresth
fuente
19
Es posible que desee considerar cambiar la respuesta aceptada a la que realmente responde a su pregunta. ;)
pasos del
66
Después de más de 6 años, creo que podemos asumir con seguridad que esto no sucederá @steps ...
Félix Gagnon-Grenier
Con Git 2.23 (agosto de 2019), lo es git restore -s origin/master -- path/to/file. Vea mi respuesta a continuación .
VonC

Respuestas:

916

Es posible hacerlo (en el repositorio desplegado)

git fetch
git checkout origin/master -- path/to/file

La búsqueda descargará todos los cambios recientes, pero no la incluirá en su código actual (área de trabajo).

La comprobación actualizará el árbol de trabajo con el archivo particular de los cambios descargados ( origin/master).

Al menos esto funciona para mí para esas pequeñas correcciones de errores tipográficos, donde se siente raro crear una rama, etc., solo para cambiar una palabra en un archivo.

qzio
fuente
1
Súper práctico, esto funcionó muy bien. Necesitaba obtener un archivo composer.json y ejecutar una actualización antes de actualizar el resto del sitio en producción. Si hubiera colocado manualmente los archivos composer.json / lock en su lugar, cuando hice una extracción, entraría en conflicto al decir que los archivos ya existían. Al hacerlo de esta manera, git reconoció los archivos sin una queja.
David
66
Esta es la respuesta que estaba buscando.
javadba
20
@ Mymozaaa El guión doble indica que lo que sigue es un nombre de archivo. Es para evitar que git interprete su nombre de archivo como una rama en el desafortunado caso de que tenga dos con el mismo nombre.
Joel Mellon
El problema es que todavía estás buscando, y si es un gran repositorio, esa será la operación costosa. Me temo que la única alternativa sería instalar gitweb en el control remoto y luego acceder a él para recuperar el archivo o tal.
Christian Goetze
pequeña pregunta, después de hacer eso, voy a una máquina diferente, luego hago sus acciones enumeradas anteriormente, pero luego las git statusveo como Changes to be committed:, lo que significa que tengo que comprometerlas nuevamente. (solo señalando que quería actualizar un solo archivo intacto pero el repositorio en sí se toca en una máquina diferente)
Ricky Levi
42

El siguiente código funcionó para mí:

     git fetch
     git checkout <branch from which file needs to be fetched> <filepath> 
Shagun Pruthi
fuente
19
git archive --format=zip --remote=ssh://<user>@<host>/repos/<repo name> <tag or HEAD> <filename> > <output file name>.zip
Dmitry R
fuente
1
Esta es una buena solución para repositorios clonados sobre ssh, pero parece que esto no es compatible con https: git archive --remote=https://github.com/git/git.git master:git/contrib/completion git-completion.bash | tar -x me da un mensaje de error:fatal: Operation not supported by protocol.
Alderath
1
fue agradable combinado con tar: s --to-stdout,git archive --remote="gitolite3@<host>:<repo>" <tag> <file> | tar xf - --to-stdout
Puggan Se
19

Con Git 2.23 (agosto de 2019) y el nuevo comando (aún experimental) git restore, visto en " ¿Cómo restablecer todos los archivos desde el directorio de trabajo pero no desde el área de preparación? ", Eso sería:

git fetch
git restore -s origin/master -- path/to/file

La idea es: git restoresolo trata con archivos, no con archivos y ramas como lo git checkouthace.
Ver " Confundido porgit checkout ": ahí es donde git switchentra)


codersam agrega en los comentarios :

en mi caso, quería obtener los datos de mi flujo ascendente (desde el que bifurqué).
Así que solo cambié a:

git restore -s upstream/master -- path/to/file
VonC
fuente
2
Qué alivio que este comando finalmente exista ... ¿Qué hacían las personas git-cluefull antes? Estaba restaurando todo y copiando los archivos individuales que necesitaba, pero fue doloroso.
Mike Wise el
Esto funcionó para mí, pero en mi caso quería obtener los datos de mi flujo ascendente (desde el que bifurqué). Así que solo cambié agit restore -s upstream/master -- path/to/file
coderSam
@coderSam Gracias por este comentario. He incluido tu comentario en la respuesta para mayor visibilidad.
VonC
8

Lo que puedes hacer es:

  1. Actualice su repositorio local de git:

    git fetch

  2. Construya una sucursal local y realice el pago:

    git branch pouet && git checkout pouet

  3. Aplique la confirmación que desee en esta rama:

    git cherry-pick abcdefabcdef

    (abcdefabcdef es el sha1 de la confirmación que desea aplicar)

punta
fuente
44
Como un aparte, su segundo paso también se puede hacer en un comando como git checkout -b pouet.
Greg Hewgill
44
'pouet' es el mejor nombre de sucursal para este ejemplo.
Hussard
2

O git stash (si tiene cambios) en la rama en la que se encuentra, haga clic en el maestro de extracción, obtenga los últimos cambios, tome ese archivo en su escritorio (o la aplicación completa). Mira la sucursal en la que estabas. Git stash se aplica nuevamente al estado en el que estaba, luego corrija los cambios manualmente o arrástrelo para reemplazar el archivo.

De esta manera no es tan genial, pero definitivamente funciona si ustedes no pueden resolver nada más.

jahrichie
fuente
-10

Creo que he encontrado un truco fácil.

Elimine el archivo que tiene en el repositorio local (el archivo que desea actualizar desde la última confirmación en el servidor remoto)

Y luego hacer un git pull

Debido a que el archivo se elimina, no habrá conflicto

Viswadeep Sarangi
fuente
Eso elimina todos los cambios eventuales realizados en ese archivo localmente, y también extrae todos los demás archivos, que es específicamente lo que el OP no quiere hacer.
legrojan
En lugar de actualizar la rama remota, eliminar local es una muy mala idea.
c0der512