Salta el contingut
 

Reset i Amend

Autor: Joan Puigcerver Ibáñez

Correu electrònic: j.puigcerveribanez@edu.gva.es

Llicència: CC BY-NC-SA 4.0

(Reconeixement - NoComercial - CompartirIgual) 🅭

Reset

L'ordre git reset ens permet moure la referència de la branca actual a qualsevol altre commit del repositori. Això significa que podem modificar la història del repositori local local, per ajustar o refer la història a les nostres necessitats.

Algunes de les accions que podem fer mitjançant aquestes eines són:

  • Desfer o modificar commits anteriors.
  • Reorganitzar els commits abans de publicar-los.
  • Moure punters de les branques.

Perill

Aquestes eines són molt potents, però cal tindre en compte que modificar la història del repositori pot ser perillós.

Especialment, en les branques que ja han segut publicades (push), ja que pot ocasionar problemes entre els col·laboradors del repositori.

Preparació repositori
setup_reset.sh
#!/bin/bash

# Elimina els repositoris si existeixen
if [ -d ~/git_reset ]; then
    rm -rf ~/git_reset
fi

mkdir -p ~/git_reset
cd ~/git_reset
git init
git branch -m main
echo "# Git reset i commit --amend" > README.md
git add README.md
git commit -m "Commit inicial"
echo "- Canvi A" >> README.md
git commit -a -m "Canvi A"
echo "- Canvi B" >> README.md
git commit -a -m "Canvi B"
echo "- Canvi C" >> README.md
git commit -a -m "Canvi C"
git lga
jpuigcerver@fp:~ $ mkdir -p ~/git_reset
jpuigcerver@fp:~ $ cd ~/git_reset
jpuigcerver@fp:~/git_reset $ git init
Initialized empty Git repository in ~/git_reset/.git/
jpuigcerver@fp:~/git_reset (main) $ git branch -m main
jpuigcerver@fp:~/git_reset (main) $ echo "# Git reset i commit --amend" > README.md
jpuigcerver@fp:~/git_reset (main) $ git add README.md
jpuigcerver@fp:~/git_reset (main) $ git commit -m "Commit inicial"
[main (root-commit) 16786db] Commit inicial
 1 file changed, 1 insertion(+)
 create mode 100644 README.md
jpuigcerver@fp:~/git_reset (main) $ echo "- Canvi A" >> README.md
jpuigcerver@fp:~/git_reset (main) $ git commit -a -m "Canvi A"
[main 4dc7c85] Canvi A
 1 file changed, 1 insertion(+)
jpuigcerver@fp:~/git_reset (main) $ echo "- Canvi B" >> README.md
jpuigcerver@fp:~/git_reset (main) $ git commit -a -m "Canvi B"
[main 04fafb7] Canvi B
 1 file changed, 1 insertion(+)
jpuigcerver@fp:~/git_reset (main) $ echo "- Canvi C" >> README.md
jpuigcerver@fp:~/git_reset (main) $ git commit -a -m "Canvi C"
[main 0c65882] Canvi C
 1 file changed, 1 insertion(+)
jpuigcerver@fp:~/git_reset (main) $ git lga
* 0c65882 - (0 seconds ago) Canvi C - Joan Puigcerver (HEAD -> main)
* 04fafb7 - (0 seconds ago) Canvi B - Joan Puigcerver
* 4dc7c85 - (0 seconds ago) Canvi A - Joan Puigcerver
* 16786db - (0 seconds ago) Commit inicial - Joan Puigcerver

La sintaxi de l'ordre git reset és:

git reset [--soft | --mixed | --hard | --keep] <ref>

  • ref: La referència pot ser l'identificador de un commit, una branca o una etiqueta.

Documentació

Documentació oficial de git reset.

El comportament de git reset depén del mode especificat. Per defecte, el mode és --mixed.

Resum de l'eina git reset

Figura 1. Resum de l'eina git reset.

