Manipulación de Commits y Rebase en Git

  1. combinación de commits =========================

1-1. Descripción

Generalmente se utiliza git rebase -i <commit_inicial>, donde <commit_final> por defecto es el HEAD actual más reciente.

Rango: (commit_inicial, commit_final]

La combinación mediante rebase generalmente abre una interfaz vim para seleccionar commits y editar mensajes de commit.

git rebase -i <commit_inicial> <commit_final>

1-2. Parámetros de combinación

Comando Abreviatura Significado
pick p Mantener este commit
reword r Mantener este commit, pero modificar su mensaje
edit e Mantener este commit, pero detenerse para modificarlo (no solo el mensaje)
squash s Combinar este commit con el commit anterior
fixup f Combinar este commit con el anterior, pero sin conservar el mensaje
exec x Ejecutar comando de Shell
drop d Eliminar este commit

1-3. Generación de datos de prueba

git init
echo "contenido1" > archivo1.txt && git add . && git commit -m "crear archivo1.txt"
echo "contenido2" > archivo2.txt && git add . && git commit -m "crear archivo2.txt"
echo "contenido3" > archivo3.txt && git add . && git commit -m "crear archivo3.txt"
echo "contenido4" > archivo4.txt && git add . && git commit -m "crear archivo4.txt"
echo "contenido5" > archivo5.txt && git add . && git commit -m "crear archivo5.txt"
echo "contenido6" > archivo6.txt && git add . && git commit -m "crear archivo6.txt"
echo "contenido7" > archivo7.txt && git add . && git commit -m "crear archivo7.txt"

git log --oneline --graph

* a1b2c3d (HEAD -> master) crear archivo7.txt
* d4e5f6g crear archivo6.txt
* h7i8j9k crear archivo5.txt
* l0m1n2o crear archivo4.txt
* p3q4r5s crear archivo3.txt
* t6u7v8w crear archivo2.txt
* x9y0z1a crear archivo1.txt

1-4. Uso de squash para combinar

Nota: No se incluye p3q4r5s, se combinan l0m1n2o hasta a1b2c3d

1-4-1. Ejecutar combinación

git rebase -i p3q4r5s

1-4-2. Seleccionar commits

1-4-3. Editar mensaje de combinación

[detached HEAD m5n6o7p] crear archivo4 a archivo7
 Date: Mié Jul 5 14:01:35 2023 +0800
 4 files changed, 4 insertions(+)
 create mode 100644 archivo4.txt
 create mode 100644 archivo5.txt
 create mode 100644 archivo6.txt
 create mode 100644 archivo7.txt
Successfully rebased and updated refs/heads/master.

1-4-4. Verificar registro

git log --oneline --graph

* m5n6o7p (HEAD -> master) crear archivo4 a archivo7
* p3q4r5s crear archivo3.txt
* t6u7v8w crear archivo2.txt
* x9y0z1a crear archivo1.txt

1-5. Uso de fixup para combinar

fixup no abre el editor de mensajes

1-5-1. Ejecutar combinación

git rebase -i p3q4r5s

1-5-2. Seleccionar commits

Cambiar el mensaje original de archivo4.txt a archivo4,5,6,7 no tendrá efecto

Successfully rebased and updated refs/heads/master.

1-5-3. Verificar registro

git log --oneline --graph

* q8r9s0t (HEAD -> master) crear archivo4.txt
* p3q4r5s crear archivo3.txt
* t6u7v8w crear archivo2.txt
* x9y0z1a crear archivo1.txt

1-6. Combinación por rango

Nota: Al combinar por rango, se convierte en un HEAD separado

1-6-1. Ejecutar combinación

git rebase -i t6u7v8w h7i8j9k

1-6-2. Seleccionar commits

# Antes del cambio
pick p3q4r5s crear archivo3.txt
pick l0m1n2o crear archivo4.txt
pick h7i8j9k crear archivo5.txt

# Después del cambio
pick p3q4r5s crear archivo3.txt
s l0m1n2o crear archivo4.txt
s h7i8j9k crear archivo5.txt

1-6-3. Editar mensaje de combinación

# Antes del cambio
# This is a combination of 3 commits.
# This is the 1st commit message:
crear archivo3.txt
# This is the commit message #2:
crear archivo4.txt
# This is the commit message #3:
crear archivo5.txt

# Después del cambio
# This is a combination of 3 commits.
# This is the 1st commit message:

crear archivo3,4,5

