Tengo dos repositorios. En uno, hago cambios en el archivo ./hello.test
. Confirmo los cambios y creo un parche a partir de ese compromiso con git format-patch -1 HEAD
. Ahora, tengo un segundo depósito que contiene un archivo que tiene el mismo contenido que hello.test pero se coloca en un directorio diferente con un nombre diferente: ./blue/red/hi.test
. ¿Cómo hago para aplicar el parche mencionado anteriormente al hi.test
archivo? Lo intenté, git am --directory='blue/red' < patch_file
pero eso, por supuesto, se queja de que los archivos no tienen el mismo nombre (¿y pensé que a Git no le importaba?). Sé que probablemente podría editar el diff para aplicarlo a ese archivo específico, pero estoy buscando una solución de comando.
100
Respuestas:
Puede crear el parche usando
git diff
y luego aplicarlo usando lapatch
utilidad, que le permite especificar el archivo al que desea aplicar la diferencia.Por ejemplo:
fuente
am
oapply
, pero no puedo encontrarlo. Si se encuentra duplicando muchos cambios, podría haber una solución mejor usando submódulos, o lo que sea que su idioma de elección proporcione para compartir código (por ejemplo, en Ruby podría extraer el código duplicado como una gema).Existe una solución simple que no implica la edición manual de parches ni un script externo.
En el primer repositorio (esto también puede exportar un rango de confirmación, utilícelo
-1
si desea seleccionar solo una confirmación):En el segundo repositorio:
En lugar de usar
--relative
ingit format-patch
, otra solución es usar la-p<n>
opción ingit am
para eliminarn
directorios de la ruta de los parches, como se menciona en una respuesta a una pregunta similar .También es posible ejecutar
git format-patch --relative <committish>
sin el--stdout
, y generará un conjunto de.patch
archivos. Estos archivos se pueden alimentar directamentegit am
congit am --directory blue/red/ path/to/*.patch
.fuente
--directory
opción parece requerir que especifique la ruta completa del directorio en relación con la raíz del repositorio; algo así como--directory=./
mientras chdir'd en un subdirectorio en el repositorio no funcionará.--3way
ayudas condoes not exist in index
:git am --3way --directory (relative-path) (patch)
-k
tecla en ambos comandos para no eliminar la primera línea del mensaje de confirmación.--3way
no solo ayuda con los errores "no existe en el índice" (como lo señala @nobar), sino que también le permite manejar limpiamente los conflictos de fusión. En lugar de dejar intactos los archivos en conflicto, se agrega un bloque de conflicto que luego se puede resolver.Respondiendo a mi propia pregunta con un script que hace exactamente esto: https://github.com/mprpic/apply-patch-to-file
En lugar de modificar el archivo de parche manualmente, solicita al usuario el archivo de destino, modifica el parche y lo aplica al repositorio en el que se encuentra actualmente.
fuente
Sobre la base de la respuesta de @georgebrock, aquí hay una solución que utilicé:
Primero, cree los archivos de parche como de costumbre (p. Ej.
git format-patch commitA..commitB
).Luego, asegúrese de que su repositorio de destino esté limpio (no debe haber archivos modificados o sin seguimiento) y aplique los parches de esta manera:
Por cada archivo de parche, obtendrá un error como "error: XYZ no existe en el índice". Ahora puede aplicar este archivo de parche manualmente:
Tienes que seguir estos tres pasos para cada archivo de parche.
Esto preservará el mensaje de confirmación original, etc. sin requerir ningún
git format-patch
comando especial o editar los archivos de parche.fuente
git format-patch -1 commitA --stdout > thing.diff
; (2) Edite el archivo de parche hasta que haga lo que necesito; (3) Texto para confirmargit am --3way thing.diff
que tiene la ventaja de que puede aceptar las partes del parche que se aplican limpiamente y utilizargit
el proceso estándar de resolución de conflictos para las partes que no lo hacen.Entiendo que los dos archivos son exactamente iguales en su situación, por lo que es probable que el parche tenga éxito.
Sin embargo, en caso de que desee aplicar un parche a un archivo similar, pero no exactamente el mismo, o si desea realizar un parche interactivo, utilizará la combinación de tres vías.
Digamos que modificado el archivo
A
, denotan nos dejóA~1
que la versión anterior, y que desea aplicar el diff entreA~1
aA
al archivoB
.Abra una herramienta de combinación de tres vías, por ejemplo Beyond Compare, la ruta del panel izquierdo es
A
, el panel central es el ancestro común, por lo que la ruta esA~1
, la ruta del panel derecho esB
. A continuación, la muestra panel inferior el resultado de aplicar el diff entreA~1
aA
al archivoB
.La siguiente figura ilustra la idea.
fuente
FYI: Recientemente tuve problemas al intentar descargar un parche de Github y aplicarlo a un archivo local (que era una "anulación" en una nueva ubicación).
git am
no aplicaría el parche porque el archivo "no estaba en el índice" o "sucio". Pero descubrí que elpatch
comando simple podría aplicar el parche. Me pidió el nombre del archivo a parchear.Hice el trabajo, de todos modos ...
fuente