Informació

Aquesta ordre mou la referència de la branca actual, on està situat el HEAD.

Soft

El mode reset --soft mou la referència de la branca actual al commit especificat, conservant els canvis perduts a l'Àrea de Preparació (Staging Area).

git reset --soft <ref>
Exemple: reset --soft

Establim la referencia de la branca main al commit Canvi B.

En aquest cas, es perdran els canvis del commit Canvi C, que es conservaran en l'Àrea de Preparació.

jpuigcerver@fp:~/git_reset (main) $ git reset --soft 04fafb7
jpuigcerver@fp:~/git_reset (main) $ git status
On branch main
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
    modified:   README.md

jpuigcerver@fp:~/git_reset (main) $ git lga
* 04fafb7 - (0 seconds ago) Canvi B - Joan Puigcerver (HEAD -> main)
* 4dc7c85 - (0 seconds ago) Canvi A - Joan Puigcerver
* 16786db - (0 seconds ago) Commit inicial - Joan Puigcerver

Creem de nou el commit Canvi C.

jpuigcerver@fp:~/git_reset (main) $ git commit -m "Canvi C"
[main 0c65882] Canvi C
 1 file changed, 1 insertion(+)
jpuigcerver@fp:~/git_reset (main) $ git lga
* 0c65882 - (0 seconds ago) Canvi C - Joan Puigcerver (HEAD -> main)
* 04fafb7 - (0 seconds ago) Canvi B - Joan Puigcerver
* 4dc7c85 - (0 seconds ago) Canvi A - Joan Puigcerver
* 16786db - (0 seconds ago) Commit inicial - Joan Puigcerver

Mixed

El mode reset --mixed mou la referència de la branca actual al commit especificat. Els canvis es conserven en el Directori de Treball.

Aquest es el comportament per defecte si no s'especifica cap altra opció.

git reset --mixed <ref>
Exemple: reset --mixed

Establim la referencia de la branca main al commit Canvi B.

En aquest cas, es perdran els canvis del commit Canvi C, que es conservaran en el Directori de Treball.

jpuigcerver@fp:~/git_reset (main) $ git reset --mixed 04fafb7
Unstaged changes after reset:
M   README.md
jpuigcerver@fp:~/git_reset (main) $ git status
On branch main
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:   README.md

no changes added to commit (use "git add" and/or "git commit -a")
jpuigcerver@fp:~/git_reset (main) $ git lga
* 04fafb7 - (0 seconds ago) Canvi B - Joan Puigcerver (HEAD -> main)
* 4dc7c85 - (0 seconds ago) Canvi A - Joan Puigcerver
* 16786db - (0 seconds ago) Commit inicial - Joan Puigcerver

Creem de nou el commit Canvi C.

jpuigcerver@fp:~/git_reset (main) $ git add README.md
jpuigcerver@fp:~/git_reset (main) $ git commit -m "Canvi C"
[main 0c65882] Canvi C
 1 file changed, 1 insertion(+)
jpuigcerver@fp:~/git_reset (main) $ git lga
* 0c65882 - (0 seconds ago) Canvi C - Joan Puigcerver (HEAD -> main)
* 04fafb7 - (0 seconds ago) Canvi B - Joan Puigcerver
* 4dc7c85 - (0 seconds ago) Canvi A - Joan Puigcerver
* 16786db - (0 seconds ago) Commit inicial - Joan Puigcerver

Hard

El mode reset --hard mou la referència de la branca actual al commit especificat. modificant l'estat del repositori i revertint-lo a la referència especificada.

Perill

Tots els canvis es descarten permanentment.

git reset --hard <ref>
Exemple: reset --hard

Establim la referencia de la branca main al commit Canvi B.

En aquest cas, es perdran els canvis del commit Canvi C, que no es conservaran enlloc i no es podran recuperar.