[detached HEAD u1v2w3x] crear archivo3,4,5
 Date: Mié Jul 5 14:01:23 2023 +0800
 3 files changed, 3 insertions(+)
 create mode 100644 archivo3.txt
 create mode 100644 archivo4.txt
 create mode 100644 archivo5.txt
Successfully rebased and updated detached HEAD.

1-6-4. Verificar ramas

git branch

* (HEAD detached from refs/heads/master)
  master

1-6-5. Crear nueva rama

git switch -c desarrollo

Switched to a new branch 'desarrollo'

1-6-6. Verificar registro

git log --oneline --graph --all

* u1v2w3x (HEAD -> desarrollo) crear archivo3,4,5
| * a1b2c3d (master) crear archivo7.txt
| * d4e5f6g crear archivo6.txt
| * h7i8j9k crear archivo5.txt
| * l0m1n2o crear archivo4.txt
| * p3q4r5s crear archivo3.txt
|/
* t6u7v8w crear archivo2.txt
* x9y0z1a crear archivo1.txt

2. Rebase

2-1. Explicación del rebase

Al fusionar ramas, si la rama desarrollo no apunta al último HEAD de la rama master, fusionar las dos generará un commit (no-fast-forward).

Si se utiliza rebase para que la rama desarrollo apunte al último HEAD de master, entonces se convertirá en una fusión de avance rápido (fast-forward).

2-2. Rebase sin conflictos

2-2-1. Ver estado de ramas

git log --oneline --graph --all

* k2l3m4n (HEAD -> master) agregar archivo2.txt
| * o5p6q7r (desarrollo) agregar trabajo2.txt
| * s8t9u0v agregar trabajo1.txt
|/
* w1x2y3z agregar archivo1.txt

2-2-2. Cambiar a rama desarrollo

git switch desarrollo

2-2-3. Ejecutar rebase

git rebase master

Successfully rebased and updated refs/heads/desarrollo.

2-2-4. Verificar registro

git log --oneline --graph --all

* a4b5c6d (HEAD -> desarrollo) agregar trabajo2.txt
* e7f8g9h agregar trabajo1.txt
* k2l3m4n (master) agregar archivo2.txt
* w1x2y3z agregar archivo1.txt

2-3. Rebase con conflictos

2-3-1. Ver estado de ramas

git log --oneline --graph --all

* b8c9d0e (HEAD -> master) master modifica archivo1.txt
* k2l3m4n agregar archivo2.txt
| * f1g2h3i (desarrollo) desarrollo modifica archivo1.txt
| * o5p6q7r agregar trabajo2.txt
| * s8t9u0v agregar trabajo1.txt
|/
* w1x2y3z agregar archivo1.txt

2-3-2. Cambiar a rama desarrollo

git switch desarrollo

2-3-3. Error en rebase

git rebase --abort: cancelar rebase

git rebase --skip: saltar conflicto de rebase, el archivo conflictivo usará la versión de master

git rebase master

Auto-merging archivo1.txt
CONFLICT (content): Merge conflict in archivo1.txt
error: could not apply f1g2h3i... desarrollo modifica archivo1.txt
Resolve all conflicts manually, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commit: run "git rebase --skip".
To abort and get back to the state before "rebase", run "git rebase --abort".
Could not apply f1g2h3i... desarrollo modifica archivo1.txt

git status

interactive rebase in progress; onto b8c9d0e
Last commands done (3 commands done):
   pick o5p6q7r agregar trabajo2.txt
   pick f1g2h3i desarrollo modifica archivo1.txt
  (see more in file .git/rebase-merge/done)
No commands remaining.
You are currently rebasing branch 'desarrollo' on 'b8c9d0e'.
(fix conflicts and then run "git rebase --continue")
(use "git rebase --skip" to skip this patch)
(use "git rebase --abort" to check out the original branch)

Unmerged paths:
   (use "git restore --staged <file>..." to unstage)
   (use "git add <file>..." to mark resolution)
        both modified:   archivo1.txt

no changes added to commit

2-3-4. Resolver conflicto

contenido1
<<<<<< HEAD
master
=======
desarrollo
>>>>>> f1g2h3i (desarrollo modifica archivo1.txt)

contenido1
master
desarrollo

2-3-5. Continuar rebase

git add archivo1.txt
git rebase --continue

[detached HEAD j5k6l7m] desarrollo modifica archivo1.txt Nuevo
 1 file changed, 4 insertions(+)
Successfully rebased and updated refs/heads/desarrollo.

2-3-6. Verificar registro

git log --oneline --graph --all

