¿Cómo renombrar el file en la twig, fusionar y tener dos files con historial en Git?

Tengo un repository git con las siguientes twigs:

older: file (with, say, 10 commits) newer: file (10 commits from "older" plus 5 new commits) 

La twig "más nueva" se ramificó desde la twig "más antigua" como algún punto.

Me gustaría fusionar ambas twigs en master, tener ambas versiones de "file" como dos files diferentes y quiero mantener el historial de ambos:

 master: file-as-seen-in-older (10 commits) file-as-seen-in-newer (15 commits) 

Aquí hay una forma robusta y segura de cambiar el nombre del file, usando git rebase . Esto funcionará perfectamente en el caso simple en que su sucursal sea newer y / o older divergió del maestro (o alguna otra sucursal) y no se fusionó en nuevos cambios de la sucursal padre después de eso, eliminando el antiguo nombre de file completamente de su historial.

(Si ocurrieron tales fusiones, entonces el command sigue siendo seguro, y el resultado final es el mismo, pero puede que no limpie su historial tan atrás como quisiera).

  1. Elija en qué twig desea cambiar el nombre de file. Verifique esa twig. Asumiré que elegiste older .

     $ git checkout older 
  2. Ahora, necesitamos encontrar la base de fusión de los older y sus padres. Aquí es donde los older divergen de sus padres, creando una historia nueva e independiente. Normalmente puede encontrar esto fácilmente navegando en git log o gitk , pero podemos encontrarlo con un simple command. (Asumiré que el master es el padre de older ).

     $ git merge-base older master 914b05d90e1de0ff9f89370810888c7f192d65cc $ git tag base 914b05d 

    En mi repository, git merge-base 914b05d identificador de confirmación 914b05d . Etiquetamos la confirmación con la base tags para facilitar la reference.

  3. Ahora, haz una base datos interactiva en la base

     $ git rebase --interactive base 
  4. En la window del editor que aparece, verifique que liste cada confirmación en anterior, desde el momento en que divergió de su matriz, hasta la última confirmación.

    • Mover al primer compromiso.
    • Cambie la pick palabra para edit . Pronto editaremos este compromiso para cambiar el nombre del file.
    • Ahora, mira hacia abajo a través de los otros commits. Cualquiera que mencione el file nombre en el post de confirmación deberá ser reformulado. Cambie la pick por la reword para tener la oportunidad de volver a networkingactar los posts de confirmación apropiados.
    • Guarda el file y cierra.
  5. Ahora, tu rebase comenzará! git revisará el primer compromiso y se detendrá, esperando que usted modifique el compromiso. Aquí, podemos mover el file y comenzar la rebase nuevamente.

      $ git mv file file-from-older $ git rebase --continue 

    git corregirá la confirmación con sus cambios, y luego abrirá su editor para permitirle volver a networkingactar la confirmación. Cambie las references al file para decir file-from-older en file-from-older lugar. Guarda el file y cierra.

  6. Cualquier compromiso que haya marcado para la reword también aparecerá en su editor. Edítalos de la misma manera. (Si se olvidó de marcar un compromiso para volver a networkingactar, puede volver a establecer la base de nuevo)

  7. Una vez que termina la rebase, examine el resultado, con git log o gitk . Observa eso

    • El nombre del file original no existe en su tree de trabajo
    • o en tu historia, y eso
    • older twigs todavía older viejas de su padre en el mismo lugar, a saber, base .

    Si alguna de estas cosas es falsa, algo salió mal (tal vez un error tipográfico), y tenemos que deshacer la confirmación. Podemos hacer eso fácilmente con git reset --hard older@{1} , que se restablece a su estado anterior a la rebase. Luego puede repetir la operación de rebase y descubrir dónde salió mal.

  8. Ahora que ha verificado el éxito de la rebase, puede fusionar sus cambios en master o donde sea. Si desea cambiar file nombre del file en ambas twigs, simplemente repita el process para la twig newer también.

  9. Finalmente, puedes fusionar tus twigs en master :

     $ git checkout master $ git merge older newer 

    Al mostrar cualquier conflicto (no relacionado), esto debería ir sin problemas.