Skip to content

Latest commit

 

History

History
86 lines (67 loc) · 5.15 KB

File metadata and controls

86 lines (67 loc) · 5.15 KB
Fusión de subarbre

La idea de la fusió de subarbre és que teniu dos projectes, i un dels projectes es mapeja a un subdirectori de l’altre. Quan especifiqueu una fusió de subarbre, Git és sovint prou intel·ligent per descobrir que un és un subarbre de l’altre i fusionar adequadament.

Passarem per un exemple de com afegir un projecte separat a un projecte existent i després fusionar el codi del segon en un subdirectori del primer.

Primer, afegirem l’aplicació Rack al nostre projecte. Afegirem el projecte Rack com a referència remota al nostre propi projecte i després el revisarem a la seva pròpia branca:

$ git remote add rack_remote https://github.com/rack/rack
$ git fetch rack_remote --no-tags
warning: no common commits
remote: Counting objects: 3184, done.
remote: Compressing objects: 100% (1465/1465), done.
remote: Total 3184 (delta 1952), reused 2770 (delta 1675)
Receiving objects: 100% (3184/3184), 677.42 KiB | 4 KiB/s, done.
Resolving deltas: 100% (1952/1952), done.
From https://github.com/rack/rack
 * [new branch]      build      -> rack_remote/build
 * [new branch]      master     -> rack_remote/master
 * [new branch]      rack-0.4   -> rack_remote/rack-0.4
 * [new branch]      rack-0.9   -> rack_remote/rack-0.9
$ git checkout -b rack_branch rack_remote/master
Branch rack_branch set up to track remote branch refs/remotes/rack_remote/master.
Switched to a new branch "rack_branch"

Ara tenim l’arrel del projecte Rack a la nostra branca rack_branch i el nostre propi projecte a la branca master. Si reviseu un i després l’altre, podeu veure que tenen arrels de projecte diferents:

$ ls
AUTHORS         KNOWN-ISSUES   Rakefile      contrib         lib
COPYING         README         bin           example         test
$ git checkout master
Switched to branch "master"
$ ls
README

Aquest és un concepte una mica estrany. No totes les branques al vostre repositori realment han de ser branques del mateix projecte. No és comú, perquè rarament és útil, però és bastant fàcil tenir branques que contenen històries completament diferents.

En aquest cas, volem extreure el projecte Rack al nostre projecte master com a un subdirectori. Ho podem fer a Git amb git read-tree. Aprendreu més sobre read-tree i els seus amics a ch10-git-internals.asc, però per ara, tingueu en compte que llegeix l’arbre arrel d’una branca al vostre àrea de preparació actual i directori de treball. Acabem de tornar a la vostra branca master, i extraiem la branca rack_branch al subdirectori rack de la nostra branca master del nostre projecte principal:

$ git read-tree --prefix=rack/ -u rack_branch

Quan fem commit, sembla que tenim tots els fitxers de Rack sota aquest subdirectori, com si els haguéssim copiat des d’un tarball. El que es torna interessant és que podem fusionar canvis d’una de les branques a l’altra de manera bastant fàcil. Així que, si el projecte Rack s’actualitza, podem extreure canvis aigües amunt canviant a aquesta branca i extreient:

$ git checkout rack_branch
$ git pull

Després, podem fusionar aquests canvis de nou a la nostra branca master. Per extreure els canvis i pre-omplir el missatge de commit, utilitzeu l’opció --squash, així com l’opció -Xsubtree de l’estratègia de fusió recursiva. L’estratègia recursiva és la predeterminada aquí, però la incloem per a major claredat.

$ git checkout master
$ git merge --squash -s recursive -Xsubtree=rack rack_branch
Squash commit -- not updating HEAD
Automatic merge went well; stopped before committing as requested

Tots els canvis del projecte Rack es fusionen i estan llests per ser confirmats localment. També podeu fer el contrari: fer canvis al subdirectori rack de la vostra branca master i després fusionar-los a la vostra branca rack_branch més tard per enviar-los als mantenedors o pujar-los aigües amunt.

Això ens dóna una manera de tenir un flux de treball una mica similar al flux de treball de submòduls sense utilitzar submòduls (que cobrirem a ch07-git-tools.asc). Podem mantenir branques amb altres projectes relacionats al nostre repositori i fusionar-los ocasionalment al nostre projecte. És agradable en alguns aspectes, per exemple, tot el codi es confirma en un sol lloc. No obstant això, té altres desavantatges, com que és una mica més complex i més fàcil de cometre errors en reintegrar canvis o empenyer accidentalment una branca a un repositori no relacionat.

Una altra cosa una mica estranya és que per obtenir un diff entre el que teniu al vostre subdirectori rack i el codi a la vostra branca rack_branch, per veure si necessiteu fusionar-los, no podeu utilitzar la comanda diff normal. En el seu lloc, heu d’executar git diff-tree amb la branca amb la qual voleu comparar:

$ git diff-tree -p rack_branch

O, per comparar el que està al vostre subdirectori rack amb el que estava a la branca master al servidor l’última vegada que vau fer fetch, podeu executar:

$ git diff-tree -p rack_remote/master