2012-07-12 12 views
11

Resumen: ¿Cuáles son las mejores prácticas para gestionar el seguimiento de larga ejecución de repositorios en sentido ascendente en los que desea mantener un conjunto de cambios locales?Práctica recomendada para realizar el seguimiento en sentido ascendente en fork en github

Quiero mantener un fork en github actualizado con el upstream pero aún así permitir un seguimiento claro de los cambios exclusivos de la horquilla. (Para esta discusión, asumen que upstream puntos en el repositorio principal del proyecto y que se refiere a mi origin tenedor del repositorio)

Imagínese que tengo algo como esto donde bifurcada un repositorio cuando aguas arriba/maestro estaba en E.

Upstream: 
A-B-C-D-E-F 


Fork:  
A-B-C-D-E ----- P ------T 
     \-L-M-/ \-Q-R-/ 

Después de horquizar el repositorio creé dos ramas de características (LM y QR) para agregar nuevas características que necesitaba y fusionarlas de nuevo a mi origen/maestro. Así que ahora mi sucursal tiene mejoras que no existen en sentido ascendente.

Me parece que el upstream tiene un par de soluciones interesantes, así que quiero volver a sincronizar con el upstream. En función de la mayoría de las referencias que he encontrado (git hub fork), la forma recomendada de hacerlo es fusionar el original/maestro en sentido ascendente/maestro y continuar en el camino. Así que emitiría órdenes como:

git checkout master 
git fetch upstream 
git git merge upstream/master 
git push 

continuación, me gustaría terminar con repositorios que tiene este aspecto:

Upstream: 
A-B-C-D-E-F 


Fork:  
A-B-C-D-E ----- P ------T-F' 
     \-L-M-/ \-Q-R-/ 

Hay un par de problemas que veo con esto, sin embargo.

  1. Realmente no tengo commit F en mi repositorio, tengo F 'que tiene el mismo contenido, pero un hash diferente. Por lo tanto, no puedo hacer referencia fácilmente a los commits entre los dos repositorios y saber que tengo un cambio. (se vuelve aún más complejo cuando se considera que el upstream probablemente tiene más de un cambio y tiene su propio conjunto de ramas de características que se han fusionado)

  2. A medida que avanzo y sigo haciendo esto, me resulta cada vez más difícil saber qué cambios tengo en mi repositorio más allá de lo que está en la parte superior. Por ejemplo, puedo enviar algunos de estos cambios en sentido ascendente mientras sigo agregando mis propios refinamientos. Después de varias iteraciones de esto, ¿cómo puede alguien que mira en mi repositorio saber cómo difiere de upstream? (¿Hay un comando git para encontrar estos cambios?)

  3. Al igual que en el n. ° 2, ¿cómo encontraría alguien una solución en el flujo ascendente y verificará si mi tenedor contiene la solución?

supongo que la raíz del problema es que no hay manera de que yo garantizo que mi repositorio está en la "sincronización" con el ascendente en cualquier momento dado, porque el código y los valores hash no son los mismos. Entonces, ¿cómo hago para seguir los cambios con precisión y evitar volverme loco tratando de mantener las cosas sincronizadas?

Nota: Yo había considerado usar rebase para mantener el repositorio de mi repositorio de flujo ascendente, pero esto tiene un conjunto de problemas completamente diferente. Por ejemplo, si alguien hace referencia a mi repositorio a través de submódulos, ramas, etc., entonces la reescritura del historial romperá sus referencias. Además, no creo que el historial de mi sucursal sobreviviera a la rebase, así que no tendría una vista completa de todas las ramas de características que había creado y el historial asociado.

¿Cómo lo manejan otras personas? ¿Cuáles son algunas de las mejores prácticas que debería investigar?


Actualización:

Con base en la retroalimentación de Seth, he creado un conjunto de repositorios de prueba para mostrar lo que estaba hablando y cómo funciona de la manera que él dice.

Los repositorios son:

Deben mostrar más claramente cómo la fusión de aguas arriba se ve cuando hay cambios locales.

Respuesta

10

Usted es incorrecto en su asunción. Usted dijo en su ejemplo de texto que estaría ejecutando el comando git merge. Si realmente quiso decir esto, y no git cherry-pick (y para el registro, git-merge es la mejor práctica en la situación) entonces NO obtiene F` en su rama, obtiene F. Quizás una imagen:

Después la traen, pero antes de la fusión, los repos este aspecto:

Upstream: 
A-B-C-D-E-F [master] 


Fork: /-F     [upstream/master] 
A-B-C-D-E ----- P ------T  [master] 
     \-L-M-/ \-Q-R-/  [Other branches] 

Después de combinar, tu repositorio se verá así:

Fork: /-F-------------\ [upstream/master] 
A-B-C-D-E ----- P ------T-U [master] 
     \-L-M-/ \-Q-R-/  [Other branches] 

Nueva cometer "U" en tu repositorio será una combinación cometer, al igual que comete "P" y "T".

git cherry-pick crearía "F" como lo indicó en su ejemplo. No hagas eso. git rebase a veces puede dar soporte a las ramas de rebase git rebase -p pero no siempre funciona. Además, eso es reescribir la historia pública, lo cual es una mala idea.

Tengo un documento sobre las mejores prácticas de git: Commit Often, Perfect Later, Publish Once Es posible que desee investigar específicamente la sección del flujo de trabajo para obtener más inspiración.

+0

Gracias por los consejos. Agregué un ejemplo para mostrar que se comporta como lo describes. Parece obvio ahora, pero me perdí el punto de la fusión que traía la historia de la corriente ascendente con la coincidencia de hash de confirmación. Todavía queda una pregunta: si estoy en la bifurcación, ¿cómo puedo encontrar fácilmente todos los cambios en los que soy diferente de la versión anterior y hacerlo de una manera que me permita comprender/ver qué características tiene la horquilla que la corriente ascendente no lo hace? – Allen

+0

@Allen: 'git log -graph --decorate --oneline master..upstream/master' Dependiendo de lo que esté intentando hacer, cambie el orden de los dos. argumentos separados o cambiar el número de puntos a tres pueden ayudar. –

Cuestiones relacionadas