¿Cómo aplicar un parche de git de un repositorio a otro?


Tengo dos repositorios, uno es el repositorio principal de una biblioteca, y el otro es un proyecto que usa esa biblioteca.

Si hago una corrección en el proyecto subordinado, me gustaría una forma fácil de aplicar ese parche de nuevo hacia arriba.

La ubicación del archivo es diferente en cada repositorio.

  • Principal repo: www.playdar.org/static/playdar.js
  • Proyecto: playlick.com/lib/playdar.js

Traté de usar git format-patch -- lib/playdar.js en el proyecto playlick, y luego git am en el el repositorio principal de playdar, pero las diferentes ubicaciones de los archivos en el archivo de parche generaron un error.

¿Hay una manera fácil de aplicar el parche de una confirmación dada en un archivo dado a otro archivo arbitrario en otro lugar?

Para los puntos de bonificación, ¿qué pasa si el archivo al que desea aplicar el parche no está en un repositorio git?

Author: CharlesB, 2009-05-31

8 answers

Si la edición manual del archivo de parche está fuera de cuestión o es inviable, esto se puede hacer con opciones estándar (disponibles en git apply, git format-patch y GNU patch).

  1. -p<n> elimina n los directorios principales de las rutas del parche.

  2. Después del procesamiento -p, --directory=<root> antepone root a cada una de las rutas del parche antes de aplicar.

Ejemplo

Así que, para su ejemplo, tomar un parche que estaba originalmente en static/playdar.js y aplicarlo a lib/playdar.js, se ejecutaría:

$ cat patch_file | git am     \ 
          -p1                 \ # remove 1 leading directory ('static/')
         --directory='lib/'     # prepend 'lib/'
 84
Author: vergenzt,
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-26 18:46:49

El parche producido por git format-patch es simplemente un archivo de texto you puede editar los encabezados diff para que modifique una ruta diferente.

Así que, por ejemplo, habría producido algo como esto:

diff --git a/lib/playdar.js b/lib/playdar.js
index 1234567..89abcde
-- a/lib/playdar.js
++ b/lib/playdar.js

Todo lo que tienes que hacer es cambiar lib/playdar.js a static/playdar.js y luego ejecutar el parche a través de git am"

El parche debe ser legible por la utilidad de parche GNU estándar para personas que no tienen git - - - pero no ejecutan format-patch con el -M, -C etc. opciones para producir parches de cambio de nombre en que caso, porque el apoyo para ellos no es universal.

 36
Author: araqnid,
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-09-16 12:26:21

Suponiendo que ambos proyectos son proyectos de git, suena como que submódulos sería el ajuste perfecto para usted. Esto permite que un proyecto de git se vincule dinámicamente a otro proyecto de git, esencialmente horneando un repositorio de git dentro de otro repositorio de git, ambos teniendo sus propias vidas distintas.

En otras palabras, agregue "repositorio principal" como un submódulo en "proyecto". Cada vez que confirmas/envías cosas nuevas en "repositorio principal", simplemente git pull las devuelves al "proyecto".

 4
Author: Henrik Paul,
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
2009-05-31 11:48:17

Para completar La respuesta de Henrik , y para ir por el punto de bonificación

¿Qué pasa si el archivo al que desea aplicar el parche no está en un repositorio git?

Si tiene acceso a los directorios del archivo candidato para un parche que proviene de un repositorio git, primero podría transformar ese árbol de directorios/archivos en un repositorio git. ('git init': un repositorio git es solo a .git dentro de un directorio raíz después de todo).
Entonces usted establecería ese repo como un submódulo para su proyecto principal.

 2
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
2017-05-23 11:54:43

Puede agregar un nuevo control remoto y extraer de él. Artículo con detalles.

$ cd <path-to-repoB>
$ git remote add repoA <git-URL-for-repoA>
$ git pull repoA
 1
Author: Der_Meister,
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-12-29 06:25:34

Creo que el subárbol es la mejor solución para su problema

Tutorial 1

Tuorial 2

 0
Author: Mauro,
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-02-12 14:00:29

Puede simplemente eliminar (renombrar) temporalmente el repositorio principal.

cd to/main/project
mv .git .git_
cd to/sub/project
git apply patchname
cd -
mv .git_ .git
 0
Author: ya.teck,
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-03-03 09:29:25

Usando la opción --relative para format-patch puede mejorar la abstracción (ocultar detalles irrelevantes sobre el repositorio desde el que se generó el parche).

[repository-with-changes]
git format-patch --relative=(path-to-library) (base-commit-for-patch) ## 'HEAD~1'

He encontrado que la opción --3way es necesaria al aplicar el parche (para evitar un error does not exist in index) your su kilometraje puede variar. Es probable que usar --directory=(...) solo sea necesario si su ruta de destino no es la raíz del repositorio.

[repository-to-update]
git am --3way --directory=(path-to-library) (patch-file)

  • format-patch creará un archivo de parche por confirmación a la rama actual desde "base".

  • La documentación para la opción --relative parece que falta en algunos casos, pero parece funcionar de todos modos (a partir de la versión 2.7.4).

 0
Author: nobar,
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-12-11 14:56:09