Portem sis mòduls ajornant aquesta lliçó. A la 03-02 vam dir que el reflog explica com Git recorda per on ha passat HEAD. A la 03-06 vam prometre que esborrar una branca amb -D gairebé mai no és irreversible, i vam remetre aquí. A la 05-01 vam dir que un rebase desastrós es pot desfer, i vam remetre aquí. A la 05-04, que un stash drop accidental és recuperable. A la 09-02, que els commits que un reset --hard deixa enrere continuen allà. I a la 09-03, que origin/main@{1} guarda on era el servidor abans de la reescriptura.
Totes aquestes promeses s'aguanten sobre la mateixa peça, i és hora de desenvolupar-la sencera.
El reflog és probablement la funcionalitat de Git amb millor relació entre el que salva i el poc que es coneix. Molta gent porta anys fent servir Git sense haver-lo executat mai, i és exactament l'ordre que converteix «he perdut tres dies de feina» en «he trigat dos minuts a recuperar-ho».
Comencem pel més important: si has arribat aquí en pànic, no has perdut res, sempre que allò que busques arribés a ser un commit. Continua llegint amb calma.
Contingut
- Què és el reflog i on viu
- Local i temporal: els dos límits que cal conèixer
- Llegir
git reflog HEAD@{n}davant deHEAD@{temps}- El patró universal de recuperació
- Receptari:
reset --hard, branca esborrada, rebase, merge,--amend - Quan el reflog no n'hi ha prou:
git fsck --lost-found - Recuperar un desament temporal eliminat
- Els límits reals: el que no es pot recuperar
- Higiene: no destruir la teva pròpia xarxa de seguretat
- Què és el reflog i on viu
El reflog és el registre local de tots els moviments de cada referència.
Cada vegada que una referència —HEAD, una branca, una branca de seguiment remota— canvia de valor, Git escriu una línia en un fitxer de text anotant d'on venia, on va, qui ho ha fet i per què.
Mira-t'ho directament:
4f8a2e6c9b1d5e3a b52c9d1e4a7f3c8b Ana Ferrer <[email protected]> 1785312041 +0200 commit: GT-241 base del filtre b52c9d1e4a7f3c8b 7d3a8f4a2c6e9b1d Ana Ferrer <[email protected]> 1785312388 +0200 commit: GT-241 calcula el comptador 7d3a8f4a2c6e9b1d 4f8a2e6c9b1d5e3a Ana Ferrer <[email protected]> 1785312551 +0200 reset: moving to HEAD~2
Cada línia té: hash anterior, hash nou, identitat, marca de temps, i descripció de l'operació. És text pla, sense màgia.
L'estructura de directoris:
.git/logs/HEAD .git/logs/refs/heads/main .git/logs/refs/heads/GT-241 .git/logs/refs/remotes/origin/main .git/logs/refs/stash
| Fitxer | Registra els moviments de |
|---|---|
.git/logs/HEAD |
HEAD: tot el que has fet, inclosos els canvis de branca |
.git/logs/refs/heads/<branca> |
Només aquella branca |
.git/logs/refs/remotes/origin/<branca> |
La branca de seguiment: el que va portar cada fetch (09-03) |
.git/logs/refs/stash |
La pila de desaments temporals (05-04) |
I aquí hi ha la clau de tot el mòdul. Recupera la idea de la lliçó 09-01:
Un commit sobreviu mentre alguna cosa hi arribi. Les entrades del reflog compten com a referències.
Per això git gc no elimina un commit que apareix al reflog, encara que cap branca no l'apunti. El reflog no és només un registre: és el que manté vius els objectes orfes. Aquesta és la raó tècnica que la recuperació funcioni.
flowchart LR
subgraph refs["Referències que mantenen viu un commit"]
R1["Branques<br/>refs/heads/*"]
R2["Etiquetes<br/>refs/tags/*"]
R3["Branques remotes<br/>refs/remotes/*"]
R4["Desament temporal<br/>refs/stash"]
R5["REFLOG<br/>.git/logs/*"]
end
C["commit b52c9d1"]
R1 -.-> C
R5 ==>|"encara que les altres<br/>desapareguin"| C
- Local i temporal: els dos límits que cal conèixer
Abans del receptari, les dues limitacions. No entendre-les és el que fa que algú confiï en el reflog quan no ha de fer-ho.
És LOCAL
El reflog no viatja. No es publica amb push, no es baixa amb fetch, i un git clone no el porta.
Una sola entrada. Tot l'historial de moviments que l'Ana tenia a la seva màquina es queda a la seva màquina.
Tres conseqüències pràctiques:
- El reflog de l'Ana no pot rescatar el desastre del Bruno. Cadascú té el seu.
- El reflog no és una còpia de seguretat. Si el disc mor, mor amb ell. Les còpies de seguretat reals són
git bundlei els mateixos clons de l'equip (lliçó 09-05). - Un clon acabat de fer no té xarxa de seguretat. El primer
reset --harddesafortunat en un clon nou sí que et pot deixar sense res a recuperar, perquè no hi ha entrades anteriors.
I una conseqüència positiva, la de l'apartat 9 de la lliçó 09-03: si un company força i destrueix una branca del servidor, el teu reflog d'origin/branca conserva on era, i amb ell es restaura.
És TEMPORAL
Les entrades caduquen. Dos paràmetres ho governen:
git config --get gc.reflogExpire # per defecte: 90 dies
git config --get gc.reflogExpireUnreachable # per defecte: 30 dies| Paràmetre | S'aplica a | Valor per defecte |
|---|---|---|
gc.reflogExpire |
Entrades el commit de les quals continua sent assolible | 90 dies |
gc.reflogExpireUnreachable |
Entrades el commit de les quals ja no és assolible des de cap branca | 30 dies |
La segona és la que importa: els commits realment orfes tenen 30 dies. Després, un git gc els purga definitivament.
La caducitat no passa sola: l'executa git gc (lliçó 08-06), que Git llança automàticament quan s'acumulen objectes solts. A la pràctica, tens setmanes, no mesos, i encara menys anys.
Pots allargar el termini:
# Un any per a tot, als teus repositoris de treball
git config --global gc.reflogExpire "1 year"
git config --global gc.reflogExpireUnreachable "1 year"
# O per branca, amb un patró
git config gc.refs/heads/main.reflogExpire neverCosta uns quants megabytes i compra molta tranquil·litat.
I el contrari, que mai no has d'executar tret que sàpigues exactament què fas (lliçó 08-06):
# DESTRUEIX la xarxa de seguretat de tot aquest mòdul
git reflog expire --expire=now --all
git gc --prune=now
- Llegir
git reflog
git reflog7d3a8f4 HEAD@{0}: reset: moving to HEAD~2
9c4e7b2 HEAD@{1}: commit: GT-241 estils de l'indicador
3e7f1a8 HEAD@{2}: commit: GT-241 calcula el comptador
8a1f6c3 HEAD@{3}: rebase (finish): returning to refs/heads/GT-241
8a1f6c3 HEAD@{4}: rebase (pick): GT-241 base del filtre
2f8c6e1 HEAD@{5}: rebase (start): checkout origin/main
b52c9d1 HEAD@{6}: checkout: moving from main to GT-241
7d3a8f4 HEAD@{7}: pull: Fast-forward
4f8a2e6 HEAD@{8}: commit: chore: configuració d'eslintCom es llegeix:
HEAD@{0}és sempre l'última cosa que ha passat. L'ordre va del present cap al passat.- El hash de cada línia és on va quedar
HEADDESPRÉS d'aquella operació. Aquest detall és crucial i produeix l'error més freqüent: si vols l'estat anterior a l'operació deHEAD@{0}, necessites el hash deHEAD@{1}. - La descripció diu quina ordre ho ha provocat.
El vocabulari de les descripcions:
| Descripció | Què l'ha produïda |
|---|---|
commit: |
git commit |
commit (amend): |
git commit --amend |
commit (initial): |
El primer commit del repositori |
checkout: moving from X to Y |
git switch o git checkout |
reset: moving to X |
git reset |
pull: / merge X: |
Una integració |
rebase (start/pick/finish): |
Les fases d'un rebase |
cherry-pick: |
git cherry-pick |
revert: |
git revert |
branch: Created from X |
git branch o git switch -c |
clone: from X |
El clon inicial |
fetch: forced-update |
Algú ha reescrit la branca remota (09-03) |
El reflog d'una branca concreta
9c4e7b2 GT-241@{0}: commit: GT-241 estils de l'indicador
3e7f1a8 GT-241@{1}: commit: GT-241 calcula el comptador
8a1f6c3 GT-241@{2}: rebase (finish): refs/heads/GT-241 onto 2f8c6e1
b52c9d1 GT-241@{3}: branch: Created from HEADMolt més net que el de HEAD quan saps quina branca t'interessa, perquè no inclou els canvis de branca.
Formats útils
# Amb dates relatives: imprescindible per orientar-se
git reflog --date=relative -10
# Amb data i hora exactes
git reflog --date=iso -10
# Amb el missatge del commit a més de l'operació
git reflog --format='%h %gd %gs | %s' -10
# Només el d'una branca, amb gràfic
git log --walk-reflogs --oneline GT-2417d3a8f4 HEAD@{fa 3 minuts}: reset: moving to HEAD~2
9c4e7b2 HEAD@{fa 41 minuts}: commit: GT-241 estils de l'indicador
3e7f1a8 HEAD@{fa 2 hores}: commit: GT-241 calcula el comptador--date=relative és el que més ajuda en una recuperació: «ho tenia just abans de dinar» es tradueix directament a una entrada.
I git log -g (o --walk-reflogs), que recorre el reflog mostrant cada entrada com un commit complet:
Útil quan no reconeixes un commit pel seu missatge i necessites veure quins fitxers tocava.
HEAD@{n} davant de HEAD@{temps}
HEAD@{n} davant de HEAD@{temps}Dues sintaxis que s'assemblen i signifiquen coses diferents.
| Sintaxi | Què és | Exemple |
|---|---|---|
HEAD@{2} |
L'entrada número 2 del reflog (comptant des de 0) | Dues operacions enrere |
HEAD@{2.hours.ago} |
On era HEAD fa dues hores |
Segons el rellotge |
HEAD~2 |
Dos commits enrere al graf | Recorre pares, no reflog |
HEAD^2 |
El segon pare (només en fusions) | L'altra branca de la fusió |
main@{5} |
Cinquena entrada del reflog de main |
— |
main@{yesterday} |
On era main ahir |
— |
origin/main@{1} |
On era la branca remota abans de l'últim fetch | 09-03 |
@{-1} |
La branca anterior on has estat | El que fa servir git switch - |
La distinció crítica, i mereix un exemple:
git log --oneline HEAD~3 -1 # tres commits enrere a la història
git log --oneline HEAD@{3} -1 # on era HEAD fa tres operacionsHEAD~3 recorre el graf: segueix la cadena de pares. HEAD@{3} recorre la teva història personal: pot ser en una altra branca, en un commit orfe, en qualsevol lloc on hagis estat.
Quan has fet un reset, HEAD~1 et porta al pare del commit actual (que ja no és el que buscaves) i HEAD@{1} et porta on eres abans del reset (que sí que ho és).
Les formes temporals accepten expressions molt naturals:
git log --oneline main@{yesterday} -3
git log --oneline main@{"1 week ago"} -3
git log --oneline main@{2026-07-28.09:00:00} -3
git diff main@{1.day.ago} mainI l'avís que dona Git quan et passes de termini:
No és un error: t'està dient que ha fet servir l'entrada més antiga disponible. Si la data que has demanat és anterior, el resultat no és el que et penses.
- El patró universal de recuperació
Totes les receptes de l'apartat següent són el mateix procediment. Aprèn-te'l una vegada.
flowchart TD
A["1. git reflog (o git reflog show branca)"] --> B["2. Localitzar l'entrada:<br/>fer servir la descripció i --date=relative"]
B --> C["3. VERIFICAR el candidat:<br/>git show hash --stat<br/>git log --oneline hash -5"]
C --> D{"És el que buscava?"}
D -->|No| B
D -->|Sí| E["4. git branch rescat hash"]
E --> F["5. Comprovar-ho a la branca nova"]
F --> G["6. Integrar: merge, cherry-pick,<br/>o reset --hard si n'estàs segur"]
El pas 4 és el que cal interioritzar, i és la diferència entre una recuperació tranquil·la i un segon ensurt:
# BÉ: crea un punter nou. No mou res del que ja tens
git branch rescat 9c4e7b2
# PITJOR: mou la teva branca actual, i si t'equivoques de hash perds de vista el d'ara
git reset --hard 9c4e7b2git branch és purament additiu. Si el hash era l'equivocat, esborres la branca i en proves un altre. No s'ha mogut res. Amb reset --hard cada intent fallit afegeix una capa més de confusió.
I el pas 3, verificar, evita l'error de recuperar el commit equivocat:
git show 9c4e7b2 --stat # quins fitxers tocava?
git log --oneline 9c4e7b2 -5 # quina història té al darrere?
git diff HEAD 9c4e7b2 --stat # en què es diferencia del que tinc ara?I per inspeccionar sense comprometre't a res:
git switch --detach 9c4e7b2 # mirar el projecte en aquell estat
# ...obrir fitxers, executar l'aplicació...
git switch - # tornar
- Receptari:
reset --hard, branca esborrada, rebase, merge, --amend
reset --hard, branca esborrada, rebase, merge, --amend6.1. Desfer un git reset --hard
La situació. L'Ana volia treure un commit i va escriure HEAD~3.
No has perdut res (tret del que estigués sense confirmar, lliçó 09-02).
4f8a2e6 HEAD@{0}: reset: moving to HEAD~3
9c4e7b2 HEAD@{1}: commit: GT-241 estils de l'indicador
3e7f1a8 HEAD@{2}: commit: GT-241 calcula el comptador
8a1f6c3 HEAD@{3}: commit: GT-241 base del filtre
2f8c6e1 HEAD@{4}: checkout: moving from main to GT-241HEAD@{1} (9c4e7b2) és la punta que hi havia just abans del reset.
git show 9c4e7b2 --stat # verificar
git branch rescat-GT-241 9c4e7b2
git log --oneline rescat-GT-241 -49c4e7b2 (rescat-GT-241) GT-241 estils de l'indicador 3e7f1a8 GT-241 calcula el comptador 8a1f6c3 GT-241 base del filtre 2f8c6e1 chore: configuració d'eslint
Recuperat. Ara, si vols que GT-241 torni a ser això:
La drecera, si acabes de fer-ho i no has fet res més (lliçó 09-02):
O directament amb la sintaxi del reflog:
6.2. Recuperar una branca esborrada amb -D
Això tanca la promesa de la lliçó 03-06.
Primer regal: Git imprimeix el hash en esborrar. Si el tens al buffer del terminal, la recuperació és immediata:
Si has tancat el terminal, hi ha dos camins.
A. El reflog de HEAD (funciona si vas estar en aquella branca):
b52c9d1 HEAD@{fa 3 hores}: checkout: moving from GT-247 to main
b52c9d1 HEAD@{fa 3 hores}: commit: GT-247 valida el formulariB. Buscar per missatge entre tots els commits orfes (funciona sempre):
O directament sobre la base d'objectes:
I el detall important que s'oblida: el reflog de la branca mateixa s'esborra amb ella.
.git/logs/refs/heads/GT-247 ja no existeix. Per això cal buscar al reflog de HEAD, que sí que sobreviu.
-Dgairebé mai no és irreversible. Els commits continuen a.git/objects, assolibles des del reflog deHEAD, durant almenys 30 dies. La promesa de la lliçó 03-06 queda complerta.
I l'excepció, per ser honestos: si la branca es va crear, se li van fer commits i es va esborrar sense que HEAD hi passés mai (per exemple, amb git branch X <hash> i després git branch -D X), el reflog de HEAD no la registra. En aquest cas, git fsck de l'apartat 7.
6.3. Rescatar un rebase que ha sortit malament
Això tanca la promesa de la lliçó 05-01.
El Bruno ha fet un rebase -i de deu commits, ha aixafat els que no havia d'aixafar i ha acabat amb --continue.
4b8e2c9 HEAD@{0}: rebase (finish): returning to refs/heads/GT-241
4b8e2c9 HEAD@{1}: rebase (squash): GT-241 el filtre complet
8f2d6a1 HEAD@{2}: rebase (squash): GT-241 base del filtre
6e2b9c7 HEAD@{3}: rebase (pick): GT-241 base del filtre
2f8c6e1 HEAD@{4}: rebase (start): checkout origin/main
9c4e7b2 HEAD@{5}: checkout: moving from main to GT-241L'entrada clau és rebase (start): l'anterior a ella és l'estat exacte previ al rebase. Aquí, HEAD@{5} → 9c4e7b2.
Els deu commits originals, intactes.
Una drecera que gairebé ningú no coneix: durant un rebase, Git desa la posició inicial a ORIG_HEAD, i també en una referència especial:
git rev-parse ORIG_HEAD
cat .git/rebase-merge/orig-head 2>/dev/null # només mentre el rebase està en marxaI si el rebase encara no ha acabat, la sortida és molt més simple:
Torna tot exactament a l'estat previ. Fes-lo servir sempre que puguis: és més net que recuperar després.
Per comparar el resultat amb l'original i decidir què fer, git range-diff (lliçó 07-02):
6.4. Desfer un merge que no havies d'haver fet
Si acabes de fer-lo i no hi ha res a sobre:
merge sempre escriu ORIG_HEAD abans de fusionar. És la sortida canònica.
Si ja has fet més coses a sobre:
c7e2a91 HEAD@{0}: commit: GT-241 ajusta el comptador
2b9e6c1 HEAD@{1}: merge funcionalitat/experimental: Merge made by the 'ort' strategy.
7d3a8f4 HEAD@{2}: commit: GT-241 estils de l'indicadorHEAD@{2} és l'estat previ a la fusió. Però compte: si hi tornes, perds també el commit c7e2a91 que has fet després. El correcte és rescatar-lo a part:
git branch abans-del-merge 7d3a8f4
git switch abans-del-merge
git cherry-pick c7e2a91 # portar només el commit bo (lliçó 05-03)I si el merge ja està publicat, res de reflog: la resposta és git revert -m 1 (lliçó 05-06).
Un cas freqüent i desconcertant: git merge --abort no funciona perquè la fusió va acabar bé; només era mala idea. --abort serveix mentre hi ha conflictes sense resoldre, no després.
6.5. Recuperar un commit sobreescrit per --amend
La Carla ha fet git commit --amend i s'ha adonat que ha perdut part del missatge original —o pitjor, que el commit anterior tenia canvis que el nou no té.
No has perdut res. --amend no modifica el commit: en crea un de nou i mou la branca (lliçó 09-01). L'original continua a la base de dades.
3f8a1d6 HEAD@{0}: commit (amend): GT-241 calcula el comptador sobre la llista completa
8f4c2a9 HEAD@{1}: commit: GT-241 calcula el comptador
b52c9d1 HEAD@{2}: commit: GT-241 base del filtreHEAD@{1} (8f4c2a9) és el commit original, abans de l'--amend.
# Veure el missatge original complet
git show 8f4c2a9 --stat
git log -1 --format=%B 8f4c2a9
# Comparar els dos
git diff 8f4c2a9 3f8a1d6I les maneres de recuperar, segons el que necessitis:
# A. Tornar del tot a l'original
git reset --hard 8f4c2a9
# B. Recuperar només el missatge
git commit --amend -m "$(git log -1 --format=%B 8f4c2a9)"
# C. Recuperar un fitxer concret que s'ha perdut a l'amend
git restore --source=8f4c2a9 --staged --worktree app.js
# D. Veure què s'ha perdut exactament
git diff 3f8a1d6 8f4c2a96.6. Recuperar després d'un checkout a una altra branca amb commits en detached HEAD
Reprenent l'apartat 5.7 de la lliçó 09-01: has fet commits en HEAD desacoblat i te n'has anat.
7d3a8f4 HEAD@{0}: checkout: moving from 9c4e7b2 to main
9c4e7b2 HEAD@{1}: commit: prova de l'algorisme alternatiu
3e7f1a8 HEAD@{2}: commit: esbós del filtre per data
4f8a2e6 HEAD@{3}: checkout: moving from main to 4f8a2e6La línia checkout: moving from 9c4e7b2 to main et dona el hash d'on vas sortir.
La taula de referència ràpida
| Desastre | On mirar | Ordre de rescat |
|---|---|---|
reset --hard de més |
git reflog -5, entrada anterior al reset: |
git branch rescat HEAD@{1} |
Branca esborrada amb -D |
El hash que ha imprès -D, o git reflog | grep <branca> |
git branch <branca> <hash> |
| Rebase desastrós | Entrada anterior a rebase (start) |
git branch abans 9c4e7b2 / git rebase --abort si continua en marxa |
| Merge no desitjat | ORIG_HEAD, o entrada anterior al merge |
git reset --hard ORIG_HEAD |
--amend que se n'ha endut alguna cosa |
Entrada commit: anterior a commit (amend): |
git restore --source=<hash> <fitxer> |
| Commits en HEAD desacoblat | checkout: moving from <hash> to <branca> |
git branch <nom> <hash> |
| Branca remota reescrita per un altre | git reflog show origin/<branca> |
git branch antiga origin/<branca>@{1} |
| Desament temporal eliminat | git fsck --unreachable | grep commit |
Apartat 8 |
| No apareix res al reflog | git fsck --lost-found |
Apartat 7 |
- Quan el reflog no n'hi ha prou:
git fsck --lost-found
git fsck --lost-foundEl reflog registra els moviments de referències. Hi ha objectes que arriben a la base de dades sense que cap referència es mogui, i per a aquests cal l'altra eina.
Checking object directories: 100% (256/256), done. dangling commit 9c4e7b2e4a7f3c8b6d2e9a5f1c7b3d8e4a6f2c9b dangling commit 3e7f1a8b6d2e9a5f1c7b3d8e4a6f2c9b7d3a8f4a dangling blob 6f2b9d4a8c1e5f3b7d9a2c6e4f8b1d3a5c7e9f2b dangling tree 8a1f6c3d5e2b9c7f4a6d1e8b3c5f7a9d2e4b6c8a
I a més crea un directori amb enllaços:
Què és cada cosa
| Tipus | Què és | Per què apareix |
|---|---|---|
| dangling commit | Un commit al qual no arriba cap referència | reset, branca esborrada, rebase, --amend, desament temporal eliminat |
| dangling blob | Contingut d'un fitxer sense arbre que el referenciï | Un git add el commit del qual mai no es va arribar a fer |
| dangling tree | Un directori sense commit que el faci servir | Un commit a mitges, o l'arbre d'un desament temporal |
| unreachable X | Igual, però comptant el reflog | Amb --unreachable també es veuen els del reflog |
dangling és normal i inofensiu. No és un símptoma de corrupció. És el que s'espera en qualsevol repositori actiu. La distinció entre això i els errors de debò (missing, broken link) és la lliçó 09-05.
Com inspeccionar els candidats
Un fsck pot tornar desenes de línies. La feina és identificar quin és el teu.
# Els commits penjants, amb data, autor i missatge, ordenats per data
git fsck --lost-found --no-progress 2>/dev/null \
| awk '/dangling commit/ {print $3}' \
| xargs -I{} git log -1 --format='%ci %h %an %s' {} \
| sort -r2026-07-30 18:22:41 +0200 9c4e7b2 Ana Ferrer GT-241 estils de l'indicador 2026-07-30 17:51:03 +0200 3e7f1a8 Ana Ferrer GT-241 calcula el comptador 2026-07-28 11:04:17 +0200 8a1f6c3 Bruno Salas WIP a GT-238
Això converteix una llista de hashos en informació utilitzable. Desa-ho com a àlies:
git config --global alias.perduts '!git fsck --lost-found --no-progress 2>/dev/null | awk "/dangling commit/ {print \$3}" | xargs -I{} git log -1 --format="%ci %h %an %s" {} | sort -r'Inspecció individual, amb les eines de lampisteria de la lliçó 01-04:
tree 8a1f6c3d5e2b9c7f4a6d1e8b3c5f7a9d2e4b6c8a parent 2f8c6e1a4b7d9c3e5f2a8b6d1c9e4f7a3b5d2c8e author Ana Ferrer <[email protected]> 1785312041 +0200 committer Ana Ferrer <[email protected]> 1785312041 +0200 GT-241 estils de l'indicador de pendents
# El diff complet
git show 9c4e7b2
# Només els fitxers
git show --stat 9c4e7b2
# Què contenia un blob penjant
git cat-file -p 6f2b9d4 | head -20
# De quin tipus és un objecte qualsevol
git cat-file -t 8a1f6c3Els blobs penjants: l'add que mai no es va confirmar
Aquest és el cas que salva més feina del que la gent espera. Si vas preparar un fitxer amb git add i després el vas perdre, el contingut és a la base de dades (lliçó 09-01, taula de l'apartat 1).
# Buscar entre els blobs penjants el que contingui una cadena que recordis
for b in $(git fsck --lost-found --no-progress 2>/dev/null | awk '/dangling blob/ {print $3}'); do
if git cat-file -p "$b" 2>/dev/null | grep -q "calculaPendents"; then
echo "=== $b ==="
git cat-file -p "$b" | head -5
fi
done=== 6f2b9d4a8c1e5f3b7d9a2c6e4f8b1d3a5c7e9f2b ===
function calculaPendents(tasques) {
return tasques.filter(t => !t.completada).length;
}Buscar per una cadena que recordis és molt més eficaç que revisar els blobs un a un.
- Recuperar un desament temporal eliminat
Això tanca la promesa de la lliçó 05-04.
Primer regal, un altre cop: drop imprimeix el hash. Amb ell:
I si va ser un git stash clear, que esborra tota la pila sense imprimir res, hi ha dos camins.
A. El reflog del desament temporal, si encara existeix:
stash clear esborra la referència, però el fitxer de log a vegades sobreviu fins al següent gc. Val la pena mirar-lo primer.
B. Buscar els commits del desament temporal entre els inassolibles:
git fsck --unreachable --no-progress | grep commit | awk '{print $3}' \
| xargs -I{} git log -1 --format='%h %ci %s' {} \
| grep -i "WIP on\|On .*:"b52c9d1 2026-07-30 16:12:44 +0200 WIP on GT-241: 7d3a8f4 GT-241 base del filtre 8f4c2a9 2026-07-29 09:31:20 +0200 On main: proves del comptador
Els desaments temporals es reconeixen pel seu missatge: WIP on <branca>: (els automàtics) o On <branca>: <missatge> (els que has creat amb -m).
Un desament temporal és internament un commit de fusió amb dos o tres pares, i val la pena veure-ho perquè explica com funciona:
| Pare | Què conté |
|---|---|
1r (7d3a8f4) |
El HEAD en el moment del desament |
2n (4f8a2e6) |
L'índex (el que estava preparat) |
3r (9c4e7b2) |
Els fitxers sense seguiment, si vas fer servir -u |
I la recuperació:
# Aplicar-lo directament
git stash apply b52c9d1
# O tornar-lo a la pila per tractar-lo amb normalitat
git stash store -m "recuperat: GT-241 a mitges" b52c9d1
git stash list# Veure què contenia sense aplicar-lo
git show b52c9d1 # els canvis del directori de treball
git show b52c9d1^2 # el que estava preparat
git show b52c9d1^3 # els fitxers sense seguiment (si n'hi ha)
- Els límits reals: el que no es pot recuperar
Toca ser honestos. Hi ha dues fronteres que cap tècnica d'aquesta lliçó no travessa.
Frontera 1: el que mai no va entrar a la base de dades
Ja ho vam veure a la lliçó 09-01, i és la limitació fonamental:
| Situació | Recuperable? |
|---|---|
| Un commit, encara que la branca s'esborrés | Sí |
Un git add sense confirmar |
Sí: hi ha blob |
| Un desament temporal, fins i tot eliminat | Sí: són commits |
Un fitxer modificat i destruït amb git restore |
No |
Un fitxer destruït per reset --hard sense add previ |
No |
Un fitxer sense seguiment esborrat per git clean |
No |
Quan ets en un dels tres últims casos, Git ja no et pot ajudar. El que queda és fora de Git:
1. L'historial local del teu editor. És la via que més vegades funciona i la que menys es prova.
- VS Code: paleta d'ordres → «Local History: Find Entry to Restore». Desa versions de cada fitxer que has editat, independentment de Git.
- IntelliJ / WebStorm / Eclipse: menú contextual del fitxer → Local History → Show History. Desa setmanes.
- Vim: si tens
set undofile, l'historial de desfer persisteix entre sessions (:earlier 1h).
2. Còpies de seguretat del sistema: Time Machine a macOS, instantànies de Btrfs/ZFS, versions anteriors a Windows, còpies al núvol.
3. Buscar a /tmp i als fitxers d'intercanvi de l'editor (.swp de Vim, ~ d'altres).
Frontera 2: el que ja ha passat per gc
Si es va executar git gc --prune=now després que el commit quedés orfe, l'objecte ha desaparegut físicament. Si a més es va executar git reflog expire --expire=now --all, no en queda ni registre.
Comprova si encara hi és abans de rendir-te:
Aquest missatge significa que l'objecte ja no existeix. Però abans de donar-lo per perdut, mira fora de la teva màquina:
# El té el servidor?
git fetch origin '+refs/*:refs/remotes/copia/*'
git log --all --oneline | grep -i "GT-241"
# El té un company? (el seu clon és una còpia gairebé completa)
git remote add bruno /ruta/o/url/al/clon/del/bruno
git fetch bruno
git log --oneline bruno/GT-241Aquesta és la xarxa de seguretat del model distribuït, i és el tema central de la lliçó 09-05.
I la prevenció, que és el que de debò resol això
# 1. Confirma aviat i sovint. Un "wip" cada mitja hora ho canvia tot.
git commit -am "wip"
# 2. Abans de qualsevol operació arriscada, un marcador. Costa dos segons.
git branch copia-$(date +%H%M)
# 3. Abans de netejar, un desament temporal amb els fitxers sense seguiment inclosos
git stash push -u -m "per si de cas"
# 4. Allarga el reflog als teus repositoris de treball
git config --global gc.reflogExpire "1 year"
git config --global gc.reflogExpireUnreachable "1 year"
# 5. Publica les teves branques, encara que estiguin a mitges
git push -u origin GT-241La cinquena és la més infravalorada. Una branca publicada és a dues màquines. Cap accident local no hi pot fer res.
- Higiene: no destruir la teva pròpia xarxa de seguretat
Tanca la lliçó el que no s'ha de fer.
1. git reflog expire --expire=now --all. Buida el registre. Tot el que és orfe queda desprotegit.
2. git gc --prune=now. Elimina immediatament els objectes inassolibles. Té el seu ús legítim (després d'un filter-repo de la lliçó 08-05, on esborrar és justament l'objectiu), i cap en un dia normal.
3. Confiar en el reflog com a còpia de seguretat. És local, temporal i mor amb el disc. No és una còpia de seguretat.
4. Recuperar amb reset --hard en lloc de git branch. Cada intent fallit afegeix confusió. branch no mou res.
5. Treballar mesos sense publicar una branca. Un clon nou té el reflog buit; una branca sense publicar existeix en un sol disc.
I una comprovació de salut de trenta segons, per saber si la teva xarxa de seguretat és on et penses:
echo "Entrades al reflog de HEAD: $(git reflog | wc -l)"
echo "Entrada més antiga: $(git reflog --date=iso | tail -1)"
echo "reflogExpire: $(git config --get gc.reflogExpire || echo '90 dies (per defecte)')"
echo "reflogExpireUnreachable: $(git config --get gc.reflogExpireUnreachable || echo '30 dies (per defecte)')"
echo "Objectes penjants: $(git fsck --lost-found --no-progress 2>/dev/null | grep -c dangling)"
echo "Branques sense publicar: $(git for-each-ref --format='%(refname:short) %(upstream)' refs/heads | awk '$2==""{print $1}' | tr '\n' ' ')"Errors Habituals i Consells
Error 1: no provar git reflog. És la primera ordre davant de qualsevol «he perdut commits», i la majoria de la gent no l'executa mai.
Error 2: confondre HEAD@{1} amb HEAD~1. El primer és on eres fa una operació; el segon és el commit pare. Després d'un reset, són coses completament diferents.
Error 3: agafar el hash de l'entrada equivocada. El hash d'una línia és on va quedar HEAD després d'aquella operació. Per a l'estat previ a HEAD@{0}, necessites HEAD@{1}.
Error 4: recuperar amb reset --hard en lloc de git branch. Si el hash era l'equivocat, amb branch esborres la branca i en proves una altra; amb reset cada intent complica més l'estat.
Error 5: creure que el reflog viatja en un clone. No viatja. El clon nou té una sola entrada i cap xarxa de seguretat.
Error 6: confiar en el reflog per sempre. 90 dies per al que és assolible, 30 per al que és orfe, i gc els aplica. A la pràctica, setmanes.
Error 7: espantar-se amb els dangling de git fsck. Són normals en qualsevol repositori actiu. El greu és missing i broken link (lliçó 09-05).
Error 8: donar per perdut un desament temporal. stash drop imprimeix el hash, stash clear deixa els commits orfes, i tots dos es recuperen amb git fsck --unreachable buscant WIP on.
Error 9: rendir-se sense mirar fora de Git. L'historial local de l'editor recupera el que Git no pot, i gairebé ningú no ho prova.
Consell 1: el patró és sempre el mateix. Reflog → verificar amb git show → git branch rescat <hash>.
Consell 2: git reflog --date=relative. «Ho tenia abans de dinar» es tradueix directament a una entrada.
Consell 3: defineix l'àlies git perduts. El dia que el necessitis no recordaràs la canonada de fsck i awk.
Consell 4: git rebase --abort mentre puguis. Molt més net que recuperar després.
Consell 5: allarga el reflog a un any. Dues línies de configuració global i uns quants megabytes.
Consell 6: publica les teves branques. Una branca en dues màquines és immune als accidents d'una.
Exercicis
Exercici 1: el receptari complet
Sobre un repositori de proves amb app.js, estils.css i index.html:
- Crea sis commits a
maini una brancaGT-241amb tres commits propis. - Provoca quatre desastres seguits, sense recuperar entre l'un i l'altre:
a.
git reset --hard HEAD~2aGT-241. b.git switch main && git branch -D GT-241. c. Ungit commit --amendamainque esborri part del missatge. d. Ungit merged'una branca experimental que no volies. - Executa
git reflog --date=relativei anota, per a cada desastre, quina entrada faries servir. - Recupera les quatre coses fent servir sempre
git branch, maireset. - Verifica cada recuperació amb
git show --statigit diff.
Exercici 2: els límits de la recuperació
- En un repositori nou, crea tres situacions: un commit, un fitxer preparat amb
git add, i un fitxer modificat només al disc. - Executa
git reset --hard HEAD~1. - Recupera el commit amb el reflog i el fitxer preparat amb
git fsck --lost-found+git cat-file -p. - Documenta per què el tercer és irrecuperable, comprovant-ho amb
git fsckigit reflog. - Crea un desament temporal amb
-u, elimina'l ambgit stash cleari recupera'l ambgit fsck --unreachable. - Comprova amb
git show --format='%p' -sque el desament té tres pares i inspecciona'n cadascun.
Exercici 3: la caducitat i la higiene
- Crea un repositori amb deu commits i provoca cinc commits orfes amb
reset. - Comprova que apareixen a
git fsck --lost-found. - Executa
git reflog expire --expire=now --alli torna a mirargit reflogigit fsck. Explica la diferència entre les dues sortides. - Executa
git gc --prune=nowi comprova ambgit cat-file -t <hash>que els objectes han desaparegut de debò. - Repeteix l'experiment configurant abans
gc.reflogExpireUnreachable "1 year"i explica què canvia. - Escriu la comprovació de salut de l'apartat 10 en un guió i interpreta'n la sortida en un repositori real teu.
Solucions
Solució 1:
rm -rf /tmp/p9-04 && mkdir /tmp/p9-04 && cd /tmp/p9-04 && git init -q -b main
git config user.name "Ana Ferrer"; git config user.email "[email protected]"
for i in 1 2 3 4 5 6; do echo "linia $i" >> app.js; git add .; git commit -q -m "chore: commit $i"; done
git switch -q -c GT-241
echo "// filtre" > filtre.js && git add . && git commit -q -m "GT-241 base del filtre"
echo "// comptador" >> filtre.js && git commit -q -am "GT-241 calcula el comptador"
echo ".pendent{}" > estils.css && git add . && git commit -q -m "GT-241 estils de l'indicador"
git rev-parse --short HEAD# 2a. reset --hard
git reset -q --hard HEAD~2
# 2b. esborrar la branca
git switch -q main
git branch -D GT-241# 2c. amend destructiu
git commit -q --amend -m "chore"
# 2d. merge no desitjat
git switch -q -c experimental HEAD~1
echo "experiment" > experiment.txt && git add . && git commit -q -m "experiment que no val"
git switch -q main
git merge -q --no-ff experimental -m "Merge experimental"
git log --oneline -3c7e2a91 (HEAD -> main) Merge experimental 2b9e6c1 (experimental) experiment que no val 3f8a1d6 chore
c7e2a91 HEAD@{fa 4 segons}: merge experimental: Merge made by the 'ort' strategy.
3f8a1d6 HEAD@{fa 12 segons}: checkout: moving from experimental to main
2b9e6c1 HEAD@{fa 18 segons}: commit: experiment que no val
7d3a8f4 HEAD@{fa 25 segons}: checkout: moving from main to experimental
3f8a1d6 HEAD@{fa 33 segons}: commit (amend): chore
8f4c2a9 HEAD@{fa 40 segons}: checkout: moving from GT-241 to main
6e2b9c7 HEAD@{fa 48 segons}: reset: moving to HEAD~2
9c4e7b2 HEAD@{fa 55 segons}: commit: GT-241 estils de l'indicador| Desastre | Entrada a fer servir | Hash |
|---|---|---|
a. reset --hard |
L'anterior al reset: |
9c4e7b2 |
b. branch -D |
El hash imprès, o el checkout: moving from GT-241 |
8a1f6c3 (el que va imprimir -D) |
c. --amend |
La commit: anterior a commit (amend): |
8f4c2a9 |
d. merge |
L'anterior al merge, o ORIG_HEAD |
3f8a1d6 |
Fixa't en el matís de (b): després del reset --hard, GT-241 apuntava a 6e2b9c7, i això és el que va esborrar -D (8a1f6c3 a l'exemple del missatge). Però el que l'Ana vol és l'estat previ al reset, 9c4e7b2. El reflog els conserva tots dos.
# 4. Recuperar, sempre amb branch
git branch rescat-GT-241-completa 9c4e7b2
git branch rescat-amend 8f4c2a9
git branch rescat-abans-merge 3f8a1d6
git branchCap d'aquestes operacions no ha mogut main. Tot el que hi havia continua on era, i ara a més hi ha tres punts d'accés al que s'ha recuperat.
9c4e7b2 (rescat-GT-241-completa) GT-241 estils de l'indicador 8a1f6c3 GT-241 calcula el comptador 6e2b9c7 GT-241 base del filtre 7d3a8f4 chore: commit 6
Els tres commits, inclosos els dos que el reset --hard havia deixat enrere.
El missatge original, abans que l'--amend el deixés en chore.
L'única cosa que va aportar el merge no desitjat. Per desfer-lo:
I per restaurar GT-241 de debò:
Solució 2:
rm -rf /tmp/p9-04b && mkdir /tmp/p9-04b && cd /tmp/p9-04b && git init -q -b main
echo "base" > app.js && git add . && git commit -q -m "c1"
# 1. Les tres situacions
echo "COMMIT" >> app.js && git commit -q -am "c2: confirmat"
echo "PREPARAT" > estils.css && git add estils.css
echo "NOMES AL DISC" >> app.js
# 2. El desastre
git reset -q --hard HEAD~13f8a1d6 HEAD@{0}: reset: moving to HEAD~1
8f4c2a9 HEAD@{1}: commit: c2: confirmat
3f8a1d6 HEAD@{2}: commit (initial): c1# 4. El tercer
git fsck --lost-found --no-progress | wc -l
git reflog | grep -c "NOMES AL DISC"
grep -rl "NOMES AL DISC" .git/ 2>/dev/null | wc -lUn sol objecte penjant (el de l'add), cap entrada de reflog, i ni un byte a tot .git. La línia NOMES AL DISC mai no es va convertir en objecte: no se'n va calcular el SHA, no es va comprimir, no es va escriure. Git no pot tornar el que mai no va rebre. Les úniques vies serien l'historial local de l'editor o una còpia del sistema de fitxers.
# 5. El desament temporal
echo "feina a mitges" >> app.js
echo "fitxer nou" > esborrany.txt
git stash push -u -q -m "GT-241 a mitges"
git stash list
git stash clear
git stash listgit fsck --unreachable --no-progress | grep commit | awk '{print $3}' \
| xargs -I{} git log -1 --format='%h %ci %s' {} | grep -i "on main"Recuperat íntegre, inclòs el fitxer sense seguiment.
git cat-file -t b52c9d1
git show --stat b52c9d1^2 # l'índex
git show --stat b52c9d1^3 # els que no tenen seguimentTres pares exactament com deia l'apartat 8: HEAD, l'índex i els fitxers sense seguiment. Un desament temporal és un commit, i per això sobreviu a stash clear.
Solució 3:
rm -rf /tmp/p9-04c && mkdir /tmp/p9-04c && cd /tmp/p9-04c && git init -q -b main
for i in $(seq 1 10); do echo "linia $i" >> app.js; git add .; git commit -q -m "commit $i"; done
git rev-parse --short HEAD
git reset -q --hard HEAD~53f8a1d6 HEAD@{0}: reset: moving to HEAD~5
9c4e7b2 HEAD@{1}: commit: commit 10
8f4c2a9 HEAD@{2}: commit: commit 9# 3. Buidar el reflog
git reflog expire --expire=now --all
git reflog | wc -l
git fsck --lost-found --no-progress | grep -c "dangling commit"La diferència clau: el reflog és buit, però els objectes continuen allà. reflog expire esborra el registre, no els objectes. Encara es poden recuperar amb fsck... però ja no saps quina era la punta ni en quin ordre estaven, perquè aquella informació vivia al reflog. Recuperable, sí; còmode, no.
git cat-file -t 9c4e7b2
git log --oneline 9c4e7b2 -3 # el commit i la seva història continuen accessibles# 4. Ara sí, la purga
git gc --prune=now -q
git fsck --lost-found --no-progress | grep -c "dangling commit"
git cat-file -t 9c4e7b2Ara sí que ha desaparegut de debò. L'objecte ja no existeix a .git/objects. Cap tècnica d'aquesta lliçó no el recupera; només un clon aliè o una còpia de seguretat.
# 5. Amb reflog llarg
rm -rf /tmp/p9-04d && mkdir /tmp/p9-04d && cd /tmp/p9-04d && git init -q -b main
git config gc.reflogExpire "1 year"
git config gc.reflogExpireUnreachable "1 year"
for i in $(seq 1 10); do echo "l $i" >> app.js; git add .; git commit -q -m "c$i"; done
git rev-parse --short HEAD > /tmp/punta.txt
git reset -q --hard HEAD~5
git gc --prune=now -q
git reflog | wc -l
git cat-file -t "$(cat /tmp/punta.txt)"El gc --prune=now no ha pogut purgar res, perquè les entrades del reflog continuen vigents i el reflog compta com a referència. Aquest és el mecanisme exacte que manté vius els objectes orfes, i per això allargar la caducitat protegeix de debò.
# 6. Comprovació de salut
cat > /tmp/salut-git.sh <<'EOF'
#!/usr/bin/env bash
echo "Entrades al reflog de HEAD: $(git reflog | wc -l)"
echo "Entrada més antiga: $(git reflog --date=iso | tail -1)"
echo "reflogExpire: $(git config --get gc.reflogExpire || echo '90 dies (defecte)')"
echo "reflogExpireUnreachable: $(git config --get gc.reflogExpireUnreachable || echo '30 dies (defecte)')"
echo "Objectes penjants: $(git fsck --lost-found --no-progress 2>/dev/null | grep -c dangling)"
echo "Branques sense publicar: $(git for-each-ref --format='%(refname:short) %(upstream)' refs/heads | awk '$2==""{print $1}' | tr '\n' ' ')"
EOF
chmod +x /tmp/salut-git.sh && /tmp/salut-git.shEntrades al reflog de HEAD: 11
Entrada més antiga: 3f8a1d6 HEAD@{2026-07-31 11:02:14 +0200}: commit (initial): c1
reflogExpire: 1 year
reflogExpireUnreachable: 1 year
Objectes penjants: 5
Branques sense publicar: mainL'última línia és la que dona més informació en un repositori real: cada branca sense upstream existeix en un sol disc.
Conclusió
El reflog és la raó per la qual gairebé res no es perd a Git, i saber-ho canvia per complet la relació amb les ordres destructives.
- El reflog registra cada moviment de cada referència, en text pla sota
.git/logs/. I no és només un registre: les seves entrades compten com a referències, i per això mantenen vius els commits als quals no arriba cap branca. - És local: no viatja en un
clone, no es publica, i mor amb el disc. No és una còpia de seguretat. I és temporal: 90 dies per al que és assolible, 30 per al que és orfe, quegcaplica. HEAD@{n}no ésHEAD~n. El primer recorre la teva història personal de moviments; el segon recorre el graf. Després d'unreset, són coses diferents, i confondre'ls és l'error més comú.- El patró de recuperació és sempre el mateix:
git reflog→ verificar ambgit show --stat→git branch rescat <hash>. Crear una branca és additiu i no mou res;reset --hardcomplica cada intent fallit. - El receptari cobreix tot el que aquest curs havia anat prometent: desfer un
reset --hard(entrada anterior alreset:), recuperar una branca esborrada amb-D(el hash que imprimeix, o el reflog deHEAD, perquè el de la branca s'esborra amb ella), rescatar un rebase (entrada anterior arebase (start), o--abortsi continua en marxa), desfer unmerge(ORIG_HEAD) i recuperar el que se'n va endur un--amend(l'entradacommit:anterior). - Quan el reflog no n'hi ha prou,
git fsck --lost-found: els objectes dangling són normals, i entre ells hi ha els commits orfes i els blobs d'ungit addque mai no es va confirmar.git cat-file -pigit showels inspeccionen. - Un desament temporal és un commit amb dos o tres pares (
HEAD, índex, sense seguiment), i per això sobreviu adropi aclear: es busca perWIP onentre els inassolibles i es torna ambgit stash store. - Els límits són reals: el que mai no va ser objecte (modificacions sense
add, fitxers esborrats perclean) i el que ja ha passat pergc --prune. Aquí només salven l'historial local de l'editor, una còpia del sistema o el clon d'un company. - I la prevenció que fa innecessària tota la lliçó: confirmar sovint, posar un
git branchabans del que és arriscat,stash push -uabans de netejar, allargar el reflog a un any i publicar les branques.
Fins aquí, tot s'aguantava sobre una premissa: que la base de dades d'objectes estigués sana. Els objectes existien, els hashos quadraven i Git els podia llegir.
I quan no? Quan git status respon error: object file .git/objects/4f/8a2e6... is empty, quan una referència apunta a un objecte que no existeix, quan l'índex és corrupte i Git es nega a fer absolutament res. Això ja no és un problema de referències mal posades: és un problema d'integritat, i té el seu propi diagnòstic, les seves pròpies reparacions i —el més important— un criteri clar per saber quan cal deixar d'intentar arreglar-ho i tornar a clonar.
Continua a la lliçó 09-05: Tractant amb Repositoris Corruptes.
Dominant Git: De Principiant a Avançat
Mòdul 1: Introducció a Git
- Què és Git?
- Instal·lant Git
- Terminologia Bàsica de Git
- El Model de Dades de Git
- Configurant Git
- Configuració Inicial
Mòdul 2: Operacions Bàsiques de Git
- Creant un Repositori
- Clonant un Repositori
- Flux de Treball Bàsic de Git
- Preparant i Confirmant Canvis
- Inspeccionant Canvis amb git diff
- Visualitzant l'Historial de Confirmacions
Mòdul 3: Branques i Fusió
- Entenent les Branques
- Creant i Canviant Branques
- Fusionant Branques
- Estratègies de Fusió
- Resolent Conflictes de Fusió
- Gestió de Branques
Mòdul 4: Treballant amb Repositoris Remots
- Entenent els Repositoris Remots
- Afegint un Repositori Remot
- Autenticació amb Repositoris Remots
- Obtenint i Baixant Canvis
- Enviant Canvis
- Rastrejant Branques
Mòdul 5: Operacions Avançades de Git
- Rebase
- Rebase Interactiu
- Cherry-Picking de Confirmacions
- Desant Canvis Temporals
- Etiquetant Confirmacions
- Revertint Confirmacions
Mòdul 6: Eines i Tècniques de Git
- Usant Git Hooks
- Git Bisect
- Git Blame
- Git Log i Àlies
- Submòduls de Git
- Múltiples Còpies de Treball amb git worktree
Mòdul 7: Estratègies de Col·laboració i Flux de Treball
- Forks i Pull Requests
- Revisions de Codi amb Git
- Flux de Treball Git Flow
- GitHub Flow
- Trunk Based Development
- Integració Contínua amb Git
Mòdul 8: Bones Pràctiques i Consells de Git
- Escrivint Bons Missatges de Confirmació
- Mantenint un Historial Net
- Ignorant Fitxers amb .gitignore
- Atributs de Fitxer amb .gitattributes
- Bones Pràctiques de Seguretat
- Consells de Rendiment
Mòdul 9: Resolució de Problemes i Depuració
- Problemes Habituals de Git
- Desfent Canvis
- Resolent Divergències amb el Remot
- Recuperant Confirmacions Perdudes
- Tractant amb Repositoris Corruptes
- Tècniques Avançades de Depuració
