<div class="page">
<div class="cover text-center">
<img class="mx-auto" src=/itb/images/logo_mislata.png alt="logo">
# Branques en Git
<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ó
Una de les característiques més importants de Git és treballar en __branques__, que permet
el desenvolupament col·laboratiu i en paral·lel d'un projecte.
Moltes de les estratègies de Git per desenvolupar projectes es basen a realitzar
els canvis en branques independents que, una vegada acabades, s'integren en la __branca principal__.
La __branca principal__ d'un projecte s'anomena originalment `master`, però últimament és preferible
utilitzar la nomenclatura `main` per evitar la nomenclatura __master/slave__ que té connotacions
racistes.
Si ens fixem en el repositori que hem utilitzat en els materials anteriors, observem que hem
estat treballant sobre la branca `main`.
```shell
joapuiib@FP:~/git_tutorial (main) $ git status
On branch main
Your branch is up to date with 'origin/main'.
nothing to commit, working tree clean
joapuiib@FP:~/git_tutorial (main) $ git lga
* bdbfcb2 - (1 day ago) Modificació de Pau - Pau (HEAD -> main, origin/main, origin/HEAD)
* c9fc6c8 - (2 day ago) Changed README.md - .Joan Puigcerver
* 8e70293 - (5 days ago) Added Readme.md - Joan Puigcerver
```
Les branques existeixen tant en el _Repositori Local_ com en el _Repositori Remot_.
Les branques del _Repositori Remot_ s'identifiquen amb el prefix del `remote` configurat,
normalment `origin`.
En la història anterior es pot observar la branca local `main` i la branca remota `origin/main`.
## Branques en Git
Podeu imaginar les branques d'un repositori com uns punters,
que apunten a un _commit_ del repositori.
#2.1[Estat inicial del repositori](/itb/DAM-ED/UD2/img/git_material/03_branches/branques_inicial.png)
::: example
En la història anterior:
- La branca `main` apunta al _commit_ `bdbfcb2`.
- La branca `origin/main` també apunta al _commit_ `bdbfcb2`.
:::
Quan es crea una branca, l'únic que es fa és crear un nou punter
on estem situats en eixe instant.
Per crear una nova branca, executem l'ordre:
```bash
git branch <branch_name>
```
#2.2[Estat del repositori després de crear la branca 'docs'](/itb/DAM-ED/UD2/img/git_material/03_branches/create_docs.png)
Creem la branca `docs`, en la qual afegirem documentació en el fitxer __README.md__.
```shell
joapuiib@FP:~/git_tutorial (main) $ git branch docs
joapuiib@FP:~/git_tutorial (main) $ git lga
* bdbfcb2 - (1 day ago) Modificació de Pau - Pau (HEAD -> main, origin/main, origin/HEAD, docs)
* c9fc6c8 - (2 day ago) Changed README.md - Joan Puigcerver
* 8e70293 - (5 days ago) Added Readme.md - Joan Puigcerver
```
Vegem que s'ha creat el punter `docs` en l'últim _commit_.
No obstant això, el fet de crear una nova branca no et situa directament en
ella. De fet, l'estat actual del _Repositori Local_ i del _Directori de Treball_
s'indica mitjançant un altre punter, anomenat `HEAD`.
Podeu observar en la història que ara mateix, el `HEAD` apunta a la branca `main`.
També es pot observar en el prompt de la terminal.
Per situar-nos en la branca creada hem d'utilitzar l'ordre `checkout` o `switch`.
```bash
git checkout <reference>
git switch <reference>
```
De manera molt simplificada, el propòsit de l'ordre `checkout` i `switch` és moure
el `HEAD` a la referència especificada.
::: info
L'ordre `checkout` té altres funcions i per evitar confusions,
es va crear l'ordre `switch`:
- https://stackoverflow.com/questions/57265785/whats-the-difference-between-git-switch-and-git-checkout-branch
:::
#2.3[Estat del repositori després de situar-se en la branca 'docs'](/itb/DAM-ED/UD2/img/git_material/03_branches/checkout_docs.png)
```shell
joapuiib@FP:~/git_tutorial (main) $ git lga
* bdbfcb2 - (1 day ago) Modificació de Pau - Pau (HEAD -> main, origin/main, origin/HEAD, docs)
* c9fc6c8 - (2 day ago) Changed README.md - Joan Puigcerver
* 8e70293 - (5 days ago) Added Readme.md - Joan Puigcerver
Switched to branch 'docs'
joapuiib@FP:~/git_tutorial (main) $ git checkout docs
joapuiib@FP:~/git_tutorial (docs) $ git lga
* bdbfcb2 - (1 day ago) Modificació de Pau - Pau (HEAD -> docs, main, origin/main, origin/HEAD)
* c9fc6c8 - (2 day ago) Changed README.md - Joan Puigcerver
* 8e70293 - (5 days ago) Added Readme.md - Joan Puigcerver
```
De moment, la branca `main` i la branca `docs` apunten al mateix
_commit_ i per tant, l'estat del repositori és el mateix en les
dues branques.
Però, quan es realitza un _commit_ sols s'efectuen els canvis
en la branca en la qual estems situats (on està el `HEAD`).
#2.4[Estat del repositori després de fer un commit des de la branca 'docs'](/itb/DAM-ED/UD2/img/git_material/03_branches/commit_docs.png)
Anem a fer un canvi en el fitxer __README.md__ des de la branca
`docs`.
```shell
joapuiib@FP:~/git_tutorial (docs) $ git checkout docs
Already on 'docs'
joapuiib@FP:~/git_tutorial (docs) $ cat README.md
# Tutorial de Git
Estem aprenent a utilitzar Git!
Hem modificat un fitxer existent.
joapuiib@FP:~/git_tutorial (docs) $ echo >> README.md
joapuiib@FP:~/git_tutorial (docs) $ echo "## Documentació" >> README.md
joapuiib@FP:~/git_tutorial (docs) $ echo "- https://git-scm.com/docs" >> README.md
joapuiib@FP:~/git_tutorial (docs) $ cat README.md
# Tutorial de Git
Estem aprenent a utilitzar Git!
Hem modificat un fitxer existent.
## Documentació
- https://git-scm.com/docs
joapuiib@FP:~/git_tutorial (docs) $ git status
On branch docs
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: .red{README.md}
joapuiib@FP:~/git_tutorial (docs) $ git add README.md
joapuiib@FP:~/git_tutorial (docs) $ git commit -m "Added docs"
[docs ced9cee] Added docs
1 file changed, 3 insertions(+)
joapuiib@FP:~/git_tutorial (docs) $ git lga
* ced9cee - (0 seconds ago) Added docs - Joan Puigcerver (HEAD -> docs)
* bdbfcb2 - (1 day ago) Modificació de Pau - Pau (main, origin/main, origin/HEAD)
* c9fc6c8 - (2 day ago) Changed README.md - Joan Puigcerver
* 8e70293 - (5 days ago) Added Readme.md - Joan Puigcerver
```
Podeu observar com s'ha creat un nou _commit_ i la referència `HEAD -> docs` ha avançat.
En canvi, la referència `main` s'ha quedat en el _commit_ anterior i, per tant,
no conté els canvis que acabem de realitzar.
```shell
joapuiib@FP:~/git_tutorial (docs) $ git checkout docs
Already on 'docs'
joapuiib@FP:~/git_tutorial (docs) $ cat README.md
# Tutorial de Git
Estem aprenent a utilitzar Git!
Hem modificat un fitxer existent.
## Documentació
- https://git-scm.com/docs
joapuiib@FP:~/git_tutorial (docs) $ git checkout main
Switched to branch 'main'
joapuiib@FP:~/git_tutorial (main) $ cat README.md
# Tutorial de Git
Estem aprenent a utilitzar Git!
Hem modificat un fitxer existent.
```
## Sincronitzant branques amb el Repositori Remot
En el [Material: Repositori Remot](/itb/DAM-ED/UD2/materials/02_git_remote.html) vam estudiar
com sincronitzar el _Repositori Remot_ i el _Repositori Local_, amb ordres com `push`, `pull` i `fetch`.
En eixe moment, sols estàvem treballant amb la branca principal `main`. Anem a veure com podem sincronitzar
altres branques entre els dos repositoris.
El més important que cal tindre en compte és que les operacions `push`, `pull` i `fetch` sincronitzen els canvis
de la branca actual (`HEAD`).
#3.1[Estat del repositori després de publicar els canvis de la branca 'docs' al repositori remot](/itb/DAM-ED/UD2/img/git_material/03_branches/push_setupstream_docs.png)
Les branques es creen en el _Repositori Local_. Si consulteu
el _Repositori Remot_, observareu que la branca `docs` no existeix.
Si volem publicar aquesta branca en el _Repositori Remot_, haurem de realitzar un `push`.
La primera vegada que executeu la comanda fallarà, ja que Git no sap a quina branca del _Repositori Remot_ s'han de publicar els canvis i,
per tant, el que haurem de fer és configurar la __branca upstream__ mitjançant l'opció `--set-upstream` (de la mateixa manera que vam fer amb la branca `main`):
```shell
joapuiib@FP:~/git_tutorial (docs) $ git checkout docs
Already on 'docs'
joapuiib@coltrane:~/git_tutorial (docs) $ git push
fatal: The current branch docs has no upstream branch.
To push the current branch and set the remote as upstream, use
git push --set-upstream origin docs
joapuiib@coltrane:~/git_tutorial (docs) $ git push --set-upstream origin docs
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 12 threads
Compressing objects: 100% (3/3), done.
Writing objects: 100% (3/3), 391 bytes | 391.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
remote:
remote: Create a pull request for 'docs' on GitHub by visiting:
remote: https://github.com/joapuiib/git_tutorial/pull/new/docs
remote:
To github.com:joapuiib/git_tutorial.git
* [new branch] docs -> docs
joapuiib@FP:~/git_tutorial (docs) $ git lga
* ced9cee - (1 hour ago) Added docs - Joan Puigcerver (HEAD -> docs, origin/docs)
* bdbfcb2 - (1 day ago) Modificació de Pau - Pau (main, origin/main, origin/HEAD)
* c9fc6c8 - (2 day ago) Changed README.md - Joan Puigcerver
* 8e70293 - (5 days ago) Added Readme.md - Joan Puigcerver
```
Podeu observar que s'ha creat la branca `origin/docs` i que el _Repositori Remot_ conté aquesta branca.
Podeu sincronitzar els canvis d'aquesta branca mitjançant `push`, `pull` i `fetch`, de la mateixa manera que vam
fer amb `main`.
## Fusió de branques (merge)
Les branques permeten realitzar canvis en el repositori d'una manera independent,
però en algun moment, aquests canvis s'hauran d'integrar.
S'ha creat la branca `docs`, en la qual s'ha afegit documentació al fitxer README.md, però
aquests canvis encara no s'han incorporat a la branca `main`.
```shell
joapuiib@FP:~/git_tutorial (docs) $ git lga
* ced9cee - (1 hour ago) Added docs - Joan Puigcerver (HEAD -> docs, origin/docs)
* bdbfcb2 - (1 day ago) Modificació de Pau - Pau (main, origin/main, origin/HEAD)
* c9fc6c8 - (2 day ago) Changed README.md - Joan Puigcerver
* 8e70293 - (5 days ago) Added Readme.md - Joan Puigcerver
```
Una manera d'incorporar els canvis és mitjançant la fusió (`merge`) de dues branques.
::: info "Important"
Cal tindre en compte que sempre s'incorporen els canvis d'una branca particular
en la branca actual (`HEAD`).
:::
### Fusió directa o Fast-forward
El primer pas per realitzar un `merge` és situar-nos en la branca on volem incorporar els canvis, en aquest cas,
a la branca `main`. Després, ja podem fusionar els canvis mitjançant l'ordre `git merge`:
```bash
git merge <branch name>
```
```shell
joapuiib@FP:~/git_tutorial (docs) $ git checkout main
Switched to branch 'main'
joapuiib@FP:~/git_tutorial (main) $ git merge docs
Updating bdbfcb2..ced9cee
Fast-forward
README.md | 3 .green{+++}
1 file changed, 3 insertions(+)
joapuiib@FP:~/git_tutorial (main) $ git lga
* ced9cee - (1 hour ago) Added docs - Joan Puigcerver (HEAD -> main, docs, origin/docs)
* bdbfcb2 - (1 day ago) Modificació de Pau - Pau (origin/main, origin/HEAD)
* c9fc6c8 - (2 day ago) Changed README.md - Joan Puigcerver
* 8e70293 - (5 days ago) Added Readme.md - Joan Puigcerver
```
Podeu observar que el missatge de l'ordre `merge` indica que s'ha realitzat de manera directa (_Fast-forward_).
Una fusió directa o _fast-forward_ ocorre quan el punter de la branca on es volen incorporar els canvis
directament es pot avançar a l'estat de la branca on estan els nous canvis.
::: example
En aquest cas, el punter `main` ha avançat des del _commit_ `bdbfcb2` fins al _commit_ `ced9cee`.
:::
#4.1.1[Estat del repositori abans del merge fast-forward](/itb/DAM-ED/UD2/img/git_material/03_branches/before_ff.png)
#4.1.2[Estat del repositori després del merge fast-forward](/itb/DAM-ED/UD2/img/git_material/03_branches/after_ff.png)
Si consultem l'estat del fitxer, podem veure com sí que s'han incorporat els canvis fets en l'últim _commit_.
```shell
joapuiib@FP:~/git_tutorial (main) $ cat README.md
# Tutorial de Git
Estem aprenent a utilitzar Git!
Hem modificat un fitxer existent.
## Documentació
- https://git-scm.com/docs
```
### Branques divergents
La fusió directa o _fast-forward_ és la manera més fàcil i neta d'incorporar canvis, però no sempre és possible.
Primer, fem un canvi al fitxer __README.md__ des de la branca `main`:
```shell
joapuiib@FP:~/git_tutorial (main) $ nano README.md
joapuiib@FP:~/git_tutorial (main) $ git diff
diff --git a/README.md b/README.md
index 2a4404c..8edda24 100644
--- a/README.md
+++ b/README.md
@@ -3,5 +3,8 @@ Estem aprenent a utilitzar Git!
Hem modificat un fitxer existent.
+## Branques
+Estem aprenent a utilitzar branques.
+
## Documentació
- https://git-scm.com/docs
joapuiib@FP:~/git_tutorial (main) $ git add README.md
joapuiib@FP:~/git_tutorial (main) $ git commit -m "Added branch text"
[main 7344d0a] Added branch text
1 file changed, 3 insertions(+)
joapuiib@FP:~/git_tutorial (main) $ git lga
* 7344d0a - (2 seconds ago) Added branch text - Joan Puigcerver (HEAD -> main)
* ced9cee - (1 hour ago) Added docs - Joan Puigcerver (docs, origin/docs)
* bdbfcb2 - (1 day ago) Modificació de Pau - Pau (origin/main, origin/HEAD)
* c9fc6c8 - (2 day ago) Changed README.md - Joan Puigcerver
* 8e70293 - (5 days ago) Added Readme.md - Joan Puigcerver
```
Després, fem un canvi al fitxer __README.md__ des de la branca `docs`:
```shell
joapuiib@FP:~/git_tutorial (main) $ git checkout docs
Switched to branch 'docs'
joapuiib@FP:~/git_tutorial (docs) $ nano README.md
joapuiib@FP:~/git_tutorial (docs) $ git diff
diff --git a/README.md b/README.md
index 2a4404c..68d0029 100644
--- a/README.md
+++ b/README.md
@@ -5,3 +5,4 @@ Hem modificat un fitxer existent.
## Documentació
- https://git-scm.com/docs
+- https://git-scm.com/docs/git-merge
joapuiib@FP:~/git_tutorial (docs) $ git add README.md
joapuiib@FP:~/git_tutorial (docs) $ git commit -m "Added more docs"
[docs 8c00eae] Added more docs
1 file changed, 1 insertion(+)
joapuiib@FP:~/git_tutorial (docs) $ git lga
* 8c00eae - (12 seconds ago) Added more docs - Joan Puigcerver (HEAD -> docs)
| * 7344d0a - (5 minutes ago) Added branch text - Joan Puigcerver (main)
|/
* ced9cee - (1 hour ago) Added docs - Joan Puigcerver (origin/docs)
* bdbfcb2 - (1 day ago) Modificació de Pau - Pau (origin/main, origin/HEAD)
* c9fc6c8 - (2 day ago) Changed README.md - Joan Puigcerver
* 8e70293 - (5 days ago) Added Readme.md - Joan Puigcerver
```
Podeu observar com les dues branques `main` i `docs` s'originen a partir del mateix _commit_ `ced9cee`,
però han divergit ja que s'han fet canvis en les dues branques de manera independent.
#4.2.1[Estat del repostori abans del merge](/itb/DAM-ED/UD2/img/git_material/03_branches/before_divergent.png)
En aquest cas, si volem incorporar els canvis de `docs` a `main`, no és possible realitzar una fusió directa
o _fast-forward_. Si realitzem la fusió (`merge`), se'ns obrirà l'editor configurat per defecte,
on podem especificar el missage del __merge _commit___, que crearà Git per integrar els canvis de les dues branques.
::: info
Quan s'obri l'editor de text configurat per defecte, heu de guardar el contingut i tancar-lo per continuar amb
el `merge`.
Si esborreu el missatge, el `merge` no es portarà a terme.
:::
#4.2.2[Estat del repositori després del merge](/itb/DAM-ED/UD2/img/git_material/03_branches/after_divergent.png)
```shell
joapuiib@FP:~/git_tutorial (docs) $ git checkout main
Switched to branch 'main'
joapuiib@FP:~/git_tutorial (main) $ git merge docs
Auto-merging README.md
Merge made by the 'recursive' strategy.
README.md | 1 .green{+}
1 file changed, 1 insertion(+)
joapuiib@FP:~/git_tutorial (main) $ git lga
* 888cdca - (15 seconds ago) Merge branch 'docs' into main - Joan Puigcerver (HEAD -> main)
|\
| * 8c00eae - (7 minutes ago) Added more docs - Joan Puigcerver (docs)
* | 7344d0a - (12 minutes ago) Added branch text - Joan Puigcerver
|/
* ced9cee - (1 hour ago) Added docs - Joan Puigcerver (origin/docs)
* bdbfcb2 - (1 day ago) Modificació de Pau - Pau (origin/main, origin/HEAD)
* c9fc6c8 - (2 day ago) Changed README.md - Joan Puigcerver
* 8e70293 - (5 days ago) Added Readme.md - Joan Puigcerver
```
S'ha creat el _commit_ `888cfca`, que incorpora els canvis de les dues branques.
### Resolució de conflictes
Fins ara, els canvis que hem realitzat en les branques no han entrat en conflicte entre ells.
Si dues branques modifiquen la mateixa part d'un fitxer, apareixerà un conflicte quan tractem
de fususionar els dos canvis.
Primer, creem la branca `branch_text` en el repositori:
```shell
joapuiib@FP:~/git_tutorial (main) $ git branch branch_text
joapuiib@FP:~/git_tutorial (main) $ git lga
* 888cdca - (1 hour ago) Merge branch 'docs' into main - Joan Puigcerver (HEAD -> main, branch_text)
|\
| * 8c00eae - (1 hour ago) Added more docs - Joan Puigcerver (docs)
* | 7344d0a - (1 hour ago) Added branch text - Joan Puigcerver
|/
* ced9cee - (2 hours ago) Added docs - Joan Puigcerver (origin/docs)
* bdbfcb2 - (1 day ago) Modificació de Pau - Pau (origin/main, origin/HEAD)
* c9fc6c8 - (2 day ago) Changed README.md - Joan Puigcerver
* 8e70293 - (5 days ago) Added Readme.md - Joan Puigcerver
```
Després, des de la branca `main` anem a fer canvis en el fitxer __README.md__:
```shell
joapuiib@FP:~/git_tutorial (main) $ nano README.md
joapuiib@FP:~/git_tutorial (main) $ git diff
diff --git a/README.md b/README.md
index f8ad314..32c3d04 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@ Estem aprenent a utilitzar Git!
Hem modificat un fitxer existent.
## Branques
-Estem aprenent a utilitzar branques.
+Estem aprenent a utilitzar i fusionar branques.
## Documentació
- https://git-scm.com/docs
joapuiib@FP:~/git_tutorial (main) $ git add README.md
joapuiib@FP:~/git_tutorial (main) $ git commit -m "Modified branch text"
[main cc8cf03] Modified branch text
1 file changed, 1 insertion(+), 1 deletion(-)
joapuiib@FP:~/git_tutorial (main) $ git lga
* cc8cf03 - (3 seconds ago) Modified branch text - Joan Puigcerver (HEAD -> main)
* 888cdca - (1 hour ago) Merge branch 'docs' into main - Joan Puigcerver (branch_text)
|\
| * 8c00eae - (1 hour ago) Added more docs - Joan Puigcerver (docs)
* | 7344d0a - (1 hour ago) Added branch text - Joan Puigcerver
|/
* ced9cee - (2 hours ago) Added docs - Joan Puigcerver (origin/docs)
* bdbfcb2 - (1 day ago) Modificació de Pau - Pau (origin/main, origin/HEAD)
* c9fc6c8 - (2 day ago) Changed README.md - Joan Puigcerver
* 8e70293 - (5 days ago) Added Readme.md - Joan Puigcerver
```
Finalment, des de la branca `branch_text` fem canvis en la mateixa secció del fitxer __README.md__:
```shell
joapuiib@FP:~/git_tutorial (main) $ git checkout branch_text
Switched to branch 'branch_text'
joapuiib@FP:~/git_tutorial (branch_text) $ nano README.md
joapuiib@FP:~/git_tutorial (branch_text) $ git diff
diff --git a/README.md b/README.md
index f8ad314..32c3d04 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@ Estem aprenent a utilitzar Git!
Hem modificat un fitxer existent.
## Branques
-Estem aprenent a utilitzar branques.
+Estem aprenent a utilitzar i resoldre conflictes en les branques.
## Documentació
- https://git-scm.com/docs
joapuiib@FP:~/git_tutorial (branch_text) $ git add README.md
joapuiib@FP:~/git_tutorial (branch_text) $ git commit -m "Resolve conflict text"
[branch_text 421fbed] Resolve conflict text
1 file changed, 1 insertion(+), 1 deletion(-)
joapuiib@FP:~/git_tutorial (branch_text) $ git lga
* 421fbed - (28 seconds ago) Resolve conflict text - Joan Puigcerver (HEAD -> branch_text)
| * cc8cf03 - (5 minutes ago) Modified branch text - Joan Puigcerver (main)
|/
* 888cdca - (1 hour ago) Merge branch 'docs' into main - Joan Puigcerver
|\
| * 8c00eae - (1 hour ago) Added more docs - Joan Puigcerver (docs)
* | 7344d0a - (1 hour ago) Added branch text - Joan Puigcerver
|/
* ced9cee - (2 hours ago) Added docs - Joan Puigcerver (origin/docs)
* bdbfcb2 - (1 day ago) Modificació de Pau - Pau (origin/main, origin/HEAD)
* c9fc6c8 - (2 day ago) Changed README.md - Joan Puigcerver
* 8e70293 - (5 days ago) Added Readme.md - Joan Puigcerver
```
Anem a incorporar els canvis de `branch_text` a `main`:
```shell
joapuiib@FP:~/git_tutorial (branch_text) $ git checkout main
Switched to branch 'main'
joapuiib@FP:~/git_tutorial (main) $ git merge branch_text
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
Automatic merge failed; fix conflicts and then commit the result.
joapuiib@FP:~/git_tutorial (main|MERGING) $ git status
On branch main
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add <file>..." to mark resolution)
.red{both modified: README.md}
no changes added to commit (use "git add" and/or "git commit -a")
joapuiib@FP:~/git_tutorial (main|MERGING) $ cat README.md
# Tutorial de Git
Estem aprenent a utilitzar Git!
Hem modificat un fitxer existent.
## Branques
<<<<<<< HEAD
Estem aprenent a utilitzar i fusionar branques.
=======
Estem aprenent a utilitzar i resoldre conflictes en les branques.
>>>>>>> branch_text
## Documentació
- https://git-scm.com/docs
- https://git-scm.com/docs/git-merge
```
Observeu com la fusió `merge` no s'ha portat a terme perquè Git ha detectat un conflicte
i ens demana que el solucionem.
Analitzem la informació de `git status`:
- Ens indica que estem a meitat d'un `merge`.
- Ens indica que hem de solucionar els conflictes i executar `git commit`.
- Podem avortar la fusió `merge` mitjançant `git merge --abort`.
- Ens indica que el fitxer __README.md__ ha sigut modificat per les dues branques.
- Ens indica que hem de fer un `git add <file>` per indicar que hem resolt els conflictes.
Observem que en el contingut del fitxer __README.md__ s'ha afegit el següent contingut:
```text
<<<<<<< HEAD
Estem aprenent a utilitzar i fusionar branques.
=======
Estem aprenent a utilitzar i resoldre conflictes en les branques.
>>>>>>> branch_text
```
En aquest text vegem que:
- En la part de dalt indica què ha canviat en la branca actual (`HEAD`)
- La línia __=======__ separa els canvis de les dues branques.
- En la part de baix indica què ha canviat en la branca que estem fusionant (`branch_text`)
Per a resoldre el conflicte, heu de modificar el contingut del fixer per incorporar
els dos canvis i eliminar les línies especials que ha introduït Git.
Podem deixar el contingut com:
```text
## Branques
Estem aprenent a utilitzar branques, com fusionar-les i resoldre els conflictes.
```
```shell
joapuiib@FP:~/git_tutorial (main|MERGING) $ nano README.md
joapuiib@FP:~/git_tutorial (main|MERGING) $ git diff
diff --cc README.md
index 32c3d04,9954f8c..0000000
--- a/README.md
+++ b/README.md
@@@ -4,7 -4,7 +4,7 @@@ Estem aprenent a utilitzar Git
Hem modificat un fitxer existent.
## Branques
- Estem aprenent a utilitzar i fusionar branques.
.red{-Estem aprenent a utilitzar i resoldre conflictes en les branques.}
++Estem aprenent a utilitzar branques, com fusionar-les i resoldre els conflictes.
## Documentació
- https://git-scm.com/docs
```
Marquem el fitxer com resol mitjançant `git add`:
```shell
joapuiib@FP:~/git_tutorial (main|MERGING) $ git status
On branch main
You have unmerged paths.
(fix conflicts and run "git commit")
(use "git merge --abort" to abort the merge)
Unmerged paths:
(use "git add <file>..." to mark resolution)
.red{both modified: README.md}
no changes added to commit (use "git add" and/or "git commit -a")
joapuiib@FP:~/git_tutorial (main|MERGING) $ git add README.md
joapuiib@FP:~/git_tutorial (main|MERGING) $ git status
On branch main
All conflicts fixed but you are still merging.
(use "git commit" to conclude merge)
Changes to be committed:
.green{modified: README.md}
```
Ja hem resolt tots els conflictes. Per concluir la fusió `merge`, executem l'ordre `git commit`.
Això ens obrirà l'editor de text amb el missatge de _commit_ per defecte.
```shell
joapuiib@FP:~/git_tutorial (main|MERGING) $ git commit
[main 270498d] Merge branch 'branch_text' into main
joapuiib@FP:~/git_tutorial (main) $ git lga
* 270498d - (13 seconds ago) Merge branch 'branch_text' into main - Joan Puigcerver (HEAD -> main)
|\
| * 421fbed - (5 minutes ago) Resolve conflict text - Joan Puigcerver (branch_text)
* | cc8cf03 - (10 minutes ago) Modified branch text - Joan Puigcerver
|/
* 888cdca - (1 hour ago) Merge branch 'docs' into main - Joan Puigcerver
|\
| * 8c00eae - (1 hour ago) Added more docs - Joan Puigcerver (docs)
* | 7344d0a - (1 hour ago) Added branch text - Joan Puigcerver
|/
* ced9cee - (2 hours ago) Added docs - Joan Puigcerver (origin/docs)
* bdbfcb2 - (1 day ago) Modificació de Pau - Pau (origin/main, origin/HEAD)
* c9fc6c8 - (2 day ago) Changed README.md - Joan Puigcerver
* 8e70293 - (5 days ago) Added Readme.md - Joan Puigcerver
```
## Canvi de base (rebase)
A més del `merge`, Git ens proporciona una altra manera de fusionar canvis entre dues branques,
anomenat __Canvi de base__ o `rebase`.
En l'exemple anterior, s'han fusionat dues branques divergents `main` i `docs` mitjançant un _Merge Commit_,
que combina les dues històries. `rebase` proporciona una manera més neta d'incorporar els canvis entre les
dues branques.
Quan es va crear la branca `docs`, inicialment es trobava en el mateix punt que la branca `main`,
però al realitzar canvis en les dues branques, la seua història es va separar. Aquest _commit_ on
es va originar la branca, és l'_antecessor comú_ de les dues branques, que podem anomenar com la _base_.
De manera simplificada, l'operació `rebase` el que fa és canviar la base de la branca actual al lloc especificat.
Creem la branca `rebase_text` i afegim nou text al fitxer __README.md__:
::: info
Quan creem una branca mitjançant `git branch`, no es mou el `HEAD` a aquesta branca, operació
la qual s'hauria de fer amb `git checkout`.
Podem realitzar les dues accions a la vegada utilitzant l'opció `-b` de l'ordre `checkout`,
que crearà la branca i mourà el `HEAD` a aquesta:
```bash
git checkout -b <branch_name>
```
:::
```shell
joapuiib@FP:~/git_tutorial (main) $ git checkout -b rebase_text
Switched to a new branch 'rebase_text'
joapuiib@FP:~/git_tutorial (rebase_text) $ nano README.md
joapuiib@FP:~/git_tutorial (rebase_text) $ git diff
diff --git a/README.md b/README.md
index 0c03e66..7d4f4f9 100644
--- a/README.md
+++ b/README.md
@@ -5,6 +5,8 @@ Hem modificat un fitxer existent.
## Branques
Estem aprenent a utilitzar branques, com fusionar-les i resoldre els conflictes.
+
+### Canvi de base
+L'operació `rebase` s'utilitza per canviar la base d'una branca.
## Documentació
- https://git-scm.com/docs
joapuiib@FP:~/git_tutorial (rebase_text) $ git add README.md
joapuiib@FP:~/git_tutorial (rebase_text) $ git commit -m "Added rebase text"
[rebase_text 4d5800d] Added rebase text
1 file changed, 2 insertions(+)
joapuiib@FP:~/git_tutorial (rebase_text) $ git lga
* 4d5800d - (30 seconds ago) Added rebase text - Joan Puigcerver (HEAD -> rebase_text)
* 270498d - (1 day ago) Merge branch 'branch_text' into main - Joan Puigcerver (main)
[...]
```
Anem a fer divergir la branca `main` amb un nou _commit_:
```shell
joapuiib@FP:~/git_tutorial (rebase_text) $ git checkout main
Switched to branch 'main'
joapuiib@FP:~/git_tutorial (main) $ nano README.md
joapuiib@FP:~/git_tutorial (main) $ git diff
diff --git a/README.md b/README.md
index 0c03e66..0aeb509 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,7 @@ Estem aprenent a utilitzar Git!
Hem modificat un fitxer existent.
## Branques
-Estem aprenent a utilitzar branques, com fusionar-les i resoldre els conflictes.
+Estem aprenent a utilitzar branques, com fusionar-les, canviar la seua base i resoldre els conflictes.
## Documentació
- https://git-scm.com/docs
joapuiib@FP:~/git_tutorial (main) $ git add README.md
joapuiib@FP:~/git_tutorial (main) $ git commit -m "Added rebase to branch text"
[main 1f28584] Added rebase to branch text
1 file changed, 1 insertion(+), 1 deletion(-)
joapuiib@FP:~/git_tutorial (main) $ git lga
* 1f28584 - (15 seconds ago) Added rebase to branch text - Joan Puigcerver (HEAD -> main)
| * 4d5800d - (5 minutes ago) Added rebase text - Joan Puigcerver (rebase_text)
|/
* 270498d - (1 day ago) Merge branch 'branch_text' into main - Joan Puigcerver
[...]
```
#5.1[Estat del repositori abans del canvi de base](/itb/DAM-ED/UD2/img/git_material/03_branches/before_rebase.png)
Si en aquest moment, fem una fusió entre `main` i `rebase_text`, es crearia un _Merge commit_
on convergirien les dues branques. Per evitar-ho i fusionar-les d'una manera més neta,
primer canviarem la base de la branca `rebase_text` a la branca `main`.
El funcionament de la comanda `rebase` és que mou la branca actual `HEAD` a la branca
que s'especifica en la comanda:
```bash
git rebase <branch_name>
```
Per tant, si volem canviar la base de la branca `rebase_text`, primer ens hem de posicionar en ella:
```shell
joapuiib@FP:~/git_tutorial (main) $ git checkout rebase_text
Switched to branch 'rebase_text'
joapuiib@FP:~/git_tutorial (rebase_text) $ git rebase main
First, rewinding head to replay your work on top of it...
Applying: Added rebase text
Using index info to reconstruct a base tree...
M README.md
Falling back to patching base and 3-way merge...
Auto-merging README.md
joapuiib@FP:~/git_tutorial (rebase_text) $ cat README.md
cat README.md
# Tutorial de Git
Estem aprenent a utilitzar Git!
Hem modificat un fitxer existent.
## Branques
Estem aprenent a utilitzar branques, com fusionar-les, canviar la seua base i resoldre els conflictes.
### Canvi de base
L'operació `rebase` s'utilitza per canviar la base d'una branca.
## Documentació
- https://git-scm.com/docs
- https://git-scm.com/docs/git-merge
joapuiib@FP:~/git_tutorial (rebase_text) $ git lga
* 81403f8 - (10 minutes ago) Added rebase text - Joan Puigcerver (HEAD -> rebase_text)
* 1f28584 - (5 minutes ago) Added rebase to branch text - Joan Puigcerver (main)
* 270498d - (1 day ago) Merge branch 'branch_text' into main - Joan Puigcerver
[...]
```
#5.2[Estat del repositori després del canvi de base](/itb/DAM-ED/UD2/img/git_material/03_branches/after_rebase.png)
S'ha efectuat el `rebase` i observem que en la branca `rebase_text` tenim els canvis efectuats en les dues branques.
El _commit_ __Added rebase text__ ara té com a base el _commit_ `81403f8`, quan abans era `4d5800d`.
::: info
També observem que el _hash_ del _commit_ ha canviat.
Això és deu a què Git, el que realment ha fet és crear un nou _commit_
amb els canvis que es van efectuar en l'anterior _commit_.
:::
En aquest moment, podríem continuar treballant en la branca `rebase_text` si considerem
que els canvis realitzats no són suficients per a incorporar-los a la branca `main`.
En el cas que sí que es vulga incorporar els canvis a la branca `main`, podem
fusionar (`merge`) les dues branques en una fusió directa (_fast-forward_).
Observarvem que la història és més neta que amb un _Merge Commit_.
```shell
joapuiib@FP:~/git_tutorial (rebase_text) $ git checkout main
Switched to branch 'main'
joapuiib@FP:~/git_tutorial (main) $ git merge rebase_text
Updating 1f28584..81403f8
Fast-forward
README.md | 3 .green{+++}
1 file changed, 3 insertions(+)
joapuiib@FP:~/git_tutorial (main) $ git lga
* 81403f8 - (10 minutes ago) Added rebase text - Joan Puigcerver (HEAD -> main, rebase_text)
* 1f28584 - (5 minutes ago) Added rebase to branch text - Joan Puigcerver
* 270498d - (1 day ago) Merge branch 'branch_text' into main - Joan Puigcerver
[...]
```
### Resolució de conflictes
De la mateixa manera que amb el `merge`, també poden sorgir conflictes quan fem un `rebase` si les dues branques han
fet modificacions en les mateixes parts del codi.
Creem un conflicte entre les branques `main` i `rebase_text`.
```shell
joapuiib@FP:~/git_tutorial (main) $ nano README.md
joapuiib@FP:~/git_tutorial (main) $ git diff
diff --git a/README.md b/README.md
index 7ac542e..1dd118e 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@ Hem modificat un fitxer existent.
Estem aprenent a utilitzar branques, com fusionar-les, canviar la seua base i resoldre els conflictes.
### Canvi de base
-L'operació `rebase` s'utilitza per canviar la base d'una branca.
+L'operació `rebase` s'utilitza per canviar la base d'una branca. També poden sorgir conflictes.
## Documentació
- https://git-scm.com/docs
joapuiib@FP:~/git_tutorial (main) $ git add README.md
joapuiib@FP:~/git_tutorial (main) $ git commit -m "Rebase conflict text"
[main 84fe400] Rebase conflict text
1 file changed, 1 insertion(+), 1 deletion(-)
joapuiib@FP:~/git_tutorial (main) $ git push
Total 0 (delta 0), reused 0 (delta 0)
To github.com:joapuiib/git_tutorial.git
270498d..84fe400 main -> main
joapuiib@FP:~/git_tutorial (main) $ git lga
* 84fe400 - (26 seconds ago) Rebase conflict text - Joan Puigcerver (HEAD -> main, origin/main)
* 81403f8 - (2 hours ago) Added rebase text - Joan Puigcerver (rebase_text)
* 1f28584 - (2 hours ago) Added rebase to branch text - Joan Puigcerver
* 270498d - (1 day ago) Merge branch 'branch_text' into main - Joan Puigcerver
[...]
```
Des de la banca `rebase_text`:
```shell
joapuiib@FP:~/git_tutorial (main) $ git checkout rebase_text
Switched to branch 'rebase_text'
joapuiib@FP:~/git_tutorial (rebase_text) $ nano README.md
joapuiib@FP:~/git_tutorial (rebase_text) $ git diff
diff --git a/README.md b/README.md
index 7ac542e..1dd118e 100644
--- a/README.md
+++ b/README.md
@@ -7,7 +7,7 @@ Hem modificat un fitxer existent.
Estem aprenent a utilitzar branques, com fusionar-les, canviar la seua base i resoldre els conflictes.
### Canvi de base
-L'operació `rebase` s'utilitza per canviar la base d'una branca.
+L'operació `rebase` s'utilitza per canviar la base d'una branca. Cal resoldre els conflictes.
## Documentació
- https://git-scm.com/docs
joapuiib@FP:~/git_tutorial (rebase_text) $ git add README.md
joapuiib@FP:~/git_tutorial (rebase_text) $ git commit -m "Resolve rebase conflict text"
[rebase_text 86d3db7] Resolve rebase conflict text
1 file changed, 1 insertion(+), 1 deletion(-)
[rebase_text 84fe400] Rebase conflict text
joapuiib@FP:~/git_tutorial (rebase_text) $ git push -u origin rebase_text
Enumerating objects: 11, done.
Counting objects: 100% (11/11), done.
Delta compression using up to 12 threads
Compressing objects: 100% (9/9), done.
Writing objects: 100% (9/9), 954 bytes | 954.00 KiB/s, done.
Total 9 (delta 3), reused 0 (delta 0)
remote: Resolving deltas: 100% (3/3), completed with 1 local object.
remote:
remote: Create a pull request for 'rebase_text' on GitHub by visiting:
remote: https://github.com/joapuiib/git_tutorial/pull/new/rebase_text
remote:
To github.com:joapuiib/git_tutorial.git
* [new branch] rebase_text -> rebase_text
Branch 'rebase_text' set up to track remote branch 'rebase_text' from 'origin'.
joapuiib@FP:~/git_tutorial (rebase_text) $ git lga
* 86d3db7 - (18 seconds ago) Resolve rebase conflict text - Joan Puigcerver (HEAD -> rebase_text, origin/rebase_text)
| * 84fe400 - (5 minutes ago) Rebase conflict text - Joan Puigcerver (main, origin/main)
|/
* 81403f8 - (2 hours ago) Added rebase text - Joan Puigcerver
* 1f28584 - (2 hours ago) Added rebase to branch text - Joan Puigcerver
* 270498d - (1 day ago) Merge branch 'branch_text' into main - Joan Puigcerver
[...]
```
::: info
Hem publicat la branca `rebase_text` abans de fer el `rebase`.
Aquesta operació ens servirà per al següent apartat.
:::
Canviem la base de la branca `rebase_text` a `main`:
```shell
joapuiib@FP:~/git_tutorial (rebase_text) $ git rebase main
First, rewinding head to replay your work on top of it...
Applying: Resolve rebase conflict text
Using index info to reconstruct a base tree...
M README.md
Falling back to patching base and 3-way merge...
Auto-merging README.md
CONFLICT (content): Merge conflict in README.md
error: Failed to merge in the changes.
Patch failed at 0001 Resolve rebase conflict text
.yellow{hint: Use 'git am --show-current-patch' to see the failed patch}
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 "git rebase", run "git rebase --abort".
joapuiib@FP:~/git_tutorial (rebase_text|REBASE 1/1) $ git status
.red{rebase in progress; onto} 84fe400
You are currently rebasing branch 'rebase_text' on '84fe400'.
(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)
.red{both modified: README.md}
no changes added to commit (use "git add" and/or "git commit -a")
```
S'observa que el `rebase` no s'ha pogut efectuar perquè han sorgit conflictes,
que hem de resoldre.
Analitzem la informació de `git status`:
- Indica que estem a meitat d'un `rebase`.
- S'han de resoldre els conflictes i continar amb `git rebase --continue`.
- Es pot avortar l'operació amb `git rebase --abort`.
- Ens indica que el fitxer __README.md__ ha sigut modificat per les dues branques.
- Ens indica que hem de fer un `git add <file>` per indicar que hem resolt els conflictes.
Resolem els conflictes de la mateixa manera que quan ho hem fet en l'operació de fusió `merge`
i continuem amb el `rebase`.
```shell
joapuiib@FP:~/git_tutorial (rebase_text|REBASE 1/1) $ nano README.md
joapuiib@FP:~/git_tutorial (rebase_text|REBASE 1/1) $ git diff
diff --cc README.md
index 1dd118e,6ccc124..0000000
--- a/README.md
+++ b/README.md
@@@ -7,7 -7,7 +7,7 @@@ Hem modificat un fitxer existent
Estem aprenent a utilitzar branques, com fusionar-les, canviar la seua base i resoldre els conflictes.
### Canvi de base
- L'operació `rebase` s'utilitza per canviar la base d'una branca. També poden sorgir conflictes.
.red{ -L'operació `rebase` s'utilitza per canviar la base d'una branca. Cal resoldre els conflictes.}
++L'operació `rebase` s'utilitza per canviar la base d'una branca. També poden sorgir conflictes, que haurem de resoldre.
## Documentació
- https://git-scm.com/docs
joapuiib@FP:~/git_tutorial (rebase_text|REBASE 1/1) $ git add README.md
joapuiib@FP:~/git_tutorial (rebase_text|REBASE 1/1) $ git status
.red{rebase in progress; onto} 84fe400
You are currently rebasing branch 'rebase_text' on '84fe400'.
(all conflicts fixed: run "git rebase --continue")
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
.green{modified: README.md}
joapuiib@FP:~/git_tutorial (rebase_text|REBASE 1/1) $ git rebase --continue
Applying: Resolve rebase conflict text
joapuiib@FP:~/git_tutorial (rebase_text) $ git lga
* 23bbe2c - (5 minutes ago) Resolve rebase conflict text - Joan Puigcerver (HEAD -> rebase_text)
* 84fe400 - (9 minutes ago) Rebase conflict text - Joan Puigcerver (main, origin/main)
| * 86d3db7 - (5 minutes ago) Resolve rebase conflict text - Joan Puigcerver (origin/rebase_text)
|/
* 81403f8 - (2 hours ago) Added rebase text - Joan Puigcerver
* 1f28584 - (2 hours ago) Added rebase to branch text - Joan Puigcerver
* 270498d - (1 day ago) Merge branch 'branch_text' into main - Joan Puigcerver
[...]
joapuiib@FP:~/git_tutorial (rebase_text) $ cat README.md
# Tutorial de Git
Estem aprenent a utilitzar Git!
Hem modificat un fitxer existent.
## Branques
Estem aprenent a utilitzar branques, com fusionar-les, canviar la seua base i resoldre els conflictes.
### Canvi de base
L'operació `rebase` s'utilitza per canviar la base d'una branca. També poden sorgir conflictes, que haurem de resoldre.
## Documentació
- https://git-scm.com/docs
- https://git-scm.com/docs/git-merge
```
S'ha creat el _commit_ `23bbe2c` com a resultat del `rebase`.
No obstant, en aquest cas, el _commit_ original `86d3db7` continua existint en el repositori,
ja que abans l'hem publicat `push`.
En el següent apartat s'explica com solucionar-ho.
### Sincronitzar branca remota
Quan es realitza un `rebase`, es creen nous _commits_ que contenen els canvis
dels _commits_ originals. Si la branca ha sigut publicada amb un `push`, els _commits_
anteriors estaran referenciats per la branca `origin/branch_name` i continuaran existint en el repositori.
#5.2.1[Estat del repositori després del canvi de base quan s'havia publicat prèviament la branca](/itb/DAM-ED/UD2/img/git_material/03_branches/before_rebase_push.png)
```shell
joapuiib@FP:~/git_tutorial (rebase_text) $ git lga
* 23bbe2c - (5 minutes ago) Resolve rebase conflict text - Joan Puigcerver (HEAD -> rebase_text)
* 84fe400 - (9 minutes ago) Rebase conflict text - Joan Puigcerver (main, origin/main)
| * 86d3db7 - (5 minutes ago) Resolve rebase conflict text - Joan Puigcerver (origin/rebase_text)
|/
* 81403f8 - (2 hours ago) Added rebase text - Joan Puigcerver
[...]
```
Si intentem publicar la nova branca, després de fer el `rebase` ens trobarem amb el següent error:
```shell
joapuiib@FP:~/git_tutorial (rebase_text) $ git push
To github.com:joapuiib/git_tutorial.git
.red{! [rejected] rebase_text -> rebase_text (non-fast-forward)
error: failed to push some refs to 'git@github.com:joapuiib/git_tutorial.git'}
.yellow{hint: Updates were rejected because the tip of your current branch is behind
hint: its remote counterpart. Integrate the remote changes (e.g.
hint: 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.}
```
::: danger
No seguiu el consell `git pull` en aquest cas.
Git ha detectat que hi ha _commits_ en el Repositori Remot que no estan en la branca local i,
per tant, ens suggereix que els integrem amb `git pull`. No obstant això, aquests canvis
corresponen al _commit_ original, abans de fer el `rebase`.
:::
En aquest cas, el que s'ha de fer és __modificar la història__ del _Repositori Remot_
i publicar els canvis de manera forçosa amb l'opció `-f` o `--force`. D'aquesta manera, el _commit_ original
desapareixerà i la branca estarà sincronitzada en els dos repositoris.
#5.2.2[Estat del repositori després de publicar de nou la branca on s'ha canviat la base](/itb/DAM-ED/UD2/img/git_material/03_branches/after_rebase_push.png)
```shell
joapuiib@FP:~/git_tutorial (rebase_text) $ git push --force
Enumerating objects: 8, done.
Counting objects: 100% (8/8), done.
Delta compression using up to 12 threads
Compressing objects: 100% (6/6), done.
Writing objects: 100% (6/6), 654 bytes | 327.00 KiB/s, done.
Total 6 (delta 2), reused 0 (delta 0)
remote: Resolving deltas: 100% (2/2), completed with 1 local object.
To github.com:joapuiib/git_tutorial.git
+ a7bf696...c360f57 rebase_text -> rebase_text (forced update)
joapuiib@FP:~/git_tutorial (rebase_text) $ git lga
* 23bbe2c - (5 minutes ago) Resolve rebase conflict text - Joan Puigcerver (HEAD -> rebase_text, origin/rebase_text)
* 84fe400 - (9 minutes ago) Rebase conflict text - Joan Puigcerver (main, origin/main)
* 81403f8 - (2 hours ago) Added rebase text - Joan Puigcerver
[...]
```
Per concloure, podem fusionar la branca `rebase_text` i `main`.
```shell
joapuiib@FP:~/git_tutorial (rebase_text) $ git checkout main
Switched to branch 'main'
joapuiib@FP:~/git_tutorial (main) $ git merge rebase_text
Updating 84fe400..c360f57
Fast-forward
README.md | 2 .green{+}.red{-}
1 file changed, 1 insertion(+), 1 deletion(-)
joapuiib@FP:~/git_tutorial (main) $ git push
Total 0 (delta 0), reused 0 (delta 0)
To github.com:joapuiib/git_tutorial.git
+ faed5a5...23bbe2c main -> main
joapuiib@FP:~/git_tutorial (main) $ git lga
* 23bbe2c - (5 minutes ago) Resolve rebase conflict text - Joan Puigcerver (HEAD -> main, rebase_text, origin/main, origin/rebase_text)
* 84fe400 - (9 minutes ago) Rebase conflict text - Joan Puigcerver
* 81403f8 - (2 hours ago) Added rebase text - Joan Puigcerver
[...]
```
## Pull: Merge vs Rebase
Imagineu que en aquest punt, una altra persona, com podria ser Pau realitza canvis en la branca `main`.
```shell
pau@FP:~/git_tutorial_pau (main) $ git pull
From github.com:joapuiib/git_tutorial
* [new branch] main -> origin/main
Updating bdbfcb2..84fe400
Fast-forward
README.md | 10 .green{++++++++++}
1 file changed, 10 insertions(+)
pau@FP:~/git_tutorial_pau (main) $ git lga
* 23bbe2c - (5 minutes ago) Resolve rebase conflict text - Joan Puigcerver (HEAD -> main, rebase_text, origin/main, origin/rebase_text)
* 84fe400 - (9 minutes ago) Rebase conflict text - Joan Puigcerver
* 81403f8 - (2 hours ago) Added rebase text - Joan Puigcerver
[...]
pau@FP:~/git_tutorial_pau (main) $ nano pau.txt
pau@FP:~/git_tutorial_pau (main) $ git diff
diff --git a/pau.txt b/pau.txt
index b133905..c7de357 100644
--- a/pau.txt
+++ b/pau.txt
@@ -1,1 +1,2 @@
Modificació de Pau
+Altra modificació de Pau
pau@FP:~/git_tutorial_pau (main) $ git commit -a -m "Altra modificació de Pau"
[main faed5a5] Altra modificacio de Pau
1 file changed, 1 insertion(+)
pau@FP:~/git_tutorial_pau (main) $ git push
Enumerating objects: 5, done.
Counting objects: 100% (5/5), done.
Delta compression using up to 12 threads
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 304 bytes | 304.00 KiB/s, done.
Total 3 (delta 0), reused 0 (delta 0)
To github.com:joapuiib/git_tutorial.git
84fe400..faed5a5 main -> main
pau@FP:~/git_tutorial_pau (main) $ git lga
* faed5a5 - (2 seconds ago) Altra modificacio de Pau - Pau (HEAD -> main, origin/main)
* 23bbe2c - (5 minutes ago) Resolve rebase conflict text - Joan Puigcerver (rebase_text, origin/rebase_text)
* 84fe400 - (9 minutes ago) Rebase conflict text - Joan Puigcerver
* 81403f8 - (2 hours ago) Added rebase text - Joan Puigcerver
[...]
```
#6.1[Estat del repositori de Pau després d'un commit a 'main'](/itb/DAM-ED/UD2/img/git_material/03_branches/pau_commit_before_pull_rebase.png)
::: info
L'opció `-a` en `git commit` afegeix al _Staging Area_ tots els fitxers modificats.
D'aquesta manera t'estalvies executar l'ordre `git add` abans.
Aquesta opció no funciona per als nous fitxers.
:::
Pau ha modificat la branca `main` des d'un punt diferent on nosaltres estem treballant.
Vegem l'estat del repositori:
```shell
joapuiib@FP:~/git_tutorial (main) $ git fetch
remote: Enumerating objects: 5, done.
remote: Counting objects: 100% (5/5), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 3 (delta 0), pack-reused 0
Unpacking objects: 100% (3/3), 284 bytes | 284.00 KiB/s, done.
From github.com:joapuiib/git_tutorial
84fe400..faed5a5 main -> origin/main
joapuiib@FP:~/git_tutorial (main) $ git lga
* faed5a5 - (2 seconds ago) Altra modificacio de Pau - Pau (origin/main)
* 23bbe2c - (5 minutes ago) Resolve rebase conflict text - Joan Puigcerver (HEAD -> main, rebase_text, origin/rebase_text)
* 84fe400 - (9 minutes ago) Rebase conflict text - Joan Puigcerver
* 81403f8 - (2 hours ago) Added rebase text - Joan Puigcerver
[...]
joapuiib@FP:~/git_tutorial (main) $ git status
On branch main
Your branch and 'origin/main' have diverged,
and have 1 and 1 different commits each, respectively.
(use "git pull" to merge the remote branch into yours)
nothing to commit, working tree clean
```
#6.2[Estat del nostre repositori després del fetch](/itb/DAM-ED/UD2/img/git_material/03_branches/pau_commit_fetch.png)
En aquest moment, l'ideal seria incorporar ens canvis del remot amb `git pull`, però abans,
fem una modificació en el repositori en la branca `main`:
```shell
joapuiib@FP:~/git_tutorial (main) $ vi README.md
joapuiib@FP:~/git_tutorial (main) $ git diff
diff --git a/README.md b/README.md
index 76267e7..c7e18e2 100644
--- a/README.md
+++ b/README.md
@@ -9,6 +9,9 @@ Estem aprenent a utilitzar branques, com fusionar-les, canviar la seua base i r
### Canvi de base
L'operació `rebase` s'utilitza per canviar la base d'una branca. També poden sorgir conflictes, que haurem de resoldre.
+## Pull
+L'operació `pull` pot incorporar els canvis mitjançant `merge` o `rebase`.
+
## Documentació
- https://git-scm.com/docs
- https://git-scm.com/docs/git-merge
joapuiib@FP:~/git_tutorial (main) $ git commit -a -m "Added pull text"
[main 8ee181d] Added pull text
1 file changed, 3 insertions(+)
joapuiib@FP:~/git_tutorial (main) $ git lga
* 8ee181d - (7 seconds ago) Added pull text - Joan Puigcerver (HEAD -> main)
| * faed5a5 - (5 minutes ago) Altra modificacio de Pau - Pau (origin/main)
|/
* 23bbe2c - (15 minutes ago) Resolve rebase conflict text - Joan Puigcerver (rebase_text, origin/rebase_text)
* 84fe400 - (19 minutes ago) Rebase conflict text - Joan Puigcerver
[...]
joapuiib@FP:~/git_tutorial (main) $ git status
On branch main
Your branch and 'origin/main' have diverged,
and have 1 and 1 different commits each, respectively.
(use "git pull" to merge the remote branch into yours)
nothing to commit, working tree clean
```
Podeu observar que les branques `main` i `origin/main` han __divergit__. Aquesta situació es dóna
molt sovint quan feu canvis sense haver fet un `pull` prèviament.
#6.3[Estat del nostre repositori després del commit a 'main'](/itb/DAM-ED/UD2/img/git_material/03_branches/commit_before_pull_rebase.png)
L'ordre `git status` ens proposa executar l'ordre `git pull` per a fusionar `merge`
les dues branques.
Per defecte, l'ordre `git pull` efectua una operació `merge` per incorporar els canvis
de la branca remota a la branca local. De la mateixa manera, aquesta fusió pot ser directa (_fast-forward_)
o mitjançant un _Merge commit_ i inclòs, es poden produir conflictes que hauríem de resoldre.
En aquest cas, com les dues branques han divergit, si executem l'ordre `git pull`
és crearà un _Merge commit_.
#6.4[Estat del nostre repositori si fem un `pull`](/itb/DAM-ED/UD2/img/git_material/03_branches/pull_merge.png)
No obstant això, hem aprés com incorporar canvis entre dues branques d'una manera neta i __mantenint una història linial__.
De la mateixa manera, podem indicar-li a l'ordre `pull` que volem integrar els canvis mitjançant un `rebase`,
amb l'opció `--rebase`.
```shell
joapuiib@FP:~/git_tutorial (main) $ git pull --rebase
First, rewinding head to replay your work on top of it...
Applying: Added pull text
joapuiib@FP:~/git_tutorial (main) $ git lga
* 8294072 - (7 seconds ago) Added pull text - Joan Puigcerver (HEAD -> main)
* faed5a5 - (5 minutes ago) Altra modificacio de Pau - Pau (origin/main)
* 23bbe2c - (15 minutes ago) Resolve rebase conflict text - Joan Puigcerver (rebase_text, origin/rebase_text)
[...]
```
#6.5[Estat del nostre repositori despres de fer un `pull --rebase`](/itb/DAM-ED/UD2/img/git_material/03_branches/pull_rebase.png)
## Resum
### Branques locals
- `git branch`: Mostra les branques existents al repositori.
- `git branch <branch name>`: Crea una branca nova amb el nom especificat.
- `git branch -d <branch name>`: Elimina la branca amb el nom especificat.
::: info
En aquest context, `checkout` i `switch` són equivalents.
:::
- `git checkout <ref>`: Mou el `HEAD` (estat actual del repositori) a la referència especificada. La referència pot ser una branca, una etiqueta o un _commit hash_.
- `git checkout -b <branch name>`: Crea una branca nova amb el nom especificat i mou el `HEAD` a aquesta branca.
- `git switch -c <branch name>`: Crea una branca nova amb el nom especificat i mou el `HEAD` a aquesta branca.
### Branques remotes
- `git push {-u | --set-upstream} <remote> <branch_name>`: Publica la branca actual i estableix el nom de la branca remota.
- `git push -d <remote> <branch_name>`: Elimina la branca remota amb el nom especificat.
### Fusionar branques
- `git merge <branch name>`: Fusiona i incorpora els canvis de la branca especificada a la branca actual (on està situal el `HEAD`).
- Si la fusió és _fast forward_, es produirà sense necessitat de cap acció més.
- Si la fusió no és _fast forward_, caldrà especificar el missatge del _merge commit_.
- Si hi ha conflictes, caldrà resoldre'ls.
- Opció `--abort`: Aborta la fusió que s'està produint.
- `git rebase <branch name>`: Mou la base de la branca actual (`HEAD`) a la branca especificada.
- Si hi ha conflictes, caldrà resoldre'ls.
- Opció `--continue`: Continua amb el canvi de base una vegada s'hagen resolt els conflictes.
- Opció `--abort`: Aborta el canvi de base que s'està produint.