2.1 Un No-Conflicto
Primero veamos como funciona git en una revisión normal, antes de entrar a
estudiar lo que sucede cuando hay conflictos al hacer una mezcla. Trabajemos con las
ramas del ejemplo 09 (antes de hacer el merge). Inmediatamente después de hacer
checkout de example9/branchA, miremos el status:
Listing 2.1:git status sobre un árbol limpio$ git status On branch example9/branchA nothing to commit, working tree clean
Como sabe git que no hay cambios en el árbol de trabajo? git compara el
árbol de trabajo con el index:
Listing 2.2:git ls-files en un árbol limpio$ git ls-files -s 100644 2f78cf5b66514f2506d9af5f3dadf3dee7aa6d9f 0 .gitignore 100755 ad957360597fb9bd3e83d4bfa869f6e19b7fbf2b 0 example.py 100644 475f980e6c6e24f8fc4a144e498fa1c1c59da370 0 module.py
git está listando los permisos, el ID del objeto, el index
stage y
el nombre del archivo de cada uno de los archivos en la revisión actual. git compara
los archivos en el árbol de trabajo y ve que nada ha cambiado.
Lo siguiente sería modificar example.py de alguna forma. Luego de
modificarlo y guardarlo, git se da cuenta de que el archivo ha cambiado porque
ya no se corresponde con lo lo que está en el index. La información del
index no va a cambiar hasta que agreguemos el archivo, por supuesto. Así
que agreguemos el archivo al index y veamos lo que git ls-files tiene para
nosotros:
Listing 2.3:git ls-files con un archivo modificado$ git add example.py $ git status On branch example9/branchA Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: example.py $ git ls-files -s 100644 2f78cf5b66514f2506d9af5f3dadf3dee7aa6d9f 0 .gitignore 100755 b30ade699b80860abd0ed6d84cff9df94e801d34 0 example.py 100644 475f980e6c6e24f8fc4a144e498fa1c1c59da370 0 module.py
Podemos ver que el id del objeto de example.py
cambió
pero aparte de eso no hay otras diferencias. Como puede saber git los ids de los
objetos que había en el index antes de agregarlos? git también tiene esa
información de HEAD:
Listing 2.4:git ls-tree sobre example9/branchA$ git ls-tree -r HEAD 100644 blob 2f78cf5b66514f2506d9af5f3dadf3dee7aa6d9f .gitignore 100755 blob ad957360597fb9bd3e83d4bfa869f6e19b7fbf2b example.py 100644 blob 475f980e6c6e24f8fc4a144e498fa1c1c59da370 module.py
Y podemos ver que los ids de los 3 archivos son los mismos que se tenía
originalmente en el index cuando hicimos checkout. Ahora que el id de
example.py cambió entre HEAD y lo que hay en el index, git sabe que hay
contenido nuevo asociado a example.py en el index que está listo para ser
acometido. Por eso nos muestra el archivo en Changes to be committed.
Modifiquemos el archivo una vez más sin agregarlo y veamos lo que
sucede:
Listing 2.5:Luego de modificar un archivo ya agregado$ git status On branch example9/branchA Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: example.py Changes not staged for commit: (use "git add <file>..." to update what will be committed) (use "git restore <file>..." to discard changes in working directory) modified: example.py $ git ls-tree -r HEAD 100644 blob 2f78cf5b66514f2506d9af5f3dadf3dee7aa6d9f .gitignore 100755 blob ad957360597fb9bd3e83d4bfa869f6e19b7fbf2b example.py 100644 blob 475f980e6c6e24f8fc4a144e498fa1c1c59da370 module.py $ git ls-files -s 100644 2f78cf5b66514f2506d9af5f3dadf3dee7aa6d9f 0 .gitignore 100755 b30ade699b80860abd0ed6d84cff9df94e801d34 0 example.py 100644 475f980e6c6e24f8fc4a144e498fa1c1c59da370 0 module.py
Esto es interesante. example.py se muestra en Changes to be committed
porque el id del archivo cambió entre HEAD e index. Pero también aparece en
Changes not staged for commit prque git se da cuenta de que el archivo en el
árbol de trabajo no conincide con el objeto en el index. Si lo agregamos de nuevo
y verificamos:
Listing 2.6:Luego de agregar el archivo de nuevo$ git add example.py $ git status On branch example9/branchA Changes to be committed: (use "git restore --staged <file>..." to unstage) modified: example.py $ git ls-tree -r HEAD 100644 blob 2f78cf5b66514f2506d9af5f3dadf3dee7aa6d9f .gitignore 100755 blob ad957360597fb9bd3e83d4bfa869f6e19b7fbf2b example.py 100644 blob 475f980e6c6e24f8fc4a144e498fa1c1c59da370 module.py $ git ls-files -s 100644 2f78cf5b66514f2506d9af5f3dadf3dee7aa6d9f 0 .gitignore 100755 1858db13464ae33329a90cacbe294e749ea9a1a5 0 example.py 100644 475f980e6c6e24f8fc4a144e498fa1c1c59da370 0 module.py
Fíjense como el id del objeto asociado a example.py en el index cambió (de
b30ade699b8.... a 1858db13464....). Los ids de los objetos son diferentes entre
index y HEAD y por eso el archivo parece en Changes to be committed. El
contenido del archivo ahora es igual al del index y por eso git sabe que no hay más
nada que reportar sobre el archivo. Si creáramos una revisión en este momento,
cual sería el resultado?
Listing 2.7:acometiendo$ git commit -m "Some test" [example9/branchA b2f9a40] Some test 1 file changed, 6 insertions(+) $ git status On branch example9/branchA nothing to commit, working tree clean $ git ls-tree -r HEAD 100644 blob 2f78cf5b66514f2506d9af5f3dadf3dee7aa6d9f .gitignore 100755 blob 1858db13464ae33329a90cacbe294e749ea9a1a5 example.py 100644 blob 475f980e6c6e24f8fc4a144e498fa1c1c59da370 module.py $ git ls-files -s 100644 2f78cf5b66514f2506d9af5f3dadf3dee7aa6d9f 0 .gitignore 100755 1858db13464ae33329a90cacbe294e749ea9a1a5 0 example.py 100644 475f980e6c6e24f8fc4a144e498fa1c1c59da370 0 module.py
Y ahora el id de example.py cambió en
HEAD a lo que
estaba en el index cuando creamos la revisión(1858db13464ae33329a90cacbe294e749ea9a1a5).
Ahora los ids de los archivos son los mismos entre HEAD e index y el archivo en el
árbol de trabajo coincide con lo que está en el index, así que git no tiene nada
que reportar al respecto en git status.
Hagamos un reset de la rama para jugar con conflictos:
Listing 2.8:Haciendo reset$ git reset --hard HEAD~ HEAD is now at dfde76c A little refactor (moving condition to another function)