* j5k6l7m (HEAD -> desarrollo) desarrollo modifica archivo1.txt Nuevo
* n8o9p0q agregar trabajo2.txt
* r1s2t3u agregar trabajo1.txt
* b8c9d0e (master) master modifica archivo1.txt
* k2l3m4n agregar archivo2.txt
* w1x2y3z agregar archivo1.txt

2-4. Saltar conflictos editados

Nota: Si se salta un archivo conflictivo, se descartarán las modificaciones de la rama actual en ese archivo.

2-4-1. Ver estado de ramas

git log --oneline --graph --all

* v4w5x6y (HEAD -> desarrollo) agregar trabajo3.txt
* f1g2h3i desarrollo modifica archivo1.txt
* o5p6q7r agregar trabajo2.txt
* s8t9u0v agregar trabajo1.txt
| * b8c9d0e (master) master modifica archivo1.txt
| * k2l3m4n agregar archivo2.txt
|/
* w1x2y3z agregar archivo1.txt

2-4-2. Error en rebase

git rebase master

Auto-merging archivo1.txt
CONFLICT (content): Merge conflict in archivo1.txt
error: could not apply f1g2h3i... desarrollo modifica archivo1.txt
Resolve all conflicts manual, mark them as resolved with
"git add/rm <conflicted_files>", then run "git rebase --continue".
You can instead skip this commmit: run "git rebase --skip".
To abort and get back to the state before "git rebase", run "git rebase --abort".
Could not apply f1g2h3i... desarrollo modifica archivo1.txt

cat archivo1.txt

contenido1
<<<<<< HEAD
master
=======
desarrollo
>>>>>> f1g2h3i (desarrollo modifica archivo1.txt)

2-4-3. Saltar conflicto

git rebase --skip

Successfully rebased and updated refs/heads/desarrollo.

2-4-4. Verificar archivo

cat archivo1.txt

contenido1
master

2-4-5. Verificar registro

git log --oneline --graph --all

* z7a8b9c (HEAD -> desarrollo) agregar trabajo3.txt
* d0e1f2g agregar trabajo2.txt
* h3i4j5k agregar trabajo1.txt
* b8c9d0e (master) master modifica archivo1.txt
* k2l3m4n agregar archivo2.txt
* w1x2y3z agregar archivo1.txt

2-5. Deshacer rebase

2-5-1. Ver reflog

git reflog

j5k6l7m (HEAD -> desarrollo) HEAD@{0}: rebase (continue) (finish): returning to refs/heads/desarrollo
j5k6l7m (HEAD -> desarrollo) HEAD@{1}: rebase (continue): desarrollo modifica archivo1.txt Nuevo
n8o9p0q HEAD@{2}: rebase (pick): agregar trabajo2.txt
r1s2t3u HEAD@{3}: rebase (pick): agregar trabajo1.txt
b8c9d0e (master) HEAD@{4}: rebase (start): checkout master
f1g2h3i HEAD@{5}: checkout: moving from master to desarrollo
b8c9d0e (master) HEAD@{6}: commit: master modifica archivo1.txt
k2l3m4n HEAD@{7}: checkout: moving from desarrollo to master
f1g2h3i HEAD@{8}: commit: desarrollo modifica archivo1.txt
o5p6q7r HEAD@{9}: checkout: moving from master to desarrollo
k2l3m4n HEAD@{10}: commit: agregar archivo2.txt
w1x2y3z HEAD@{11}: checkout: moving from desarrollo to master
o5p6q7r HEAD@{12}: commit: agregar trabajo2.txt
s8t9u0v HEAD@{13}: commit: agregar trabajo1.txt
w1x2y3z HEAD@{14}: checkout: moving from master to desarrollo
w1x2y3z HEAD@{15}: commit (initial): agregar archivo1.txt

2-5-2. Deshacer

Restablecer al commit anterior a rebase (start)

git reset --hard f1g2h3i

HEAD is now at f1g2h3i desarrollo modifica archivo1.txt

2-5-3. Verificar registro

git log --oneline --graph --all

* b8c9d0e (master) master modifica archivo1.txt
* k2l3m4n agregar archivo2.txt
| * f1g2h3i (HEAD -> desarrollo) desarrollo modifica archivo1.txt
| * o5p6q7r agregar trabajo2.txt
| * s8t9u0v agregar trabajo1.txt
|/
* w1x2y3z agregar archivo1.txt

Etiquetas: Git rebase git-commands version-control squash

Publicado el 7-21 12:17