Tot el que hem vist al mòdul donava per suposada una cosa: que la base de dades d'objectes estava sana. El reflog trobava el hash, git branch creava el punter, git show llegia el commit. Els objectes eren on havien de ser i el seu contingut era el correcte.
Aquesta lliçó s'ocupa de quan no ho està.
error: object file .git/objects/4f/8a2e6c9b1d5e3a7f2c8b6d9e4a1f5c3b7d2e9a is empty fatal: loose object 4f8a2e6c9b1d5e3a7f2c8b6d9e4a1f5c3b7d2e9a (stored in .git/objects/4f/8a2e6...) is corrupt
És el missatge que més espanta de tot el curs, i cal començar per dues coses.
La primera és que gairebé mai no és corrupció de debò. La majoria dels missatges alarmants tenen causes mundanes: un disc ple, un procés interromput, un antivirus que va bloquejar un fitxer. Abans de «reparar» res, cal descartar això.
La segona és la que fa habitable aquesta lliçó: en un sistema distribuït, cada clon és una còpia de seguretat gairebé completa. El repositori del Bruno té els mateixos objectes que el teu. El servidor també. Aquest és, gairebé sempre, el camí de recuperació més ràpid, i moltes vegades el correcte és directament tornar a clonar en lloc d'intentar arreglar res.
Veurem com distingir la corrupció real d'una altra cosa, com llegir git fsck sense espantar-se, com reparar els casos freqüents ordenats de menor a major gravetat, i —el més important— quan deixar d'intentar-ho.
Contingut
- Quan sospitar corrupció i quan és una altra cosa
- Les causes reals de la corrupció
git fsckcom a eina de diagnòstic- Reparacions, de menor a major gravetat
- La xarxa de seguretat del model distribuït
- Reconstruir un repositori conservant la teva feina
- Prevenció: manteniment i còpies de seguretat de debò
- Quan deixar de reparar i tornar a clonar
- Quan sospitar corrupció i quan és una altra cosa
Abans de res, la taula de descart. Molts errors que semblen corrupció no ho són.
| Missatge / símptoma | És corrupció? | Causa real i solució |
|---|---|---|
fatal: Unable to create '.git/index.lock': File exists |
No | Forrellat orfe (09-01, apartat 5.5) |
error: insufficient permission for adding an object |
No | Permisos: es va fer servir sudo alguna vegada. chown -R |
fatal: detected dubious ownership |
No | Propietat del directori (09-01, apartat 5.6) |
error: cannot open .git/objects/...: No space left on device |
No encara, però ho serà | Disc ple. Allibera espai ABANS de continuar |
fatal: bad object HEAD |
Potser | HEAD trencat (apartat 4.5) o repositori buit |
warning: ignoring dangling symref |
No | Referència simbòlica a una cosa inexistent. Inofensiu |
dangling commit / blob / tree a fsck |
No | Completament normal (09-04) |
error: object file ... is empty |
Sí | Fitxer d'objecte de 0 bytes. Apartat 4.4 |
fatal: loose object ... is corrupt |
Sí | El contingut no coincideix amb el seu hash. Apartat 4.4 |
error: refs/heads/x does not point to a valid object! |
Sí | Referència trencada. Apartat 4.3 |
missing blob / broken link from a fsck |
Sí | Falta un objecte necessari. Apartat 3 |
fatal: index file smaller than expected |
Sí, però lleu | Índex corrupte (apartat 4.1): és una memòria cau |
error: bad signature 0x00000000 |
Sí, lleu | El mateix: índex corrupte |
fatal: packed object ... cannot be read |
Sí, greu | Packfile danyat. Apartat 4.4 |
| Tot va lent però funciona | No | Rendiment (08-06) |
El descart previ, en tres ordres
Abans de tocar res de .git:
Si veus Use% 100%, aquest és el problema. Allibera espai abans de continuar; qualsevol reparació escriurà objectes i fallarà igualment.
# 2. És meu, el repositori? Tinc permisos?
ls -ld .git .git/objects
find .git -not -user "$(id -un)" | headSi en lloc d'ext4/apfs/ntfs local hi veus nfs, cifs, fuse.sshfs o una ruta dins de Dropbox, OneDrive, iCloud o Google Drive, ja tens l'explicació, i és l'apartat 2.
- Les causes reals de la corrupció
Git és notablement robust. Els objectes són immutables, s'escriuen un cop, i cadascun porta la seva pròpia suma de verificació: el nom de l'objecte és el hash del seu contingut, així que qualsevol alteració es detecta en llegir-lo (lliçó 01-04). La corrupció, quan passa, gairebé sempre ve de fora.
| Causa | Com passa | Freqüència |
|---|---|---|
| Repositori en una carpeta sincronitzada amb el núvol | Dropbox/OneDrive/iCloud/Drive sincronitzen fitxers de .git en ple commit, o resolen «conflictes» duplicant fitxers |
La més comuna de llarg |
| Disc ple | Git escriu un objecte a mitges i no el pot acabar | Molt comuna |
Tall de llum o tancament forçat durant un commit/gc |
Escriptura interrompuda | Comuna en portàtils |
.git en un volum de xarxa (NFS, SMB, sshfs) |
Bloquejos i mtime poc fiables, escriptures reordenades |
Comuna en entorns corporatius |
| Antivirus | Bloqueja o posa en quarantena fitxers de .git/objects |
Comuna a Windows |
| Matar processos de Git a la brava | kill -9 durant gc o repack |
Ocasional |
| Disc amb sectors defectuosos | Maquinari que falla | Rara, però greu |
Editar fitxers de .git a mà |
«Ara arreglaré això amb un editor de text» | Autoinfligida |
El cas del núvol, que mereix èmfasi
No posis un repositori Git dins d'una carpeta sincronitzada pel núvol.
És la causa clàssica, i el raonament és senzill: Git escriu molts fitxers petits en un ordre concret (objecte, després índex, després referència). Un sincronitzador els puja segons el seu propi criteri i velocitat. Si treballes des de dues màquines, el sincronitzador pot combinar un .git/index d'una amb les referències de l'altra, o crear fitxers del tipus main (conflicted copy 2026-07-28).lock.
El resultat és un repositori en un estat que Git mai no hauria pogut produir.
I el més irònic: no cal en absolut. Git ja és un sistema de sincronització distribuït. Per tenir el projecte en dues màquines, la resposta és un remot, no Dropbox.
# Si et trobes en aquesta situació: treu el repositori de la carpeta sincronitzada
mv ~/Dropbox/gestor-tasques ~/projectes/gestor-tasques
cd ~/projectes/gestor-tasques
git fsck --full # comprovar els danysSi de debò necessites que un repositori hi visqui, l'única manera segura és que sigui un repositori nu (--bare) usat com a remot, al qual mai no s'escriu des de dos llocs alhora. Tot i així, git bundle (apartat 7) és millor idea.
La comprovació d'antivirus a Windows
Si la Carla treballa a Windows 11 i pateix errors intermitents:
I a Git for Windows, un ajust que redueix problemes amb antivirus i amb sistemes de fitxers lents:
git fsck com a eina de diagnòstic
git fsck com a eina de diagnòsticgit fsck (file system check) recorre la base d'objectes, verifica que el contingut de cada objecte coincideix amb el seu hash, i comprova que totes les referències entre objectes es resolen.
Opcions útils:
| Opció | Què fa |
|---|---|
--full |
Comprova també els objectes dins dels packfiles (per defecte només els solts) |
--no-progress |
Sense barra de progrés: millor per redirigir a un fitxer |
--lost-found |
Crea enllaços a .git/lost-found/ (09-04) |
--unreachable |
Llista també el que és inassolible comptant el reflog |
--connectivity-only |
Ràpid: només comprova enllaços, no verifica hashos |
--strict |
Més sever: avisa de coses que Git tolera |
--dangling / --no-dangling |
Mostrar o amagar els penjants |
Llegir la sortida: el que és normal davant del que és greu
Aquesta és la taula que evita el pànic innecessari.
Línia de fsck |
Gravetat | Què significa | Què fer |
|---|---|---|---|
dangling commit <sha> |
Cap | Commit al qual no arriba cap referència | Res. És normal després de reset, rebase, --amend |
dangling blob <sha> |
Cap | Contingut d'un git add sense confirmar |
Res (o recuperar-lo, 09-04) |
dangling tree <sha> |
Cap | Directori sense commit que el faci servir | Res |
unreachable <tipus> <sha> |
Cap | Igual, comptant el reflog | Res |
notice: HEAD points to an unborn branch |
Cap | Repositori acabat de crear sense commits | Res |
warning: ... has zero-padded file modes |
Molt baixa | Repositori antic o importat | Res, o fsck.zeroPaddedFilemode ignore |
warning: ... missingSpaceBeforeDate |
Molt baixa | Metadades mal formades d'una importació | Res |
error: <sha>: object corrupt or missing |
ALTA | L'objecte no es pot llegir | Apartat 4.4 |
missing blob <sha> |
ALTA | Un arbre referencia un blob que no existeix | Apartat 4.4 |
missing tree <sha> |
ALTA | Un commit referencia un arbre inexistent | Apartat 4.4 |
broken link from <sha> to <sha> |
ALTA | Un objecte apunta a un altre que falta | Apartat 4.4 |
error: refs/heads/x does not point to a valid object! |
ALTA | Referència trencada | Apartat 4.3 |
dangling commit en quantitats enormes |
Mitjana | Pot indicar un gc interromput |
git gc |
La regla d'or per llegir fsck:
# Amagar el soroll normal i quedar-se NOMÉS amb el que importa
git fsck --full --no-progress 2>&1 | grep -v "^dangling" | grep -v "^notice"Si això no torna res, el teu repositori està sa. Punt. Tot el que hagis vist era soroll.
Un exemple de sortida sana
Checking object directories: 100% (256/256), done. Checking objects: 100% (18432/18432), done. dangling commit 9c4e7b2e4a7f3c8b6d2e9a5f1c7b3d8e4a6f2c9b dangling blob 6f2b9d4a8c1e5f3b7d9a2c6e4f8b1d3a5c7e9f2b dangling commit 3e7f1a8b6d2e9a5f1c7b3d8e4a6f2c9b7d3a8f4a
Tres línies alarmants en aparença, zero problemes. Són les restes del reset --hard de la setmana passada i d'un git add que no es va arribar a confirmar. Un repositori actiu sempre té això.
Un exemple de sortida greu
Checking object directories: 100% (256/256), done.
error: refs/heads/GT-241 does not point to a valid object!
error: object file .git/objects/4f/8a2e6c9b1d5e3a7f2c8b6d9e4a1f5c3b7d2e9a is empty
fatal: loose object 4f8a2e6c9b1d5e3a7f2c8b6d9e4a1f5c3b7d2e9a is corrupt
missing blob 8a1f6c3d5e2b9c7f4a6d1e8b3c5f7a9d2e4b6c8a
broken link from tree 2f8c6e1a4b7d9c3e5f2a8b6d1c9e4f7a3b5d2c8e
to blob 8a1f6c3d5e2b9c7f4a6d1e8b3c5f7a9d2e4b6c8aAquí sí que hi ha feina. Una referència trencada i un objecte illegible, amb l'arbre que el necessita identificat. És l'apartat 4.
Comprovar un objecte concret
Aquest missatge, per a un hash que saps que existia, és la confirmació que l'objecte ha desaparegut.
- Reparacions, de menor a major gravetat
4.1. .git/index corrupte (el cas més freqüent i més lleu)
o
No has perdut res. I la raó és conceptualment important:
L'índex és una memòria cau derivada. No conté informació única: és una foto de què hi hauria d'haver al pròxim commit, reconstruïble enterament a partir de
HEADi del directori de treball.
Per això la reparació és de les més agraïdes de Git:
# 1. Treure l'índex trencat
rm -f .git/index
# 2. Reconstruir-lo des de HEAD
git reset
# 3. Comprovar
git statusL'única cosa que es perd és què estava preparat amb git add: després de la reconstrucció, totes les teves modificacions apareixen com a no preparades. Els canvis en si són intactes, perquè viuen als fitxers del disc, no a l'índex.
Un matís important: fes servir git reset (--mixed), mai git reset --hard. El primer reconstrueix l'índex i deixa el directori de treball en pau; el segon s'enduria per davant totes les teves modificacions (lliçó 09-02).
Si a més tenies un conflicte de fusió a mitges, la informació de les etapes de l'índex (:1:, :2:, :3: de la lliçó 03-05) sí que es perd, i cal refer la fusió:
git merge --abort 2>/dev/null || true
rm -f .git/index
git reset
git merge <branca> # tornar a començar4.2. Forrellats orfes
Ja vist a la lliçó 09-01, aquí en la seva versió completa. Els forrellats són fitxers .lock que Git crea abans d'escriure i esborra en acabar:
El procediment:
# 1. SEMPRE primer: hi ha algun Git executant-se?
ps aux | grep "[g]it "
# 2. De quan són?
ls -l $(find .git -name "*.lock")
# 3. Si no hi ha processos i són antics, esborrar-los
find .git -name "*.lock" -delete
# 4. Comprovar
git statusUn cas especial que mereix cura: .git/config.lock. Si Git va morir escrivint la configuració, el fitxer .git/config pot haver quedat truncat. Comprova-ho abans d'esborrar el forrellat:
Si està trencat, la configuració local és el més fàcil de refer a mà de tot el repositori.
4.3. Referències trencades
Què és. El fitxer refs/heads/GT-241 conté un hash que no correspon a cap objecte existent. Recorda que una branca són 41 bytes de text (lliçó 03-01):
Confirmat: la referència apunta al buit.
Reparació A: el reflog de la branca. És la millor opció, perquè conserva història:
b52c9d1 GT-241@{0}: commit: GT-241 estils de l'indicador
7d3a8f4 GT-241@{1}: commit: GT-241 calcula el comptador
4f8a2e6 GT-241@{2}: branch: Created from mainProva les entrades de dalt a baix fins a trobar-ne una de vàlida:
git cat-file -t 7d3a8f4 # commit → aquesta sí que existeix
git update-ref refs/heads/GT-241 7d3a8f4
git log --oneline GT-241 -3Has perdut l'últim commit, però recuperes la branca. Molt millor que res.
Reparació B: packed-refs. Les referències també viuen consolidades en un fitxer (lliçó 08-06):
De vegades la versió empaquetada és vàlida encara que la solta estigui trencada. Esborrant la solta, Git fa servir l'empaquetada:
Reparació C: el remot.
Reparació D: si la branca no importa, esborrar-la.
I la neteja massiva, quan hi ha moltes referències trencades:
# Veure totes les referències i la seva validesa
git for-each-ref --format='%(refname) %(objectname)' | while read -r ref sha; do
git cat-file -e "$sha" 2>/dev/null || echo "TRENCADA: $ref -> $sha"
done4.4. Objectes solts illegibles o absents
Aquest és el cas seriós.
error: object file .git/objects/4f/8a2e6c9b1d5e3a7f2c8b6d9e4a1f5c3b7d2e9a is empty fatal: loose object 4f8a2e6... is corrupt
Primer pas, el diagnòstic exacte:
Zero bytes: escriptura interrompuda. És el patró típic de disc ple o tall de llum.
# Què se suposa que era? (sovint es pot deduir del context de fsck)
git fsck --full --no-progress 2>&1 | grep -A2 "4f8a2e6"broken link from tree 2f8c6e1a4b7d9c3e5f2a8b6d1c9e4f7a3b5d2c8e
to blob 4f8a2e6c9b1d5e3a7f2c8b6d9e4a1f5c3b7d2e9aLa reparació que gairebé sempre funciona: portar-lo d'un altre clon.
Aquesta és la idea central de la lliçó i l'apartat 5 la desenvolupa. Els objectes de Git són idèntics a tot arreu: el mateix contingut produeix el mateix hash i el mateix fitxer comprimit. Si el Bruno té aquell commit, el seu objecte serveix exactament igual.
# 1. Treure l'objecte trencat (de zero bytes: no hi ha res a perdre!)
rm .git/objects/4f/8a2e6c9b1d5e3a7f2c8b6d9e4a1f5c3b7d2e9a
# 2. Portar-lo del remot: la manera senzilla
git fetch origin --force '+refs/heads/*:refs/remotes/origin/*'
# 3. O copiar-lo directament d'un altre clon
cp /ruta/al/clon/del/bruno/.git/objects/4f/8a2e6c9b1d5e3a... \
.git/objects/4f/
# 4. Comprovar
git fsck --full --no-progress 2>&1 | grep -E "^(error|missing|broken)"Si l'altre clon el té empaquetat en lloc de solt, cal extreure'l:
# Al clon sa:
cd /ruta/al/clon/del/bruno
git cat-file -p 4f8a2e6 > /tmp/objecte-recuperat
# Al repositori trencat:
cd ~/projectes/gestor-tasques
git hash-object -w -t blob /tmp/objecte-recuperatSi el hash resultant coincideix amb el que faltava, la reparació és exacta. I no pot no coincidir: el hash es calcula del contingut, així que si en surt un altre, el contingut no era el mateix (lliçó 01-04).
Per a un objecte de tipus tree o commit, el mateix procediment amb -t tree / -t commit i el contingut exacte que dona cat-file -p al clon sa.
Si l'objecte era un packfile danyat:
Un packfile trencat és pitjor, perquè conté milers d'objectes i les cadenes de delta depenen les unes de les altres (lliçó 08-06). Es pot intentar extreure el que és salvable:
# Moure el pack trencat fora i veure què sobreviu
mkdir -p /tmp/packs-trencats
mv .git/objects/pack/pack-a1b2c3.* /tmp/packs-trencats/
git fsck --full --no-progress
# Intentar recuperar objectes individuals del pack trencat
git verify-pack -v /tmp/packs-trencats/pack-a1b2c3.idx 2>/dev/null | headPerò siguem clars: amb un packfile danyat, la resposta correcta gairebé sempre és reclonar (apartat 8). Extreure objectes d'un pack trencat és un exercici d'arqueologia que rarament compensa quan hi ha un clon sa a un git clone de distància.
4.5. HEAD trencat
HEAD és un fitxer de text d'una línia (lliçó 03-01):
El que hauria de contenir:
El que pot haver passat:
Contingut de .git/HEAD |
Problema | Reparació |
|---|---|---|
ref: refs/heads/branca-esborrada |
La branca no existeix | git symbolic-ref HEAD refs/heads/main |
| Buit o brossa binària | Escriptura interrompuda | Reescriure'l |
Un hash solt (sense ref:) |
HEAD desacoblat: no és un error | git switch main |
| Un hash d'un objecte inexistent | Corrupció real | Apuntar a una branca vàlida |
# Veure quines branques hi ha realment
ls .git/refs/heads/
cat .git/packed-refs 2>/dev/null | grep refs/heads
# Reparar apuntant a una branca existent (forma correcta, no editar a mà)
git symbolic-ref HEAD refs/heads/main
# Comprovar
git status
git log --oneline -3Si no queda cap branca vàlida, el reflog de HEAD continua sent text pla i llegible encara que Git no funcioni:
4.6. .git/config corrupte
És el fitxer més fàcil de reparar, perquè el seu contingut és trivial de refer:
[core]
repositoryformatversion = 0
filemode = true
bare = false
[remote "origin"]
url = git.exemple.cat:equip/gestor-tasques.git
fetch = +refs/heads/*:refs/remotes/origin/*
[branch "main"]
remote = origin
merge = refs/heads/mainSi està truncat, edita'l (aquí sí, amb un editor de text: config és text pla per disseny i Git no el verifica amb hashos) o reconstrueix l'essencial:
git remote add origin git.exemple.cat:equip/gestor-tasques.git
git branch --set-upstream-to=origin/main main
git config user.name "Ana Ferrer"
git config user.email "[email protected]"Taula resum de reparacions
| Problema | Gravetat | Reparació | Es perd alguna cosa? |
|---|---|---|---|
.git/index corrupte |
Baixa | rm .git/index && git reset |
Només què estava preparat |
Forrellat .lock orfe |
Baixa | Comprovar processos i esborrar | Res |
.git/config trencat |
Baixa | Editar o refer amb git config |
Configuració local |
| Referència trencada | Mitjana | Reflog, packed-refs, o el remot |
Potser els últims commits d'aquella branca |
HEAD trencat |
Mitjana | git symbolic-ref HEAD refs/heads/main |
Res |
| Objecte solt illegible | Alta | Portar-lo d'un altre clon | Res, si algú el té |
| Packfile danyat | Molt alta | Reclonar | Només el que fos exclusivament local |
| Corrupció estesa | Molt alta | Reclonar | El mateix |
- La xarxa de seguretat del model distribuït
Aquí hi ha la idea que converteix aquesta lliçó en una cosa manejable, i que tanca el cercle del mòdul 1.
En un sistema centralitzat, el servidor és un punt únic de fallada: si es corromp, s'ha corromput el projecte. A Git, cada clon conté tot l'historial. L'Ana, el Bruno, la Carla, el Diego i el servidor tenen cinc còpies completes de la base d'objectes.
flowchart TD
S["git.exemple.cat<br/>història completa"]
A["Ana (Ubuntu)<br/>història completa<br/>+ GT-241 sense publicar"]
B["Bruno (macOS)<br/>història completa"]
C["Carla (Windows)<br/>història completa"]
D["Diego (fork)<br/>història completa"]
S <--> A
S <--> B
S <--> C
S <--> D
Conseqüència pràctica: quan el teu repositori es corromp, la pregunta correcta no és «com el reparo?» sinó «què tinc jo que no tingui ningú més?».
# 1. Quines branques tinc sense publicar?
git for-each-ref --format='%(refname:short) upstream=[%(upstream:short)]' refs/headsGT-241 no té upstream: existeix només en aquesta màquina. És l'única cosa que cal salvar.
# 2. Quins commits tinc per davant del remot?
git log --oneline origin/main..main
git log --oneline --branches --not --remotes
# 3. Hi ha desaments temporals?
git stash list
# 4. Hi ha canvis sense confirmar?
git status --shortAmb aquestes quatre respostes ja saps exactament quant val la reparació. Si la resposta és «res, tot està publicat», reclonar triga dos minuts i és la solució perfecta.
I si el problema és del servidor, la direcció s'inverteix: qualsevol clon de l'equip el pot reconstruir.
# Reconstruir el remot des d'un clon sa
cd ~/projectes/gestor-tasques
git push --all origin
git push --tags origin
# O crear un mirall complet des de zero
git clone --mirror ~/projectes/gestor-tasques /tmp/gestor-tasques-restaurat.git--mirror copia totes les referències tal qual: branques, etiquetes, notes. És la manera correcta de duplicar un repositori nu.
- Reconstruir un repositori conservant la teva feina
El procediment complet, quan has decidit reclonar però tens coses locals a salvar.
Pas 1: la còpia de seguretat, sempre
Encara que vagis a reclonar. Costa deu segons i és l'única cosa que impedeix que un error durant el rescat sigui definitiu.
Pas 2: inventari del que només tens tu
cd ~/projectes/gestor-tasques
# Branques sense publicar
git for-each-ref --format='%(refname:short) %(upstream)' refs/heads | awk '$2==""{print $1}'
# Commits locals per davant del remot, de totes les branques
git log --oneline --branches --not --remotes
# Desaments temporals
git stash list
# Canvis sense confirmar
git status --short
# Etiquetes locals sense publicar
git tag --no-merged origin/main 2>/dev/nullPas 3: extreure el que és local a un bundle
git bundle empaqueta commits en un sol fitxer que funciona com un remot. És l'eina correcta per a això, i funciona fins i tot si el repositori està parcialment danyat (mentre els objectes implicats estiguin sans).
# Tot el que tinc i no és al remot
git bundle create /tmp/rescat.bundle --branches --not --remotes
# O només una branca concreta
git bundle create /tmp/GT-241.bundle GT-241
# Comprovar que el bundle és vàlid
git bundle verify /tmp/rescat.bundleThe bundle contains these 2 refs: 7d3a8f4a2c6e9b1d5f3a8c6e2b9d4f7a1c5e8b3d refs/heads/GT-241 b52c9d1e4a7f3c8b6d2e9a5f1c7b3d8e4a6f2c9b refs/heads/GT-238 The bundle requires these 1 ref: 4f8a2e6c9b1d5e3a7f2c8b6d9e4a1f5c3b7d2e9a refs/heads/main /tmp/rescat.bundle is okay
Si a més tens canvis sense confirmar, treu-los a part:
git diff > /tmp/canvis-sense-confirmar.patch
git diff --cached > /tmp/canvis-preparats.patch
# I els fitxers sense seguiment, a mà:
cp -a esborrany.txt notes.md /tmp/rescat-fitxers/Si git bundle falla perquè el repositori està massa danyat, la via bruta també serveix:
# Copiar els fitxers del projecte (sense .git) i tractar-los com a canvis nous
mkdir /tmp/rescat-feina
rsync -a --exclude='.git' ~/projectes/gestor-tasques/ /tmp/rescat-feina/Es perd l'historial de les branques locals, però es conserva el contingut, que sol ser el que importava.
Pas 4: clonar de nou
cd ~/projectes
mv gestor-tasques gestor-tasques-trencat
git clone git.exemple.cat:equip/gestor-tasques.git
cd gestor-tasquesPas 5: reincorporar el que s'ha rescatat
# Portar el bundle com si fos un remot
git fetch /tmp/rescat.bundle 'refs/heads/*:refs/heads/*'
git branchLes branques locals han tornat, amb tots els seus commits.
# Els canvis sense confirmar
git apply /tmp/canvis-sense-confirmar.patch
# Els que estaven preparats
git apply --cached /tmp/canvis-preparats.patch
# Els fitxers sense seguiment
cp -a /tmp/rescat-fitxers/* .Pas 6: verificar i netejar
git fsck --full --no-progress 2>&1 | grep -E "^(error|missing|broken)"
git log --oneline --all --graph -15
git statusSi no hi ha errors i tota la teva feina hi és:
No esborris la còpia fins que ho hagis verificat. És l'única regla que importa d'aquest apartat.
El procediment en una taula
| Pas | Ordre | Per a què |
|---|---|---|
| 1 | cp -a <repo> <repo>-TRENCAT-<data> |
Xarxa de seguretat |
| 2 | git for-each-ref + git log --branches --not --remotes |
Saber què és exclusivament teu |
| 3 | git bundle create /tmp/rescat.bundle --branches --not --remotes |
Empaquetar el que és local |
| 4 | git clone <url> |
Repositori net |
| 5 | git fetch /tmp/rescat.bundle 'refs/heads/*:refs/heads/*' |
Tornar el que és local |
| 6 | git fsck --full + comprovar |
Verificar abans d'esborrar res |
- Prevenció: manteniment i còpies de seguretat de debò
git maintenance i git fsck periòdics
Reprenent la lliçó 08-06:
A més de millorar el rendiment, manté la base d'objectes ordenada i redueix el nombre de fitxers solts exposats a escriptures interrompudes.
I una comprovació periòdica, que en un repositori normal triga segons:
# Ràpida: només enllaços, no verifica hashos
git fsck --connectivity-only --no-progress
# Completa: verifica cada objecte contra el seu hash. Mensual està bé
git fsck --full --no-progress 2>&1 | grep -vE "^(dangling|notice)"I una configuració que fa que Git verifiqui els objectes en rebre'ls, detectant la corrupció en el moment en lloc de mesos després:
git config --global transfer.fsckObjects true
git config --global fetch.fsckObjects true
git config --global receive.fsckObjects trueCosta una mica de temps a cada fetch i a canvi impedeix que un objecte mal format entri al teu repositori. Al servidor, receive.fsckObjects és directament obligatori.
git bundle: la còpia de seguretat de debò
Un bundle és un únic fitxer amb tot el que li demanis, que funciona com un remot. És portàtil, verificable i no depèn de cap servei.
# Còpia completa del repositori
git bundle create ~/copies/gestor-tasques-$(date +%Y%m%d).bundle --all
# Comprovar
git bundle verify ~/copies/gestor-tasques-20260731.bundle
# Restaurar: es clona com si fos una URL
git clone ~/copies/gestor-tasques-20260731.bundle gestor-tasques-restauratI còpies incrementals, si el repositori és gran:
Un guió de còpia setmanal:
#!/usr/bin/env bash
# copia-git.sh — còpia de seguretat dels repositoris de treball
DESTI=~/copies/git
mkdir -p "$DESTI"
for repo in ~/projectes/*/; do
[ -d "$repo/.git" ] || continue
nom=$(basename "$repo")
echo "=== $nom ==="
git -C "$repo" bundle create "$DESTI/$nom-$(date +%Y%m%d).bundle" --all \
&& git -C "$repo" bundle verify "$DESTI/$nom-$(date +%Y%m%d).bundle" > /dev/null \
&& echo " OK" || echo " HA FALLAT"
done
# Conservar només les 8 còpies més recents de cada repositori
find "$DESTI" -name "*.bundle" -mtime +56 -deletePer què un bundle és millor que copiar .git amb cp:
cp -a .git |
git bundle |
|
|---|---|---|
| Coherència si hi ha un Git escrivint | Pot copiar un estat a mitges | Coherent: el genera Git |
| Verificable | No | Sí: git bundle verify |
| Mida | Tot, inclosos els objectes orfes | Només el que és assolible, comprimit |
| Restauració | Copiar de tornada | git clone <fitxer> |
| Portàtil (correu, USB) | Milers de fitxers | Un fitxer |
La llista de prevenció
1. Mai un repositori en una carpeta sincronitzada pel núvol. La causa número u. Fes servir un remot.
2. Mai .git en un volum de xarxa si ho pots evitar. Clona en local i publica.
3. Exclou les teves carpetes de projectes de l'antivirus a Windows.
4. Vigila l'espai al disc. Un df -h de tant en tant.
5. git maintenance start als repositoris de treball.
6. transfer.fsckObjects true per detectar la corrupció quan entra.
7. Publica les teves branques. Una branca publicada és a dues màquines. És la millor còpia de seguretat i la més barata.
8. git bundle setmanal del que només tens tu.
9. No matis processos de Git amb kill -9, especialment durant gc o repack.
10. No editis fitxers de .git a mà (tret de config, que és text per disseny). Fes servir git update-ref, git symbolic-ref, git config.
- Quan deixar de reparar i tornar a clonar
La decisió més important de la lliçó, i la que més temps estalvia.
Reclonar és la resposta correcta quan:
- El repositori està completament publicat (res local sense enviar). Aleshores reclonar no té cap cost.
- Hi ha un packfile danyat. Extreure objectes d'un pack trencat rarament compensa.
git fscktorna més d'un grapat d'errors.- La corrupció reapareix després de reparar-la: hi ha una causa de fons (disc, núvol, antivirus) que no has resolt.
- Portes més de trenta minuts intentant reparar-lo. El cost d'un
git cloneés de minuts; el d'una tarda d'arqueologia, no.
Val la pena intentar la reparació quan:
- El problema és l'índex, un forrellat,
HEADoconfig. Són minuts i no es perd res. - És una referència trencada i el reflog o
packed-refsla resolen. - Falta un objecte i saps d'on portar-lo.
- Tens feina local important sense publicar i necessites extreure-la abans de reclonar (apartat 6).
En forma d'arbre:
flowchart TD
Q1{"Tinc feina local<br/>sense publicar?"}
Q1 -->|No| R1["RECLONAR.<br/>És la resposta correcta<br/>i triga dos minuts"]
Q1 -->|Sí| Q2{"El dany és índex, forrellat,<br/>HEAD o una referència?"}
Q2 -->|Sí| R2["Reparar: apartat 4.<br/>Minuts, sense pèrdua"]
Q2 -->|No: objectes o packfiles| Q3{"Puc extreure el que és local<br/>amb git bundle?"}
Q3 -->|Sí| R3["Bundle + reclonar +<br/>reincorporar (apartat 6)"]
Q3 -->|No| R4["rsync del contingut sense .git,<br/>reclonar, i reaplicar com a canvis"]
I la frase que resumeix la lliçó:
Un repositori Git danyat no és un problema de dades: és un problema de logística. Les dades gairebé sempre són en un altre lloc. La teva feina consisteix a identificar què és exclusivament teu, salvar-ho, i portar la resta d'on estigui sa.
Errors Habituals i Consells
Error 1: espantar-se amb els dangling de git fsck. Són completament normals en qualsevol repositori actiu. Filtra amb grep -v "^dangling" i mira si queda alguna cosa.
Error 2: donar per corrupte el que és un disc ple. df -h és la primera ordre. Reparar amb el disc al 100 % no pot funcionar.
Error 3: tenir el repositori a Dropbox, OneDrive o iCloud. És la causa número u de corrupció real, i no cal en absolut: Git ja sincronitza.
Error 4: git reset --hard per reparar un índex corrupte. rm .git/index && git reset reconstrueix sense tocar els teus fitxers; amb --hard els perdries tots.
Error 5: editar fitxers de .git amb un editor de text. Tret de config, fes servir les ordres: git update-ref, git symbolic-ref, git config.
Error 6: reparar sense haver fet una còpia. cp -a costa deu segons i evita que un error durant el rescat sigui definitiu.
Error 7: passar hores reparant un repositori que està íntegrament publicat. Comprova primer què tens que no tingui ningú més. Si la resposta és «res», reclona.
Error 8: fer servir cp -a .git com a còpia de seguretat «oficial». Val per a una emergència, però pot copiar un estat a mitges. git bundle és coherent i verificable.
Error 9: esborrar el repositori trencat abans de verificar el nou. Verifica amb git fsck i comprova que tota la teva feina hi és; després esborra.
Consell 1: aprèn el filtre de fsck. git fsck --full --no-progress 2>&1 | grep -vE "^(dangling|notice)". Si no torna res, estàs sa.
Consell 2: git bundle create ... --all setmanal. Un fitxer, verificable, restaurable amb git clone.
Consell 3: transfer.fsckObjects true a la configuració global. Detecta la corrupció quan entra, no mesos després.
Consell 4: publica les teves branques. És la còpia de seguretat més barata i la que més vegades salva.
Consell 5: l'índex és una memòria cau. Perdre'l no té importància; recordar-ho evita molt pànic innecessari.
Consell 6: posa't un límit de temps. Trenta minuts de reparació i, si continua trencat, reclona. El clon en triga dos.
Exercicis
Exercici 1: llegir git fsck sense espantar-se
- Crea un repositori amb deu commits, una branca amb tres commits propis i un
git addsense confirmar. - Provoca objectes penjants: un
reset --hard HEAD~3, uncommit --amendi unbranch -D. - Executa
git fsck --fulli compta quantes línies torna. - Aplica el filtre del consell 1 i comprova que no queda res. Explica per què el repositori està sa malgrat les línies anteriors.
- Identifica, entre els penjants, quin correspon al
git addsense confirmar i recupera'l ambgit cat-file -p.
Exercici 2: trencar i reparar
Sobre un repositori de proves (mai sobre un de real):
- Corromp l'índex:
printf 'brossa' > .git/index. Executagit statusi anota l'error. Repara'l i explica per què no es perd res. - Trenca una referència:
echo "0000000000000000000000000000000000000000" > .git/refs/heads/GT-241. Executagit fscki repara-la amb el reflog. - Trenca
HEAD:echo "ref: refs/heads/inexistent" > .git/HEAD. Diagnostica i repara ambgit symbolic-ref. - Buida un objecte solt: localitza'n un amb
find .git/objects -type fi trunca'l amb: > <fitxer>. Executagit fsck --fulli observa l'error. - Repara el punt 4 des d'un clon sa que hauràs fet abans de trencar res.
- Després de cada reparació, executa
git fsck --fullfiltrat i confirma que està net.
Exercici 3: rescat complet amb bundle
- Munta un remot local amb
git init --barei clona'l. - Al clon, publica dos commits a
maini crea dues branques locals sense publicar amb tres commits cadascuna. Afegeix un desament temporal i algun canvi sense confirmar. - Fes l'inventari de l'apartat 5: quines branques no tenen upstream, quins commits no són al remot.
- Crea un bundle amb tot el que és local i verifica'l.
- Esborra el clon sencer (simulant corrupció irreparable) i torna a clonar.
- Reincorpora les dues branques des del bundle i comprova que els sis commits hi són.
- Explica què s'ha perdut i què no, i com ho hauries evitat publicant les branques.
Solucions
Solució 1:
rm -rf /tmp/p9-05 && mkdir /tmp/p9-05 && cd /tmp/p9-05 && git init -q -b main
git config user.name "Ana Ferrer"; git config user.email "[email protected]"
for i in $(seq 1 10); do echo "linia $i" >> app.js; git add .; git commit -q -m "commit $i"; done
git switch -q -c GT-241
for i in 1 2 3; do echo "filtre $i" >> filtre.js; git add .; git commit -q -m "GT-241 part $i"; done
echo "PREPARAT SENSE CONFIRMAR" > estils.css && git add estils.css# 2. Els desastres
git reset -q --hard HEAD~3
git commit -q --amend -m "commit 10 (missatge canviat)" 2>/dev/null || true
git switch -q main
git branch -D GT-241# 3. La sortida completa
git fsck --full --no-progress 2>&1 | wc -l
git fsck --full --no-progress 2>&1 | headChecking object directories: 100% (256/256), done. Checking objects: 100% (43/43), done. dangling commit 9c4e7b2e4a7f3c8b6d2e9a5f1c7b3d8e4a6f2c9b dangling blob 6f2b9d4a8c1e5f3b7d9a2c6e4f8b1d3a5c7e9f2b dangling commit 3e7f1a8b6d2e9a5f1c7b3d8e4a6f2c9b7d3a8f4a dangling tree 8a1f6c3d5e2b9c7f4a6d1e8b3c5f7a9d2e4b6c8a dangling commit 8f4c2a9b6d2e9a5f1c7b3d8e4a6f2c9b7d3a8f4a
Nou línies d'aspecte preocupant.
Zero errors. El repositori està perfectament sa.
La raó: dangling significa «aquest objecte existeix i és llegible, però cap referència no hi arriba». És exactament el resultat esperat d'un reset, un --amend i un branch -D: els commits continuen allà (per això són recuperables, lliçó 09-04) però ja no pengen de cap branca. És el contrari d'un problema: és la prova que la xarxa de seguretat funciona.
Els errors de debò comencen per error:, missing o broken link, i aquí no n'hi ha cap.
# 5. El blob de l'add sense confirmar
for b in $(git fsck --lost-found --no-progress 2>/dev/null | awk '/dangling blob/ {print $3}'); do
echo "--- $b ---"; git cat-file -p "$b" | head -2
doneSolució 2:
rm -rf /tmp/p9-05b && mkdir /tmp/p9-05b && cd /tmp/p9-05b && git init -q -b main
git config user.name "Bruno Salas"; git config user.email "[email protected]"
for i in 1 2 3 4 5; do echo "l $i" >> app.js; git add .; git commit -q -m "c$i"; done
git switch -q -c GT-241
echo "filtre" > filtre.js && git add . && git commit -q -m "GT-241 filtre"
git switch -q main
# El clon sa, ABANS de trencar res (pas 5)
git clone -q /tmp/p9-05b /tmp/p9-05b-saRes perdut. La modificació continuava al fitxer del disc; l'índex només era la foto de què entraria al pròxim commit, i es reconstrueix des de HEAD més el directori de treball. És una memòria cau.
# 2. Referència trencada
git rev-parse GT-241 > /tmp/hash-bo.txt
echo "0000000000000000000000000000000000000000" > .git/refs/heads/GT-241
git fsck --full --no-progress 2>&1 | grep -E "^(error|missing|broken)"git cat-file -t b52c9d1 # comprovar que l'objecte existeix
git update-ref refs/heads/GT-241 b52c9d1
git log --oneline GT-241 -2Reparada, i amb el seu commit. El reflog conservava el hash correcte perquè el fitxer de reflog és independent del fitxer de referència.
Git no falla, però es pensa que és en una branca que no existeix: git log no mostra res i un commit crearia una branca nova.
ls .git/refs/heads/
git symbolic-ref HEAD refs/heads/main
git status -sb | head -1
git log --oneline -1# 4. Objecte solt buidat
git gc -q --prune=now 2>/dev/null # empaquetem per deixar pocs solts
echo "contingut nou" > nou.txt && git add . && git commit -q -m "c6"
OBJ=$(find .git/objects -type f -path "*/??/*" | head -1)
echo "Objecte triat: $OBJ"
cp "$OBJ" /tmp/objecte-original # per si de cas
: > "$OBJ"
ls -l "$OBJ"
git fsck --full --no-progress 2>&1 | grep -vE "^(dangling|Checking)"error: object file .git/objects/6f/2b9d4a8c1e5f3b7d9a2c6e4f8b1d3a5c7e9f2b is empty error: unable to mmap .git/objects/6f/2b9d4...: No such device fatal: loose object 6f2b9d4a8c1e5f3b7d9a2c6e4f8b1d3a5c7e9f2b is corrupt
Git es nega a operar: no pot llegir un objecte que necessita.
# 5. Reparar des del clon sa
SHA=$(basename $(dirname "$OBJ"))$(basename "$OBJ")
echo "Falta: $SHA"
rm "$OBJ"
# El té, el clon sa?
git -C /tmp/p9-05b-sa cat-file -t "$SHA"# Extreure'l i tornar-lo a escriure
git -C /tmp/p9-05b-sa cat-file -p "$SHA" > /tmp/contingut
NOU=$(git hash-object -w -t blob /tmp/contingut)
echo "Escrit: $NOU"
[ "$NOU" = "$SHA" ] && echo "COINCIDEIX: reparació exacta"El hash coincideix, així que la reparació és demostrablement exacta. No pot ser d'altra manera: el nom de l'objecte és el hash del seu contingut (lliçó 01-04), de manera que si el hash surt igual, el contingut és idèntic byte a byte. Aquesta propietat és la que fa que reparar un repositori Git des d'un altre clon sigui segur i verificable.
# 6. Verificació final
git fsck --full --no-progress 2>&1 | grep -vE "^(dangling|notice|Checking)"
git log --oneline --all -3Solució 3:
rm -rf /tmp/p9-05c && mkdir /tmp/p9-05c && cd /tmp/p9-05c
git init -q --bare servidor.git
git clone -q servidor.git feina && cd feina
git config user.name "Carla Vidal"; git config user.email "[email protected]"
# 2. El que és publicat
echo "// gestor-tasques" > app.js && git add . && git commit -q -m "chore: inici"
echo "// llistat" >> app.js && git commit -q -am "feat: llistat"
git push -q -u origin main
# Dues branques locals SENSE publicar
for r in GT-241 GT-247; do
git switch -q -c "$r" main
for i in 1 2 3; do echo "$r part $i" >> "$r.js"; git add .; git commit -q -m "$r part $i"; done
done
git switch -q main
# Un desament temporal i canvis sense confirmar
echo "experiment" >> app.js && git stash push -q -m "experiment a mitges"
echo "feina en curs" >> app.js
echo "esborrany" > esborrany.txt# 3. Inventari
echo "--- Branques sense upstream ---"
git for-each-ref --format='%(refname:short) %(upstream)' refs/heads | awk '$2==""{print " "$1}'
echo "--- Commits que no són a cap remot ---"
git log --oneline --branches --not --remotes
echo "--- Desaments temporals ---"
git stash list
echo "--- Sense confirmar ---"
git status --short--- Branques sense upstream ---
GT-241
GT-247
--- Commits que no són a cap remot ---
2f8c6e1 GT-247 part 3
7a4d9b3 GT-247 part 2
5c1e8f2 GT-247 part 1
9c4e7b2 GT-241 part 3
3e7f1a8 GT-241 part 2
8a1f6c3 GT-241 part 1
--- Desaments temporals ---
stash@{0}: On main: experiment a mitges
--- Sense confirmar ---
M app.js
?? esborrany.txtSis commits, dues branques, un desament temporal i dos canvis existeixen únicament en aquesta màquina. Aquest és exactament el valor de la reparació.
# 4. El bundle
git bundle create /tmp/rescat.bundle --branches --not --remotes
git bundle verify /tmp/rescat.bundleThe bundle contains these 2 refs: 9c4e7b2... refs/heads/GT-241 2f8c6e1... refs/heads/GT-247 The bundle requires these 1 ref: b52c9d1... /tmp/rescat.bundle is okay
# El desament temporal i el que és sense confirmar, a part
git stash show -p stash@{0} > /tmp/stash.patch
git diff > /tmp/sense-confirmar.patch
mkdir -p /tmp/fitxers-nous && cp esborrany.txt /tmp/fitxers-nous/# 5. La catàstrofe
cd /tmp/p9-05c && rm -rf feina
git clone -q servidor.git feina && cd feina
git log --oneline --allNomés el que és publicat.
# 6. Reincorporar
git fetch -q /tmp/rescat.bundle 'refs/heads/*:refs/heads/*'
git branch
git log --oneline GT-241 -3
git log --oneline GT-247 -3Els sis commits i les dues branques, amb els seus hashos originals.
git apply /tmp/sense-confirmar.patch
cp /tmp/fitxers-nous/esborrany.txt .
git stash apply --index 2>/dev/null || git apply /tmp/stash.patch
git status --shortEl que s'ha perdut:
- La pila de desaments temporals com a tal. El contingut s'ha reaplicat des del pedaç, però l'entrada
stash@{0}no existeix. (Un bundle amb--allhauria inclòsrefs/stash.) - Tot el reflog, que és local i no viatja (lliçó 09-04). El clon nou té tres entrades.
- Les branques de seguiment antigues i la configuració local del repositori.
El que no s'ha perdut: ni un sol commit, ni un sol canvi.
Com s'hauria evitat: publicant les branques.
Amb les dues branques publicades, l'inventari del pas 3 hauria sortit buit, i tota aquesta lliçó s'hauria reduït a rm -rf feina && git clone. Dos segons de push davant de vint minuts de rescat.
Conclusió
La corrupció d'un repositori Git espanta molt més del que costa.
- La majoria dels missatges alarmants no són corrupció: un forrellat orfe, un disc ple, un problema de permisos o de propietat. Descarta-ho primer amb
df -hils -ld .git. - Les causes reals vénen gairebé sempre de fora de Git: un repositori en una carpeta sincronitzada amb el núvol (la número u), un disc ple, un tall de llum, un volum de xarxa, un antivirus. Els objectes de Git són immutables i porten la seva pròpia verificació; Git rarament es trenca sol.
git fsckes llegeix filtrant el soroll. Els objectes dangling són completament normals —són les restes de cadareset,rebasei--amend— i la seva presència és la prova que la xarxa de seguretat de la lliçó 09-04 funciona. El que és greu comença pererror:,missingobroken link.- Les reparacions, de menor a major: l'índex és una memòria cau derivada i es reconstrueix amb
rm .git/index && git resetsense perdre res; els forrellats s'esborren després de comprovar processos; una referència trencada es repara amb el reflog,packed-refso el remot;HEADambgit symbolic-ref; un objecte illegible portant-lo d'un altre clon, amb la garantia que si el hash coincideix, la reparació és exacta. - El model distribuït és la xarxa de seguretat. Cada clon de l'equip és una còpia gairebé completa. La pregunta correcta davant d'un repositori danyat no és «com el reparo?» sinó «què tinc jo que no tingui ningú més?», i es respon amb
git for-each-refigit log --branches --not --remotes. - El rescat es fa amb
git bundle: empaquetar el que és local en un fitxer, reclonar, i reincorporar-ho ambgit fetch <bundle>. I sempre amb uncp -aprevi i una verificació posterior abans d'esborrar res. - Prevenció: res de repositoris al núvol ni en volums de xarxa,
git maintenance start,transfer.fsckObjects true,git bundleperiòdic i —el que més rendeix— publicar les branques. - I el criteri: si tot està publicat, reclona. Triga dos minuts i és la resposta correcta. Reserva la reparació per a l'índex, els forrellats,
HEADi les referències, o per extreure feina local abans de reclonar.
Amb això, el mòdul ha cobert els quatre problemes que anunciava el tancament del mòdul 8: el reset --hard desafortunat, l'embolic amb el remot, la branca esborrada i el repositori que es nega a funcionar.
Queda el que és transversal. Perquè moltes vegades el problema no és que Git estigui trencat ni que hagis perdut alguna cosa, sinó que Git està fent alguna cosa que no entens: un fitxer que s'ignora quan no hauria de ser així, una configuració que ve d'un lloc que no sabies que existia, un push que falla per raons opaques, un canvi de comportament que ningú no recorda haver introduït. Per a això hi ha una caixa d'eines pròpia —traces, lampisteria, check-ignore, check-attr, ls-files— i, sobretot, un mètode.
Continua a la lliçó 09-06: Tècniques Avançades de Depuració.
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ó
