Git a fons
Git a l'equip: proteccions i bones pràctiques
Saber fer commits no és suficient quan sou cinc persones tocant el mateix codi. Aquesta pàgina explica, amb pas a pas, com protegir la branca principal, com revisar-vos, com evitar ensurts i què fer quan en teniu un. No és matèria de les diapositives: és per consultar quan ho necessiteu.
Git a fons
Protegeix la branca main
La branca principal és el que lliureu i el que desplegueu. Una sola empenta equivocada pot trencar la demo de dimecres. La protecció de branques fa que GitHub impedeixi els errors, en lloc de confiar que ningú se n'oblidi.
Com activar-la a GitHub
- Obriu el repositori i aneu a Settings, després a Rules i Rulesets (o a Branches, en la vista clàssica de «branch protection rules»).
- Creeu una regla nova per a la branca per defecte (
main) i, si feu Gitflow, una altra per adevelop. - Poseu-la en mode Active i marqueu les opcions de la llista de sota.
- Proveu-ho: intenteu fer
git pushdirecte amain. Ha de ser rebutjat.
Depèn del pla. Els noms exactes poden canviar una mica a la interfície de GitHub, i en repositoris privats l'obligatorietat de les regles depèn del pla de l'organització (si els botons surten desactivats o la regla no s'aplica, escriviu-ho a l'acord d'equip i vigileu-ho a mà). Pregunteu què té habilitat l'organització del vostre grup.
Què marcar i per què
Require a pull request before merging
Ningú no puja codi a main directament: tot passa per una PR. Demaneu-hi 1 aprovació com a mínim.
Dismiss stale approvals
Si s'afegeixen commits després d'aprovar, l'aprovació caduca i cal tornar a revisar.
Require status checks to pass
La PR no es pot fusionar si la integració contínua falla (vegeu més avall).
Require conversation resolution
No es fusiona amb comentaris de revisió sense resoldre.
Block force pushes
Ningú no pot reescriure la història de main amb --force.
Restrict deletions
Ningú no pot esborrar la branca per error.
Do not allow bypassing
Ni tan sols qui administra el repositori se salta les regles. Així no hi ha excepcions «només aquesta vegada».
Pull requests que es poden revisar
Una pull request (PR) és una proposta de canvi amb conversa. Si és petita i clara, la revisió és ràpida i serveix; si és enorme, ningú la mira de debò i aprova «a ull».
Una bona PR
- Una tasca, una PR. Si canvia més de 300-400 línies o fa dues coses, partiu-la.
- Títol amb sentit, preferiblement en format de Conventional Commits:
feat(registre): valida el correu. - Enllaça la tasca de Taiga (o un
Closes #34si feu servir issues de GitHub, que tanca l'issue en fusionar). - Dues línies de context: què canvia, per què i com ho heu provat. Captures si toca la interfície.
- Reviseu el vostre propi diff abans de demanar revisió: trobareu soles prints oblidats i fitxers que no hi pintaven res.
- Pull request en esborrany (draft) si voleu feedback d'una feina a mitges.
Quan reviseu
- Ho fa una persona diferent de qui l'ha escrit; rotar els revisors reparteix el coneixement.
- Mireu primer que fa el que diuen els criteris d'acceptació de la història, després els casos límit, les proves i el nom de les coses.
- Comenteu el codi, no la persona: pregunteu («per què no fem servir...?») abans d'ordenar.
- Separeu el que és imprescindible del que és opcional (nit) perquè qui rep el comentari sàpiga què ha d'arreglar.
Plantilla de PR (opcional però útil)
Si creeu el fitxer .github/pull_request_template.md, GitHub el posa com a text inicial a cada PR nova:
## Què canvia
(Una o dues frases: què fa aquesta PR i per què.)
## Ticket
Taiga: #34
## Com s'ha provat
- [ ] Proves automàtiques
- [ ] Provat a mà (explica com)
## Notes per a qui revisa
(Què vols que es miri amb més cura? Captures si canvia la interfície.)Merge, squash o rebase: com es fusiona
GitHub ofereix tres maneres de fusionar una PR i cadascuna deixa una història diferent. Triar-ne una és una decisió d'equip, no de cada persona.
| Opció | Què fa | Història resultant | Compte amb |
|---|---|---|---|
| Create a merge commit | Afegeix tots els commits de la branca i un commit de fusió. | Fidel: es veuen tots els commits i qui els ha fet. | Una història amb molts «merge» si no s'ordena. |
| Squash and merge | Aplasta tota la PR en un sol commit a main. | Neta: un commit per tasca (el títol de la PR passa a ser el missatge). | Es perd el detall dels commits i els assigna a qui obre la PR. |
| Rebase and merge | Reaplica els commits de la branca damunt de main. | Lineal, sense commits de fusió, conservant cada commit. | Reescriu els hashes; no la feu servir en branques compartides. |
Recomanació per a PES: el curs mira que tothom faci commits sovint i de manera equilibrada. Amb el squash, tota la feina d'una PR queda a nom d'una sola persona, i si programeu en parella es perd qui ha fet què. Per això val més Create a merge commit o Rebase and merge. Si en parella un sol compte fa el commit, afegiu l'altra persona amb un peu Co-authored-by: Nom <correu> perquè GitHub li compti.
Activeu també Automatically delete head branches (Settings, General): en fusionar, GitHub esborra la branca de la tasca i no s'acumulen.
Integració contínua: el porter de main
La integració contínua (CI) executa les proves, el linter i la compilació a cada PR en una màquina neta. Si la CI és un required status check de la protecció, una PR que trenca les proves no es pot fusionar.
- Creeu el fitxer
.github/workflows/ci.yml(exemple de sota, per a Node: adapteu-lo a Java, Python o Android). - Feu una PR: a la pestanya Actions veureu com s'executa.
- A la regla de protecció de main, a Require status checks, afegiu el treball
test. - Mantingueu-la ràpida (menys de 5 minuts) i, si falla a main, arregleu-la abans de fer res més.
La CI no substitueix les proves: les executa de manera automàtica i igual per a tothom. Més endavant podeu desplegar a virtech només des de main i només si la CI ha passat.
name: CI
on:
pull_request:
push:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- run: npm ci
- run: npm testMantén la teva branca al dia
Com més temps viu una branca, més costa fusionar-la. Reculli els canvis de main cada dia i mantingueu les branques curtes (de dos o tres dies, no de dues setmanes).
git switch main
git pull
git switch feature/34-registre
git rebase main # o: git merge main
git push --force-with-lease # només després d'un rebase i només a la teva branca- Merge és el més segur: no reescriu res i serveix en branques que altres persones també fan servir.
- Rebase deixa una història lineal, però reescriu els commits: no el feu mai en una branca que algú més ja s'ha baixat.
--force-with-leasefalla si algú ha pujat alguna cosa que no tens; molt més segur que--force.- Si dues persones han tocat la mateixa línia, Git marca el conflicte. Obriu el fitxer, deixeu el que toca, esborreu les marques, feu
git addi continueu (git rebase --continueo feu el commit de la fusió). Si us perdeu,git rebase --abortogit merge --aborttornen al principi.
Així es veu un conflicte
<<<<<<< HEAD
el teu canvi
=======
el canvi de l'altra persona
>>>>>>> mainSecrets i fitxers que no s'han de pujar
Un repositori de GitHub és fàcil de clonar, de copiar i de recordar per sempre. El que hi puja, hi queda.
- Fitxer
.gitignoredes del primer commit:node_modules/,build/,.env,*.log, carpetes de l'IDE, fitxers.apki claus de signatura. - Mai no pugeu contrasenyes, tokens d'API, claus privades ni el
.env. Afegiu un.env.exampleamb les variables buides perquè els companys sàpiguen quines calen. - Per a la CI, guardeu els valors a Settings, Secrets and variables, Actions, no al codi.
- Si us n'escapa un, revoqueu-lo i genereu-ne un de nou ara mateix. Esborrar el commit no n'hi ha prou: la història, els forks i les memòries cau el conserven.
- No pugeu binaris grossos (APK, vídeos). Per als executables feu servir les Releases de GitHub.
Etiquetes i versions
Una etiqueta (tag) és un nom permanent per a un commit. Etiqueteu cada lliurament i sempre podreu tornar exactament al que vau entregar.
git tag -a fag-3 -m "Lliurament Fag-3"
git push origin fag-3- A GitHub, Releases permet adjuntar notes i l'executable a una etiqueta.
- Per a versions que veuen els usuaris, useu Versionament Semàntic:
MAJOR.MINOR.PATCH(1.4.2). Una correcció puja el PATCH, una funcionalitat el MINOR i un canvi que trenca la compatibilitat el MAJOR. - Els tipus de Conventional Commits (
fix,feat,!) us diuen quin número toca: vegeu Conventional Commits.
Quan alguna cosa va malament
Tothom s'equivoca amb Git. La diferència és saber desfer-ho sense empitjorar-ho. Regla d'or: si ja ho heu pujat a una branca compartida, no reescriviu la història: feu un commit nou que ho corregeixi.
| Què ha passat | Què fer |
|---|---|
| He fet commits a main per error (sense pujar-los) | git switch -c feature/34-x (els commits ja són a la branca nova), després git switch main i git reset --hard origin/main. Compte: el reset --hard descarta canvis sense desar. |
| Tinc una errada al missatge de l'últim commit (sense pujar) | git commit --amend |
| M'he descuidat un fitxer a l'últim commit (sense pujar) | git add fitxer i git commit --amend --no-edit |
| He afegit un fitxer a l'àrea de preparació per error | git restore --staged fitxer |
| Vull descartar els canvis d'un fitxer | git restore fitxer (no es pot desfer) |
| He pujat un commit dolent a una branca compartida | git revert <hash>: crea un commit que ho desfà. No feu reset ni --force. |
| El push es rebutja («non-fast-forward») | Algú ha pujat abans: git pull --rebase (o git pull) i torneu a pujar. No forceu. |
| Crec que he perdut commits | git reflog llista on ha estat HEAD; git switch -c rescat <hash> els recupera. |
Acord d'equip sobre Git
Escriviu a la memòria què heu decidit i reviseu-ho a cada retrospectiva. Aquesta llista us serveix de guia; es desa al vostre navegador.