Rebase y rebase interactivo trabajan con el conjunto de commits de una rama: los descomponen, los reordenan, los reaplican. git cherry-pick hace algo mucho más quirúrgico: coge un commit concreto, esté donde esté, y aplica su cambio sobre la rama en la que estás ahora, creando un commit nuevo.
El nombre lo dice todo: cherry-picking es escoger las cerezas una a una. Y como toda herramienta quirúrgica, es excelente en manos que saben cuándo usarla y peligrosa en manos que la usan por costumbre. Un cherry-pick mal puesto duplica trabajo, confunde el historial y provoca conflictos absurdos meses después.
Ana lo necesita hoy. Ha corregido en main el fallo de que el foco se pierde al borrar una tarea, y la versión 1.x que sigue desplegada en el cliente tiene el mismo fallo pero vive en una rama de mantenimiento aparte, que no puede recibir todo lo que hay en main. Quiere ese commit y nada más.
Contenido
- Qué hace
git cherry-pick - El caso de Ana: llevar una corrección a mantenimiento
- Varios commits y rangos
- Opciones útiles:
-n,-x,-e,-s - Conflictos al hacer cherry-pick
- Rescatar un commit de una rama abandonada
- El problema de los duplicados
- Detectar duplicados:
git cherryy--cherry-mark - Cuándo NO usar cherry-pick
- Qué hace
git cherry-pick
git cherry-pickGit toma el diff que introduce <sha> (es decir, la diferencia entre ese commit y su padre), lo aplica sobre el estado actual de tu rama y crea un commit nuevo con ese cambio.
La palabra clave, otra vez, es nuevo. Igual que en el rebase (lección 05-01), y por el mismo motivo del modelo de datos de la lección 01-04: el commit resultante tiene otro padre, luego otro contenido, luego otro hash. No es "el mismo commit en dos ramas": son dos commits distintos que casualmente introducen el mismo cambio.
gitGraph commit id: "1a4c8d6" commit id: "8b6d3c2" branch mantenimiento/1.x commit id: "e4f7b91" checkout main commit id: "c5d9b1e" commit id: "7d3a8f4" checkout mantenimiento/1.x cherry-pick id: "7d3a8f4"
El diagrama miente un poco a propósito, porque gitGraph reutiliza la etiqueta del commit original. En realidad, en mantenimiento/1.x aparece un commit distinto, con hash b9e2c17, que introduce el mismo cambio que 7d3a8f4. Recuérdalo cada vez que veas un diagrama de cherry-pick: la flecha punteada significa "el mismo cambio", nunca "el mismo objeto".
Qué se conserva y qué no, para completar la tabla mental que empezaste en 05-01:
| Elemento | ¿Se conserva? |
|---|---|
| Mensaje | Sí (editable con -e) |
| Autor y correo | Sí: sigue siendo de quien lo escribió |
| Fecha de autoría | Sí |
| Confirmador y su fecha | No: pasas a serlo tú, ahora |
| Contenido del cambio | Sí, si no hay conflicto |
| Padre y hash | No |
Que se conserve la autoría es importante: cuando llevas la corrección de un compañero a otra rama, el crédito sigue siendo suyo.
- El caso de Ana: llevar una corrección a mantenimiento
El repositorio de gestor-tareas tiene dos líneas vivas:
main, donde se desarrolla la versión 2.mantenimiento/1.x, que reproduce lo que está desplegado en el cliente y solo recibe correcciones.
Ana corrigió el fallo del foco en main:
7d3a8f4 (HEAD -> main, origin/main) Devolver el foco al campo de texto tras borrar una tarea c5d9b1e Extraer la creación del elemento de tarea a su función 8b6d3c2 Guardar las tareas en localStorage
El commit es pequeño y autocontenido, que es exactamente lo que hace a un commit buen candidato para cherry-pick:
commit 7d3a8f4...
Author: Ana Ferrer <[email protected]>
Date: Wed Jul 29 11:42:08 2026 +0200
Devolver el foco al campo de texto tras borrar una tarea
diff --git a/app.js b/app.js
--- a/app.js
+++ b/app.js
@@ -48,6 +48,7 @@ function borrarTarea(id) {
tareas = tareas.filter(function (t) { return t.id !== id; });
guardarTareas();
pintarLista();
+ document.getElementById('nueva-tarea').focus();
}Ahora, el trasplante:
e4f7b91 (HEAD -> mantenimiento/1.x, origin/mantenimiento/1.x) Corregir el formato de la fecha en el listado 8b6d3c2 Guardar las tareas en localStorage
[mantenimiento/1.x b9e2c17] Devolver el foco al campo de texto tras borrar una tarea Date: Wed Jul 29 11:42:08 2026 +0200 1 file changed, 1 insertion(+)
commit b9e2c17...
Author: Ana Ferrer <[email protected]>
Date: Wed Jul 29 11:42:08 2026 +0200
Devolver el foco al campo de texto tras borrar una tarea
(cherry picked from commit 7d3a8f4c9b1e5d2a8f7c3b6e9d4a1c8f5b2e7d3a)
diff --git a/app.js b/app.js
...Hash nuevo (b9e2c17), autoría de Ana intacta, cambio idéntico, y una línea al final del mensaje que dice de dónde vino. Esa línea la ha puesto -x, y merece su apartado.
- Varios commits y rangos
git cherry-pick acepta varios commits sueltos y rangos.
Se aplican en el orden en que los escribes, no en orden cronológico. Si dependen unos de otros, escríbelos en el orden en que se hicieron o tendrás conflictos evitables.
Los rangos usan la misma notación de dos puntos de la lección 02-06, y con la misma trampa:
# Del commit SIGUIENTE a A, hasta B (ambos inclusive salvo A)
git cherry-pick A..B
# Desde A INCLUIDO hasta B
git cherry-pick A^..B| Expresión | Commits aplicados |
|---|---|
A..B |
Los posteriores a A hasta B. A NO se incluye |
A^..B |
Igual, pero A sí se incluye |
B |
Solo B |
B~3..B |
Los tres últimos hasta B |
--stdin |
Los que le pases por la entrada estándar, uno por línea |
Ejemplo con nombres reales: Bruno quiere llevar a mantenimiento los tres commits de correcciones que hizo en funcionalidad/exportacion-csv, que van de 6e1d9f3 a 9c7e5a1:
[mantenimiento/1.x 3a8f2d5] Añadir la conversión de tareas a formato CSV [mantenimiento/1.x 7b4e9c1] Descargar el CSV generado desde el navegador [mantenimiento/1.x d62a4f8] Añadir el botón de exportar a la barra de acciones
Tres commits nuevos con tres hashes nuevos, en el orden correcto.
Un aviso importante: un rango de cherry-pick no incluye los commits de fusión. Si el rango contiene una fusión, Git la salta silenciosamente (o falla, según el caso). Trasplantar un commit de fusión requiere -m para elegir el padre respecto al cual calcular el diff, igual que en revert (lección 05-06), y casi nunca es lo que quieres. Si tu rango tiene fusiones, probablemente lo que buscabas era un merge o un rebase.
- Opciones útiles:
-n, -x, -e, -s
-n, -x, -e, -s| Opción | Nombre largo | Qué hace |
|---|---|---|
-n |
--no-commit |
Aplica los cambios al directorio de trabajo y al índice, sin confirmar |
-x |
— | Añade (cherry picked from commit <sha>) al mensaje |
-e |
--edit |
Abre el editor para modificar el mensaje |
-s |
--signoff |
Añade una línea Signed-off-by: Nombre <correo> |
--ff |
— | Si el commit es hijo directo de HEAD, hace fast-forward en vez de crear uno nuevo |
--strategy-option |
-X ours / -X theirs |
Resolución automática de conflictos por un lado |
--allow-empty |
— | Permite crear el commit aunque no aporte cambios |
-n (--no-commit) sirve para agrupar. Si quieres que cinco commits pequeños lleguen a la rama de destino como uno solo:
Los tres cambios quedan preparados en el índice y tú decides cuándo y con qué mensaje confirmarlos. Si te arrepientes a mitad, git cherry-pick --abort deshace todo lo acumulado.
-x es fundamental en ramas de mantenimiento y es la razón por la que existe la opción. Deja una nota en el mensaje que permite, meses después, contestar a la pregunta "¿de dónde salió este commit?":
Devolver el foco al campo de texto tras borrar una tarea (cherry picked from commit 7d3a8f4c9b1e5d2a8f7c3b6e9d4a1c8f5b2e7d3a)
Con esa línea, git show 7d3a8f4 te lleva al original y puedes ver su contexto completo. Sin ella, el commit aparece en la rama de mantenimiento sin explicación posible.
Cuidado con un matiz: -x solo tiene sentido cuando el commit de origen es público. Si copias un commit de una rama local que vas a borrar, la referencia apuntará a un hash que nadie más puede resolver, y la nota confunde más que ayuda. La documentación de Git es explícita en esto: úsalo para copiar de una rama pública a otra.
-s añade la línea Signed-off-by:, una convención de proyectos que exigen certificar el origen de las aportaciones (el Developer Certificate of Origin del núcleo de Linux es el caso canónico). No es una firma criptográfica; eso son las etiquetas y commits firmados con GPG, que se ven en la lección 08-05.
- Conflictos al hacer cherry-pick
Un cherry-pick aplica un parche sobre un contexto que puede haber cambiado. Es muy normal que conflictúe, sobre todo cuando la rama de destino ha divergido mucho.
Auto-merging app.js CONFLICT (content): Merge conflict in app.js error: could not apply 7d3a8f4... Devolver el foco al campo de texto tras borrar una tarea hint: After resolving the conflicts, mark them with hint: "git add/rm <pathspec>", then run hint: "git cherry-pick --continue". hint: You can instead skip this commit with "git cherry-pick --skip". hint: To abort and get back to the state before "git cherry-pick", hint: run "git cherry-pick --abort".
La mecánica de resolución —marcadores, git status, editar, git add— es la de la lección 03-05 y no cambia. Lo específico es cómo se sale:
| Comando | Qué hace |
|---|---|
git cherry-pick --continue |
Confirma el commit con tu resolución y sigue con el siguiente del rango |
git cherry-pick --skip |
Descarta ese commit y sigue con el resto |
git cherry-pick --abort |
Cancela toda la operación y devuelve la rama a su estado inicial |
git cherry-pick --quit |
Sale del estado de cherry-pick pero conserva lo ya aplicado |
Y aquí, buena noticia: en un cherry-pick, ours y theirs NO están invertidos. ours es tu rama de destino (donde estás) y theirs es el commit que estás trayendo, que es lo intuitivo. La inversión de la lección 05-01 es una peculiaridad del rebase, no una regla general.
# Durante un conflicto de cherry-pick
git checkout --ours app.js # la versión de mi rama de destino
git checkout --theirs app.js # la versión del commit que traigoSi el conflicto te parece muy grande para el tamaño del cambio, es una señal: probablemente estés portando un commit que depende de otro que no has portado. Mira git log --oneline <origen> alrededor del commit y comprueba si hay un commit previo que también hace falta.
Cuando el commit conflictúa porque su cambio ya está aplicado en la rama de destino, Git te lo dice de otra forma:
The previous cherry-pick is now empty, possibly due to conflict resolution.
If you wish to commit it anyway, use:
git commit --allow-emptyAhí, git cherry-pick --skip es la respuesta correcta: no hay nada que aportar.
- Rescatar un commit de una rama abandonada
El segundo caso legítimo. Carla empezó funcionalidad/etiquetas-color y el equipo decidió aparcarla: el enfoque no convencía. Pero dentro había un commit que sí valía: una función que valida el formato hexadecimal de un color y que resulta útil para otra cosa.
92c7a06 Pintar la etiqueta de color en el listado d5e8f31 Anadir el campo color al modelo de tarea 5f1c4b8 Añadir la validación de colores hexadecimales e91d4a8 Extraer la creación del elemento de tarea a su función
Aquí Carla no ha usado -x, y hace bien: la rama de origen se va a borrar, así que dejar en el mensaje una referencia a un hash que quedará huérfano no ayuda a nadie. En estos casos, si quieres dejar constancia, escríbela en lenguaje humano con -e:
Añadir la validación de colores hexadecimales Rescatado de la rama funcionalidad/etiquetas-color, que se descartó por otros motivos. La función es útil de forma independiente.
Un tercer caso, para completar el catálogo de usos legítimos: te has equivocado de rama. Has hecho tres commits en main que debían ir en una rama de funcionalidad. La solución clásica es crear la rama donde estás, y devolver main a su sitio; pero si prefieres no tocar main, un cherry-pick de los tres commits a la rama correcta es una salida perfectamente válida. La casuística completa de "he confirmado en la rama equivocada" está en la lección 09-01.
- El problema de los duplicados
Aquí es donde el cherry-pick pasa factura, y conviene entenderlo bien porque es la razón principal para no abusar de él.
Escenario: Bruno tiene funcionalidad/informe-semanal con cinco commits. Uno de ellos, 4d7c1a9, corrige un fallo que urge en producción ya. Bruno hace cherry-pick de ese commit a main:
Perfecto: el fallo está corregido en main y desplegado. Pero ahora, en el repositorio, el mismo cambio existe dos veces: como 4d7c1a9 en la rama de Bruno y como 2e9b6f3 en main.
gitGraph commit id: "e91d4a8" branch funcionalidad/informe-semanal commit id: "a1c5e83" commit id: "4d7c1a9" commit id: "6f2b9d4" checkout main commit id: "2e9b6f3"
Dos semanas después, Bruno termina la funcionalidad y fusiona su rama en main. ¿Qué pasa?
Caso bueno. Si nadie ha tocado esas líneas desde entonces, la fusión a tres bandas se da cuenta de que el cambio de 4d7c1a9 ya está aplicado en main (el resultado es el mismo por los dos lados) y la fusión sale limpia. El commit 4d7c1a9 entra en el historial, pero su contenido no se aplica dos veces. El resultado es correcto; simplemente el git log de main muestra dos commits que dicen lo mismo.
Caso malo. Si alguien ha modificado esas líneas en main después del cherry-pick, la fusión ve un cambio en theirs (el de 4d7c1a9) sobre una base que ya no coincide, y conflictúa. Es el conflicto más desconcertante que existe: los marcadores muestran dos versiones casi idénticas de un código que tú ya arreglaste, y no hay forma de entender por qué choca si no recuerdas el cherry-pick de hace dos semanas.
Caso peor. Si el cambio no es idempotente —añadir una línea a una lista, incrementar un contador, añadir una entrada a un fichero de configuración—, la fusión puede aplicarlo dos veces sin conflictuar. El resultado compila, pasa los tests superficiales y está mal.
La conclusión es la que da título al último apartado: cherry-pick es para cuando no vas a fusionar después, o para cuando fusionar no es una opción (ramas que nunca se juntan, como main y mantenimiento/1.x).
- Detectar duplicados:
git cherry y --cherry-mark
git cherry y --cherry-markGit tiene herramientas para reconocer commits que introducen el mismo cambio con hashes distintos. Se basan en el patch-id: un hash calculado sobre el contenido del diff, ignorando el contexto, las líneas en blanco y los números de línea. Dos commits con el mismo patch-id hacen lo mismo aunque sean objetos distintos.
git cherry compara dos ramas y marca cada commit con + (no está en la otra) o - (ya está allí, con otro hash):
+ a1c5e83f2b7d9c4e1a8f6b3d5c2e9a7f4b1d8c6e Añadir la vista del informe semanal - 4d7c1a9e8b2f5d3c7a9e1f4b6d8c2a5e3f7b9d1c Corregir el cálculo de tareas vencidas + 6f2b9d4c1e7a3f8b5d2c9e6a4f1b8d3c7e5a2f9b Añadir el filtro por semana
El - en la segunda línea significa: "este commit ya está aplicado en main, aunque allí tenga otro hash". Exactamente lo que buscábamos. La sintaxis es git cherry [-v] <upstream> [<head>], y -v añade el asunto de cada commit.
Es especialmente útil antes de fusionar o antes de portar un lote de commits a mantenimiento: te dice qué queda realmente por llevar.
git log --cherry-mark hace lo mismo dentro de un log, sobre un rango de tres puntos:
> a1c5e83 Añadir la vista del informe semanal = 4d7c1a9 Corregir el cálculo de tareas vencidas = 2e9b6f3 Corregir el cálculo de tareas vencidas > 6f2b9d4 Añadir el filtro por semana
| Marca | Significado |
|---|---|
< |
Solo en el lado izquierdo (main) |
> |
Solo en el lado derecho (la rama) |
= |
Presente en los dos lados como cambio equivalente (patch-id igual) |
Ahí están, uno al lado del otro, los dos commits que hacen lo mismo. Variantes relacionadas:
# Ocultar los equivalentes: solo lo que de verdad falta por integrar
git log --oneline --cherry-pick --left-right main...funcionalidad/informe-semanal
# Atajo de lo anterior, solo el lado derecho
git log --oneline --cherry funcionalidad/informe-semanal...main--cherry-pick es el que usarás más: filtra el ruido y te deja solo el trabajo pendiente de verdad.
Una limitación honesta: el patch-id compara el diff. Si al hacer el cherry-pick hubo un conflicto y resolviste de forma distinta, el diff resultante no será idéntico y Git no lo reconocerá como equivalente. La detección es una ayuda, no una garantía.
- Cuándo NO usar cherry-pick
| Situación | Qué hacer en su lugar |
|---|---|
| Quieres llevar toda una rama a otra | git merge (o rebase si aún no está publicada) |
| Vas a fusionar esa rama después, más adelante | Espera y fusiona: evitas los duplicados del apartado 7 |
| Necesitas más de tres o cuatro commits seguidos | rebase --onto: reaplica un tramo completo y no deja duplicados |
Quieres poner tu rama al día con main |
git merge main o git rebase main, nunca cherry-picks sueltos de main |
| El commit depende de otros que no vas a llevar | Portar también las dependencias, o rehacer el cambio a mano |
| Quieres "copiar" un commit a la misma rama | Casi seguro que buscas revert (05-06) o un rebase interactivo |
La regla de decisión, en una frase: si las dos ramas van a acabar juntándose, no copies commits entre ellas; fusiónalas. El cherry-pick es para ramas que viven en paralelo permanentemente (mantenimiento, versiones antiguas, entornos separados) o para rescatar algo de una rama que va a morir.
Sobre la regla de oro: el cherry-pick es de las tres operaciones de este bloque la menos peligrosa, porque no reescribe nada. Añade un commit nuevo a la rama donde estás; no toca el origen ni obliga a nadie a forzar un push. Su peligro no es la reescritura sino la duplicación, que se paga más tarde y en forma de conflictos difíciles de explicar.
Errores Comunes y Consejos
Error 1: creer que cherry-pick "mueve" el commit. Lo copia. El original sigue en su rama, tan vivo como antes. Si querías moverlo, tienes que borrarlo del origen con un rebase interactivo (drop), con las implicaciones de la regla de oro que eso conlleva.
Error 2: hacer cherry-pick de commits de una rama que después vas a fusionar. Es la fuente número uno de conflictos incomprensibles. Si la rama va a entrar entera, espera.
Error 3: olvidar -x al portar a mantenimiento. Dentro de seis meses, ese commit sin origen conocido en mantenimiento/1.x será un misterio. Cuesta dos caracteres.
Error 4: usar -x copiando de una rama local que vas a borrar. La referencia queda apuntando a un hash irresoluble. Ahí es mejor -e y una nota en lenguaje humano.
Error 5: hacer cherry-pick sin mirar el commit antes. git show <sha> cuesta tres segundos y te evita descubrir a mitad del conflicto que el commit tocaba seis ficheros y dependía de otros tres.
Error 6: no comprobar el rango. A..B excluye A. Si esperabas que se aplicaran cinco commits y se aplican cuatro, es esto. Comprueba siempre antes con git log --oneline A..B.
Error 7: confundir la dirección de git cherry. El primer argumento es el upstream (con lo que comparas, normalmente main) y el segundo la rama que examinas. Al revés te dará justo lo contrario de lo que esperas.
Consejo 1: haz commits pequeños y autocontenidos. No es un consejo sobre cherry-pick, es el consejo que hace posible el cherry-pick. Un commit que hace una sola cosa se trasplanta sin drama; uno que mezcla tres, no.
Consejo 2: verifica siempre después de portar. Que el parche se aplique sin conflicto no significa que funcione en la otra rama. Ejecuta las pruebas.
Consejo 3: usa git cherry -v antes de una campaña de portado. Te dirá exactamente qué queda por llevar y qué ya está, sin depender de tu memoria.
Consejo 4: para lotes grandes, git rebase --onto en lugar de muchos cherry-picks. Es la misma operación en el fondo, pero de una sola vez y con una lista clara de lo que se está reaplicando.
Consejo 5: si el cherry-pick se complica, aborta. git cherry-pick --abort deja el repositorio exactamente como estaba. Reconstruir el cambio a mano en la rama de destino es a veces más rápido y siempre más claro que pelear con un parche que no encaja.
Ejercicios
Ejercicio 1: portar una corrección a mantenimiento
Monta un repositorio con main y una rama mantenimiento/1.x que salga de un commit antiguo. Añade dos commits a main, uno de ellos una corrección pequeña. Después:
- Porta solo la corrección a
mantenimiento/1.xdejando constancia del origen. - Demuestra que el hash es distinto pero el diff es idéntico.
- Demuestra que el autor original se ha conservado.
Ejercicio 2: el duplicado y su detección
Provoca a propósito el problema del apartado 7:
- Crea una rama con tres commits.
- Haz cherry-pick del segundo a
main. - Usa
git cherry -vpara demostrar que Git sabe que ese cambio ya está enmain. - Usa
git log --cherry-mark --left-rightpara ver los dos commits equivalentes marcados con=. - Fusiona la rama en
mainy observa qué pasa con el historial.
Ejercicio 3: agrupar varios commits en uno
Con una rama que tenga cuatro commits pequeños, lleva los tres primeros a otra rama como un único commit con un mensaje propio, usando -n. Verifica con git show --stat que el commit resultante contiene los cambios de los tres.
Soluciones
Solución 1:
mkdir /tmp/practica-cherry && cd /tmp/practica-cherry
git init -b main
echo "v1" > app.js && git add . && git commit -m "Version inicial"
git switch -c mantenimiento/1.x
git switch main
printf 'v1\nfuncionalidad nueva\n' > app.js && git commit -am "Añadir funcionalidad de la version 2"
printf 'v1\nfuncionalidad nueva\ncorreccion\n' > app.js
git -c user.name="Ana Ferrer" -c user.email="[email protected]" commit -am "Corregir el foco tras borrar"
git log --oneline5c9e1f4 Corregir el foco tras borrar a72b8d3 Añadir funcionalidad de la version 2 1e4f7c9 Version inicial
(Conflictúa porque en mantenimiento/1.x falta la línea de la funcionalidad. Se resuelve dejando solo la corrección.)
# 2 y 3. Comparar
git log --oneline -1
git show --pretty='%h | %an | %ad' --date=short HEAD | head -4
git show --pretty='%h | %an | %ad' --date=short 5c9e1f4 | head -4Hash distinto, misma autoría y misma fecha de autoría. El mensaje del nuevo incluye además la línea (cherry picked from commit 5c9e1f4...).
Solución 2:
mkdir /tmp/practica-duplicados && cd /tmp/practica-duplicados
git init -b main
printf 'linea 1\n' > f.txt && git add . && git commit -m "Base"
git switch -c funcionalidad/algo
printf 'linea 1\nA\n' > f.txt && git commit -am "Commit A"
printf 'linea 1\nA\nB\n' > f.txt && git commit -am "Commit B (la correccion urgente)"
printf 'linea 1\nA\nB\nC\n' > f.txt && git commit -am "Commit C"
git log --onelineSolo si el diff resultante coincide; si tu resolución del conflicto cambió el parche, aparecerá con +. Es la limitación que comentamos.
< 7b3e9f1 Commit B (la correccion urgente) > c17b5f9 Commit A > 4d8e3b6 Commit B (la correccion urgente) > 9f2a7c1 Commit C
Verás el commit portado y el original conviviendo en el historial de main, diciendo lo mismo dos veces. Si el conflicto se resolvió de forma distinta, además habrá conflictuado al fusionar. Ese es exactamente el precio del cherry-pick prematuro.
Solución 3:
mkdir /tmp/practica-agrupar && cd /tmp/practica-agrupar
git init -b main
echo "base" > f.txt && git add . && git commit -m "Base"
git switch -c origen
echo "uno" > uno.txt && git add . && git commit -m "Uno"
echo "dos" > dos.txt && git add . && git commit -m "Dos"
echo "tres" > tres.txt && git add . && git commit -m "Tres"
echo "cuatro" > cuatro.txt && git add . && git commit -m "Cuatro"
git log --oneline origencommit 6e2d8b5...
Portar los tres primeros pasos como un único cambio
dos.txt | 1 +
tres.txt | 1 +
uno.txt | 1 +
3 files changed, 3 insertions(+)Fíjate en el rango: a27c9f3^..3b9d6a2 incluye Uno, Dos y Tres. Sin el ^ habrías portado solo Dos y Tres.
Conclusión
git cherry-pick es la herramienta de precisión del módulo. Lo esencial:
- Copia el cambio de un commit sobre tu rama actual creando un commit nuevo con otro hash. Conserva el mensaje, el autor y la fecha de autoría; tú pasas a ser el confirmador.
- Acepta commits sueltos y rangos, con la trampa habitual de que
A..BexcluyeAyA^..Bno. Los commits de fusión quedan fuera de los rangos. -xdeja constancia del origen y es imprescindible al portar a ramas de mantenimiento públicas;-npermite acumular varios commits y confirmarlos como uno;-eedita el mensaje y-sañade el sign-off.- Los conflictos se resuelven como siempre (lección 03-05) y se sale con
--continue,--skipo--abort. AquíoursytheirsNO están invertidos: la inversión era cosa del rebase. - Los casos legítimos son dos: llevar una corrección a una rama que nunca se fusionará con el origen (mantenimiento, versiones antiguas), y rescatar un commit de una rama que se va a abandonar.
- El precio del abuso son los duplicados: si copias un commit de una rama que después fusionas, el mismo cambio acaba dos veces en el historial y, en el peor caso, aplicado dos veces.
git cherry -vygit log --cherry-mark/--cherry-pickdetectan cambios equivalentes comparando el patch-id, y son la forma de saber qué queda realmente por portar.- Si las dos ramas van a juntarse, no copies: fusiona.
Lo que viene
Las tres lecciones anteriores han manipulado commits: reaplicándolos, reorganizándolos, copiándolos. Todas parten de la misma premisa: que el trabajo ya está confirmado.
Pero el día a día tiene un problema distinto y muy frecuente. Estás a mitad de algo, con el fichero medio escrito y nada confirmable, y llega una urgencia que hay que atender ahora. No quieres confirmar un wip (aunque sea corregible con lo aprendido en 05-02), no quieres perder lo hecho, y necesitas el directorio limpio para cambiar de rama.
Git tiene un cajón para eso, y lo llevamos prometiendo desde la lección 03-02: git stash. Lo abrimos en la lección 05-04: Guardando Cambios Temporales.
Dominando Git: De Principiante a Avanzado
Módulo 1: Introducción a Git
- ¿Qué es Git?
- Instalando Git
- Terminología Básica de Git
- El Modelo de Datos de Git
- Configurando Git
- Configuración Inicial
Módulo 2: Operaciones Básicas de Git
- Creando un Repositorio
- Clonando un Repositorio
- Flujo de Trabajo Básico de Git
- Preparando y Confirmando Cambios
- Inspeccionando Cambios con git diff
- Visualizando el Historial de Confirmaciones
Módulo 3: Ramas y Fusión
- Entendiendo las Ramas
- Creando y Cambiando Ramas
- Fusionando Ramas
- Estrategias de Fusión
- Resolviendo Conflictos de Fusión
- Gestión de Ramas
Módulo 4: Trabajando con Repositorios Remotos
- Entendiendo los Repositorios Remotos
- Agregando un Repositorio Remoto
- Autenticación con Repositorios Remotos
- Obteniendo y Extrayendo Cambios
- Enviando Cambios
- Rastreando Ramas
Módulo 5: Operaciones Avanzadas de Git
- Rebase
- Rebase Interactivo
- Cherry-Picking de Confirmaciones
- Guardando Cambios Temporales
- Etiquetando Confirmaciones
- Revirtiendo Confirmaciones
Módulo 6: Herramientas y Técnicas de Git
- Usando Git Hooks
- Git Bisect
- Git Blame
- Git Log y Alias
- Submódulos de Git
- Múltiples Copias de Trabajo con git worktree
Módulo 7: Estrategias de Colaboración y Flujo de Trabajo
- Forks y Pull Requests
- Revisiones de Código con Git
- Flujo de Trabajo Git Flow
- GitHub Flow
- Trunk Based Development
- Integración Continua con Git
Módulo 8: Mejores Prácticas y Consejos de Git
- Escribiendo Buenos Mensajes de Confirmación
- Manteniendo un Historial Limpio
- Ignorando Archivos con .gitignore
- Atributos de Fichero con .gitattributes
- Mejores Prácticas de Seguridad
- Consejos de Rendimiento
Módulo 9: Solución de Problemas y Depuración
- Problemas Comunes de Git
- Deshaciendo Cambios
- Resolviendo Divergencias con el Remoto
- Recuperando Confirmaciones Perdidas
- Tratando con Repositorios Corruptos
- Técnicas Avanzadas de Depuración
