git: obtén los beneficios de `git rebase –interactive` para cherry picks

Me gustaría poder hacer esto:

git cherry-pick --interactive hash-0..hash-n-1 # fantasy command 

y obtenga el mismo flujo de trabajo que la database interactiva: aparece un búfer de editor que contiene:

 pick hash-0 pick hash-1 pick hash-2 ... pick hash-n-1 

donde puedo eliminar los commits no deseados, squash o edit para pausar entre los picks y hacer algunos commit --amend manuales (como commit --amend ) y todo eso.

Tenga en count cómo la pick de la rebase interactiva es tanalizingly como cherry-pick .

Ahora la operación anterior se puede realizar al realizar primero la selección de cereza, y luego la rebase interactiva, lo cual es inconveniente. Es decir:

 $ git tag old-head # mark starting point for later rebase $ git cherry-pick hash-0..hash-n-1 # get everything first $ git rebase --interactive old-head # okay now rebase "in-branch" to fix it up 

No solo es inconveniente debido a los dos pasos, sino porque puede requerir resolver conflictos en commits que ni siquiera desea que se descarten en la etapa de rebase.

Bueno, descubrí un buen truco.

Comience una rebase --interactive HEAD^ trivial rebase --interactive HEAD^ sobre una confirmación en su twig actual. Obtienes algo así como:

 pick 1efd396b * Fixed a bug in frob function 

Ahora, simplemente pegue los hashes adicionales que quiera elegir:

 pick 1efd396b * Fixed a bug in frob function pick f01934db * Awesome feature added pick 6fd109c1 * Refactonetworking the widgets layer squash 3900fd77 * Refactonetworking the widgets layer s'more 

Guarde y salga, y pequeñito: la mula de rebase toma el cruto adicional que cargó en su parte posterior y lo incorpora a la twig actual de acuerdo con los commands.

En realidad puedes hacer una rebase vacía con:

 git rebase --interactive HEAD 

obtienes un buffer que contiene

 noop 

No tienes que borrar eso; solo agregue sus selects después de eso.

Adición: Para producir las lists de selección para este método, use git log --oneline --reverse from..to , luego recorte la salida necesaria y anteponga los commands de rebase a cada línea: pick , squash , …

De acuerdo, siguiendo la sugerencia de Carl Norum, --onto argumento --onto de git rebase .

El caso de uso puede satisfacerse así, lo cual es una mejora, aunque todavía implica un número excesivo de pasos.

El problema principal es que la rebase necesita una twig actual para elegir, por lo que tenemos que cambiar nuestras coorderadas a una twig temporal, y luego manipular nuestra twig raíz original luego y eliminar la twig temporal.

El flujo se ve así:

 # We are originally on "mybranch" # We create a temp-branch pointing to the last commit to be picked: hash-n-1 $ git checkout -b temp-branch hash-n-1 # create branch at last hash # Then we rebase from the point before the first hash, onto our original branch $ git rebase --interactive hash-0^ --onto mybranch # The above rebase should make "temp-branch" into the very object that # we want "mybranch" to be. If it looks that way, then all that is left is # make it so: $ git checkout mybranch $ git reset --hard temp-branch $ git branch -D temp-branch 

El git rebase --interactive hash-0^ --onto mybranch utiliza el commit before hash-0 como el "upstream" para la rebase, tomando todos los commits de la twig actual (basado en hash-n-1 ) que no son en la stream ascendente. Esos compromisos son, por supuesto, hash-0 a hash-n-1 . Se vuelven a establecer en la cabeza de mybranch , pero es la temp-branch actual la que se reset --hard es reset --hard seguir el resultado. Entonces solo tenemos que asignar ese puntero a mybranch y eliminar temp-branch .

Es bastante torpe, pero elimina el duplicado de la recolección de cerezas, y es fácil recuperarlo en cualquier momento solo con el git reset --hard mybranch .

(¿Esto aún puede mejorarse?)

Tal vez haya una mejor respuesta, pero esto podría funcionar para usted

 git cherry | awk '$0=$2' > cherry.txt "$EDITOR" cherry.txt git cherry-pick --stdin < cherry.txt 

Ejemplo