2010-02-11 33 views
9

Digamos que tengo dos depósitos diferentes, así:Cómo rebasar una cesión temporal a otro

Project 1: 
Init---A---B---C---HEAD1 

Project 2: 
Init---D---E---F---G---HEAD2 

¿Hay una manera de reajustar el proyecto 1 (Init a la cabeza) a la Init cometer de Proyecto 2 para que se vea de esta manera:

Project 1 & 2: 
    A---B---C---HEAD1 
/
Init---D---E---F---G---HEAD2 

El contenido del Proyecto 1 Proyecto 2 & son similares. La principal diferencia es que su estructura de archivos es ligeramente diferente de este modo:

Project1: 

MyProject/ 
    File1 
    File2 
    File3 

Project2: 

MyParentProject/ 
    MyProject/ 
     File1 
     File2 
     File3 
    SomeFolder/ 
    SomeOtherFolder/ 
    ...etc/ 

FYI: MiProyecto no es un submódulo de MyParentProject. MyProject y MyParentProject existen en dos ubicaciones separadas como dos repositorios git separados.

+0

Simplemente tener las historias en un solo repositorio y darles un ancestro común "viejo" no suena particularmente útil. ¿Cuál es tu motivación aquí? ¿Qué es lo que quieres hacer que no puedes hacer con repositorios separados? –

Respuesta

0

Creo que podría usar git-filter-branch con la opción --parent-filter.

12

Puede tratar uno como un repositorio remoto al otro. En Proyecto1, ejecute estos comandos:

git remote add project2 <path_to_project_2> 
git fetch project2 
git branch --track project2Branch project2/master 
git checkout project2Branch 

uso git log para encontrar el hash para el primer compromiso de esa rama (que es Project2). A continuación, ejecute

git checkout master # or whatever branch you want to rebase 
git rebase <hash-for-commit> 

Ahora ha rediseñado Project1 con Project2. Dado que esto suena como una operación de una sola vez, donde sólo entonces a utilizar el repositorio, puede limpiar con

git remote rm project2 

Así que ahora su rama principal se reajusta con el inicio de Project2, y el resto tiene project2Branch de la historia de Project2. Es una especie de truco, pero hará lo que quieras.

+0

'git fetch master: project2Branch' recuperará el otro proyecto sin crear un control remoto temporal. –

+0

Esto funciona hasta cierto punto, pero lamentablemente algunos errores ocurren porque las estructuras de archivos no coinciden. Por ejemplo, digamos que modifiqué File1 en el Proyecto 1, porque File1 no existe en la carpeta raíz del Proyecto 2. Git no combina los cambios de manera apropiada. – dirtytofu

0

La solución que utilicé fue de la siguiente manera:

  • En Proyecto 2:

    git format-patch <commit> --stdout > /path/to/patch.diff 
    

    Dónde <commit> se refiere a la primera comprometerse en el "de" repositorio que desea fusionar a el objetivo".

  • En Proyecto 1:

    git am /path/to/patch.diff 
    

Esto reproduce cada commit <commit>-HEAD en Proyecto 2 en Proyecto 1.

Esto evita por completo la necesidad de un ancestro común entre los proyectos, como lo requieren la mayoría de las herramientas específicas de git.

0

Puede agregar el otro repositorio a su repositorio actual primero como control remoto y luego hacer una rebase --onto para rebasear un rango de confirmaciones de un repositorio a un punto de confirmación común en el primer repositorio.

git remote add project2 <...> 
git checkout project2-master 
git rebase -s recursive -X theirs --onto \ 
    project1-first-commit project2- start-commit project2-end-commit 

Roughly gusta eso. No es que también especifique la estrategia de fusión para usar las confirmaciones del proyecto2 si hay conflictos. Es posible que desee usar algo más. Pero aquí suponemos que project2 es el código "correcto" y project1 es solo un master remoto.

Cuestiones relacionadas