<div class="page"> <div class="cover text-center"> <img class="mx-auto" src=/itb/images/logo_mislata.png alt="logo"> # Reset i Amend <div class="text-end fit-content ms-auto my-3 mt-auto pt-3"> <p><strong>Autor:</strong> Joan Puigcerver Ibáñez</p> <p><strong>Correu electrònic:</strong> j.puigcerveribanez@edu.gva.es</p> <p><strong>Curs:</strong> 2024/2025</p> </div> <div> <p class="fw-bold mb-0">Llicència: BY-NC-SA</p> <p class="d-none d-md-block">(Reconeixement - No Comercial - Compartir Igual)</p> <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.ca" target="_blank"> <img class="mx-auto" src="/itb/images/license.png" alt="Licence"/> </a> </div><!--license--> </div><!--cover--> </div><!--page--> {:toc} ## Introducció Les eines `git reset` i `git commit --amend` ens permeten modificar la història del repositori 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. Aquestes eines són molt potents, però cal tindre en compte que modificar la història del repositori, especialment si ja s'han publicat els canvis (`push`), s'ha de fer en precaució, ja que pot ocasionar problemes entre els col·laboradors del repositori. ## Repositori d'exemple ::: tip Podeu copiar i pegar les ordres següents a __Git Bash__ per inicialitzar un repositori amb l'estructura dels exemples. ::: Tots els exemples es realitzaran a partir d'un repositori amb la següent estructura: ```bash mkdir ~/git_reset cd ~/git_reset git init echo "# Git reset" >> README.md git add README.md git commit -m "Added README.md" echo "- Primer canvi" >> README.md git commit -a -m "Primer canvi" echo "- Segon canvi" >> README.md git commit -a -m "Segon canvi" echo "- Tercer canvi" >> README.md git commit -a -m "Tercer canvi" ``` ```shell jpuigcerver@FP:~/git_reset (main) $ git lga * 90a3d19 - (2 seconds ago) Tercer canvi - Joan Puigcerver (HEAD -> main) * 707c110 - (30 seconds ago) Segon canvi - Joan Puigcerver * 5266ed4 - (47 seconds ago) Primer canvi - Joan Puigcerver * 8790081 - (72 seconds ago) Added README.md - Joan Puigcerver jpuigcerver@FP:~/git_reset (main) $ git status On branch main nothing to commit, working tree clean jpuigcerver@FP:~/git_reset (main) $ cat README.md # Git reset - Primer canvi - Segon canvi - Tercer canvi ``` ## Reset L'eina `git reset` s'utilitza per modificar l'estat actual del repositori a un _commit_ en concret. ::: info Aquesta opció mou la referència de la branca actual, on està situat el `HEAD`. ::: ::: docs Documentació oficial de Git Reset: https://git-scm.com/docs/git-reset ::: El seu comportament depén de les opcions especificades. #3.1[Resum de l'eina Git Reset](/itb/DAM-ED/UD4/img/git_reset_resum.jpg) ### Soft (`--soft`) L'opció `--soft` modifica l'estat del repositori a la referència especificada i conserva els canvis realitzats en el _Directori de Treball_ i a l'_Àrea de Preparació (Staging Area)_. ``` git reset --soft <ref> ``` - `ref`: La referència pot ser l'identificador de un commit, una branca o una etiqueta. ::: example Realitzem un `git reset --soft` per esborrar l'últim commit __Tercer canvi__: ```shell jpuigcerver@FP:~/git_reset (main) $ git lga * 90a3d19 - (5 minutes ago) Tercer canvi - Joan Puigcerver (HEAD -> main) * 707c110 - (5 minutes ago) Segon canvi - Joan Puigcerver * 5266ed4 - (5 minutes ago) Primer canvi - Joan Puigcerver * 8790081 - (5 minutes ago) Added README.md - Joan Puigcerver jpuigcerver@FP:~/git_reset (main) $ git reset --soft 707c110 jpuigcerver@FP:~/git_reset (main) $ git lga * 707c110 - (5 minutes ago) Segon canvi - Joan Puigcerver (HEAD -> main) * 5266ed4 - (5 minutes ago) Primer canvi - Joan Puigcerver * 8790081 - (5 minutes ago) Added README.md - Joan Puigcerver jpuigcerver@FP:~/git_reset (main) $ git status On branch main Changes to be committed: (use "git restore --staged <file>..." to unstage) .green{modified: README.md} jpuigcerver@FP:~/git_reset (main) $ git diff --staged diff --git a/README.md b/README.md index db1ee0e..510c85b 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ # Git reset - Primer canvi - Segon canvi +- Tercer canvi jpuigcerver@FP:~/git_reset (main) $ cat README.md # Git reset - Primer canvi - Segon canvi - Tercer canvi ``` Els canvis encara existeixen en el _Directori de Treball_ i en l'_Àrea de Preparació_. Es pot tornar a crear el commit si es dessitja directament. ```shell jpuigcerver@FP:~/git_reset (main) $ git commit -m "Tercer canvi" [main 2b8827e] Tercer canvi 1 file changed, 1 insertion(+) jpuigcerver@FP:~/git_reset (main) $ git lga * 2b8827e - (2 seconds ago) Tercer canvi - Joan Puigcerver (HEAD -> main) * 707c110 - (5 minutes ago) Segon canvi - Joan Puigcerver * 5266ed4 - (5 minutes ago) Primer canvi - Joan Puigcerver * 8790081 - (5 minutes ago) Added README.md - Joan Puigcerver ``` ::: ### Mixed (`--mixed`) L'opció `--mixed` modifica l'estat del repositori a la referència especificada. Els canvis es conserven en el _Directori de Treball_, però no a l'_Àrea de Preparació (Staging Area)_. Aquest es el comportament per defecte si no s'especifica cap altra opció. ``` git reset [--mixed] <ref> ``` - L'opció `--mixed` és opcional, ja que és el comportament per defecte. ::: example Realitzem un `git reset --mixed` per esborrar l'últim commit __Tercer canvi__: ```shell jpuigcerver@FP:~/git_reset (main) $ git lga * 90a3d19 - (5 minutes ago) Tercer canvi - Joan Puigcerver (HEAD -> main) * 707c110 - (5 minutes ago) Segon canvi - Joan Puigcerver * 5266ed4 - (5 minutes ago) Primer canvi - Joan Puigcerver * 8790081 - (5 minutes ago) Added README.md - Joan Puigcerver jpuigcerver@FP:~/git_reset (main) $ git reset --mixed 707c110 Unstaged changes after reset: M README.md jpuigcerver@FP:~/git_reset (main) $ git lga * 707c110 - (5 minutes ago) Segon canvi - Joan Puigcerver (HEAD -> main) * 5266ed4 - (5 minutes ago) Primer canvi - Joan Puigcerver * 8790081 - (5 minutes ago) Added README.md - 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) .red{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 db1ee0e..510c85b 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ # Git reset - Primer canvi - Segon canvi +- Tercer canvi jpuigcerver@FP:~/git_reset (main) $ cat README.md # Git reset - Primer canvi - Segon canvi - Tercer canvi ``` Els canvis encara existeixen en el _Directori de Treball_. Es pot tornar a crear el commit si es dessitja, però primer cal afegir els canvis a l'_Àrea de Preparació_. ```shell jpuigcerver@FP:~/git_reset (main) $ git add README.md jpuigcerver@FP:~/git_reset (main) $ git commit -m "Tercer canvi" [main 2b8827e] Tercer canvi 1 file changed, 1 insertion(+) jpuigcerver@FP:~/git_reset (main) $ git lga * 2b8827e - (2 seconds ago) Tercer canvi - Joan Puigcerver (HEAD -> main) * 707c110 - (5 minutes ago) Segon canvi - Joan Puigcerver * 5266ed4 - (5 minutes ago) Primer canvi - Joan Puigcerver * 8790081 - (5 minutes ago) Added README.md - Joan Puigcerver ``` ::: ### Hard (`--hard`) L'opció `--hard` modifica l'estat del repositori i l'_Àrea de Preparació_, revertint el repositori a la referència especificada. Els canvis no es conservern en el _Directori de Treball_ ni en l'_Àrea de Preparació_. ``` git reset --hard <ref> ``` ::: danger Compte! Tots els canvis es descarten permanentment. ::: ::: example Realitzem un `git reset --hard` per esborrar l'últim commit __Tercer canvi__: ```shell jpuigcerver@FP:~/git_reset (main) $ git lga * 90a3d19 - (5 minutes ago) Tercer canvi - Joan Puigcerver (HEAD -> main) * 707c110 - (5 minutes ago) Segon canvi - Joan Puigcerver * 5266ed4 - (5 minutes ago) Primer canvi - Joan Puigcerver * 8790081 - (5 minutes ago) Added README.md - Joan Puigcerver jpuigcerver@FP:~/git_reset (main) $ git reset --hard 707c110 HEAD is now at 707c110 Segon canvi jpuigcerver@FP:~/git_reset (main) $ git lga * 707c110 - (5 minutes ago) Segon canvi - Joan Puigcerver (HEAD -> main) * 5266ed4 - (5 minutes ago) Primer canvi - Joan Puigcerver * 8790081 - (5 minutes ago) Added README.md - Joan Puigcerver jpuigcerver@FP:~/git_reset (main) $ git status On branch main nothing to commit, working tree clean jpuigcerver@FP:~/git_reset (main) $ cat README.md # Git reset - Primer canvi - Segon canvi ``` Els canvis s'han descartat i no es poden recuperar. ::: ### Keep (`--keep`) L'opció `--keep` és molt similar al comportament per defecte. En aquest cas, no permet realitzar el `reset` si això comporta serien sobrescrits els canvis actuals del _Directori de Treball_ que no han segut confirmats (`commit`). ``` git reset --keep <ref> ``` ::: example Realitzem un `git reset --keep` per esborrar l'últim commit __Tercer canvi__, però s'ha fet un canvi al fitxer README.md abans: ```shell jpuigcerver@FP:~/git_reset (main) $ git lga * 90a3d19 - (5 minutes ago) Tercer canvi - Joan Puigcerver (HEAD -> main) * 707c110 - (5 minutes ago) Segon canvi - Joan Puigcerver * 5266ed4 - (5 minutes ago) Primer canvi - Joan Puigcerver * 8790081 - (5 minutes ago) Added README.md - Joan Puigcerver jpuigcerver@FP:~/git_reset (main) $ echo "- Quart canvi" >> 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) .red{modified: README.md} no changes added to commit (use "git add" and/or "git commit -a") jpuigcerver@FP:~/git_reset (main) $ git reset --keep 707c110 error: Entry 'README.md' not uptodate. Cannot merge. fatal: Could not reset index file to revision '707c110'. ``` Realitzar el reset suposaria pedre els canvis realitzats, per tant el reset no es porta a terme. ::: ## Amend L'opció `git commit --amend` permet realitzar canvis a l'últim commit realitzat. Això et 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. La sintaxi és: ```bash git commit --amend ``` Si no s'especifica cap missatge, s'obrirà l'editor de text definit (configurat amb `core.editor`) amb el missatge anterior. :::: example Realitzem el commit __Quart canvi__ amb canvis: ```shell jpuigcerver@FP:~/git_reset (main) $ git lga * 90a3d19 - (5 minutes ago) Tercer canvi - Joan Puigcerver (HEAD -> main) * 707c110 - (5 minutes ago) Segon canvi - Joan Puigcerver * 5266ed4 - (5 minutes ago) Primer canvi - Joan Puigcerver * 8790081 - (5 minutes ago) Added README.md - Joan Puigcerver jpuigcerver@FP:~/git_reset (main) $ echo "- Quart" >> README.md jpuigcerver@FP:~/git_reset (main) $ git commit -a -m "Quart" [main 04e87d6] Quart 1 file changed, 1 insertion(+) jpuigcerver@FP:~/git_reset (main) $ git lga * 04e87d6 - (1 second ago) Quart - Joan Puigcerver (HEAD -> main) * 90a3d19 - (5 minutes ago) Tercer canvi - Joan Puigcerver * 707c110 - (5 minutes ago) Segon canvi - Joan Puigcerver * 5266ed4 - (5 minutes ago) Primer canvi - Joan Puigcerver * 8790081 - (5 minutes ago) Added README.md - Joan Puigcerver ``` Volem modificar el fitxer perquè els canvis siguen consistents i afegir la paraula "canvi". Modifiquem el commit: ```shell jpuigcerver@FP:~/git_reset (main) $ nano README.md jpuigcerver@FP:~/git_reset (main) $ git diff diff --git a/README.md b/README.md index 137a821..a44c9ce 100644 --- a/README.md +++ b/README.md @@ -2,4 +2,4 @@ - Primer canvi - Segon canvi - Tercer canvi -- Quart +- Quart canvi jpuigcerver@FP:~/git_reset (main) $ git commit -a --amend -m "Quart canvi" [main 163e5cf] Quart canvi Date: Mon Dec 11 16:16:24 2023 +0100 1 file changed, 1 insertion(+) jpuigcerver@FP:~/git_reset (main) $ git lga * 163e6cf - (1 second ago) Quart canvi - Joan Puigcerver (HEAD -> main) * 90a3d19 - (5 minutes ago) Tercer canvi - Joan Puigcerver * 707c110 - (5 minutes ago) Segon canvi - Joan Puigcerver * 5266ed4 - (5 minutes ago) Primer canvi - Joan Puigcerver * 8790081 - (5 minutes ago) Added README.md - Joan Puigcerver ``` ::: note Fixeu-vos amb que el _hash_ del _commit_ ha canvit. Això es deu a que Git ha creat un nou _commit_ i, per tant, la història ha segut modificada. ::: :::: ## Bibliografia - https://stackoverflow.com/questions/3528245/whats-the-difference-between-git-reset-mixed-soft-and-hard - https://git-scm.com/docs/git-reset