volver restaurar recuperar from especifico borrado git patch git-submodules git-patch

git - restaurar - recuperar commit borrado



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

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

Tutorial 1

Tuorial 2

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

Si hago una corrección en el proyecto subordinado, me gustaría una manera fácil de aplicar ese parche en sentido ascendente.

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

  • Repo principal: www.playdar.org/static/playdar.js
  • Proyecto: playlick.com/lib/playdar.js

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

¿Existe una manera fácil de aplicar el parche de un compromiso dado en un archivo dado a otro archivo arbitrario en otro lugar?

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


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

Entonces, 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 estándar de GNU para las personas que no tienen git --- pero no ejecutan format-patch con las opciones -M , -C etc. para producir parches de cambio de nombre en ese caso, porque El apoyo para ellos no es universal.


El uso de la opción --relative al format-patch puede mejorar la abstracción (ocultar detalles irrelevantes sobre el repositorio desde el cual se generó el parche).

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

He encontrado que se requiere la opción de --3way para aplicar el parche (para evitar does not exist in index error de does not exist in index ), su millaje puede variar. El uso de --directory=(...) es probable que solo sea necesario si la 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 faltar en algunos casos , pero parece funcionar de todos modos (a partir de la versión 2.7.4).


Para completar la respuesta de Henrik , y obtener el punto de bonificación.

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

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


Puedes agregar un nuevo control remoto y tirar de él. Artículo con detalles.

$ cd <path-to-repoB> $ git remote add repoA <git-URL-for-repoA> $ git pull repoA


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

  1. -p<n> elimina n directorios principales de las rutas en el parche.

  2. Después de procesar -p , --directory=<root> antepone la root a cada una de las rutas en el parche antes de aplicar.

Ejemplo

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

$ cat patch_file | git am / -p1 / # remove 1 leading directory (''static/'') --directory=''lib/'' # prepend ''lib/''


Solo puedes eliminar (renombrar) temporalmente el repositorio principal.

cd to/main/project mv .git .git_ cd to/sub/project git apply patchname cd - mv .git_ .git


Suponiendo que ambos proyectos son proyectos git, parece que los submodules serían el ajuste perfecto para usted. Esto permite que un proyecto de git se vincule dinámicamente con otro proyecto de git, esencialmente horneando un repositorio de git dentro de otro repositorio de git, y ambos tienen sus propias vidas distintas.

En otras palabras, agregue "repositorio principal" como submódulo en "proyecto". Cada vez que cometas / presionas cosas nuevas en "repo principal", simplemente las regresas al "proyecto".