jpuigcerver@fp:~/git_reset (main) $ git reset --hard 04fafb7
HEAD is now at 04fafb7 Canvi B
jpuigcerver@fp:~/git_reset (main) $ git status
On branch main
nothing to commit, working tree clean
jpuigcerver@fp:~/git_reset (main) $ git lga
* 04fafb7 - (0 seconds ago) Canvi B - Joan Puigcerver (HEAD -> main)
* 4dc7c85 - (0 seconds ago) Canvi A - Joan Puigcerver
* 16786db - (0 seconds ago) Commit inicial - Joan Puigcerver

Keep

El mode reset --keep és molt similar al comportament per defecte.

En aquest cas, no permet realitzar el reset si això comporta que els canvis actuals del Directori de Treball siguen sobreescrits per els canvis de l'operació de reset.

git reset --keep <ref>
Exemple: reset --keep

Com que realitzar el reset comportaria sobreescriure els canvis del Directori de Treball, l'operació no es realitza.

jpuigcerver@fp:~/git_reset (main) $ echo "- Canvi C" >> README.md
jpuigcerver@fp:~/git_reset (main) $ git status
On branch main
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:   README.md

no changes added to commit (use "git add" and/or "git commit -a")
jpuigcerver@fp:~/git_reset (main) $ git reset --keep 4dc7c85
error: Entry 'README.md' not uptodate. Cannot merge.
fatal: Could not reset index file to revision '4dc7c85'.
jpuigcerver@fp:~/git_reset (main) $ git lga
* 04fafb7 - (0 seconds ago) Canvi B - Joan Puigcerver (HEAD -> main)
* 4dc7c85 - (0 seconds ago) Canvi A - Joan Puigcerver
* 16786db - (0 seconds ago) Commit inicial - Joan Puigcerver

Amend

L'opció git commit --amend permet realitzar canvis a l'últim commit realitzat.

Permet modificar el missatge de l'últim commit, afegir nous fitxers o afegir nous canvis els fitxers del repositori, inclòs els que han segut modificats en aquest últim commit.

El funcionament d'aquesta ordre consisteix en crear un nou commit amb els canvis de l'Àrea de Preparació i els canvis del commit anterior. A més, el nou commit substitueix l'anterior.

La sintaxi és:

git commit --amend [-m <missatge>]

  • -m <missatge>: Permet especificar un nou missatge per al commit.
Exemple: Amend

Hem modificat l'últim commit Canvi B, on hem afegit canvis a README.md i modificat el missatge del commit.

jpuigcerver@fp:~/git_reset (main) $ git lga
* 04fafb7 - (0 seconds ago) Canvi B - Joan Puigcerver (HEAD -> main)
* 4dc7c85 - (0 seconds ago) Canvi A - Joan Puigcerver
* 16786db - (0 seconds ago) Commit inicial - Joan Puigcerver
jpuigcerver@fp:~/git_reset (main) $ git status
On branch main
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:   README.md

no changes added to commit (use "git add" and/or "git commit -a")
jpuigcerver@fp:~/git_reset (main) $ git diff
diff --git a/README.md b/README.md
index dc7fc7d..d05d0d2 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,4 @@
 # Git reset i commit --amend
 - Canvi A
 - Canvi B
+- Canvi C
jpuigcerver@fp:~/git_reset (main) $ git add README.md
jpuigcerver@fp:~/git_reset (main) $ git commit --amend -m "Canvi B i C"
[main 3aedfd5] Canvi B i C
 Date: Sun Oct 20 20:21:37 2024 +0200
 1 file changed, 2 insertions(+)
jpuigcerver@fp:~/git_reset (main) $ git lga
* 3aedfd5 - (0 seconds ago) Canvi B i C - Joan Puigcerver (HEAD -> main)
* 4dc7c85 - (0 seconds ago) Canvi A - Joan Puigcerver
* 16786db - (0 seconds ago) Commit inicial - Joan Puigcerver

Bibliografia

Comentaris