Ce face git subtree
git subtree copiază conținutul altui depozit (de exemplu o bibliotecă de componente comună) într-un subdirector al proiectului tău și îl salvează în istoric ca orice alt cod. Colegii care clonează proiectul primesc totul direct, fără pași în plus, spre deosebire de git submodule, unde trebuie rulat git submodule update --init.
Cu pull aduci actualizările bibliotecii, iar cu split sau push extragi modificările făcute în subdirector ca să le trimiți înapoi în depozitul original. Opțiunea --squash comprimă istoricul bibliotecii într-un singur commit, ca istoricul proiectului să rămână curat. Comanda vine din directorul contrib/ al lui Git și este inclusă în majoritatea instalărilor (Git for Windows, Homebrew, Apple Git), dar unele distribuții Linux o pun într-un pachet separat.
Opțiuni și argumente
| Opțiune / Parametru | Descriere |
|---|---|
add --prefix=DIR DEPOZIT RAMURĂ |
Adaugă depozitul în subdirectorul DIR (subdirectorul nu trebuie să existe). |
pull --prefix=DIR DEPOZIT RAMURĂ |
Aduce și integrează modificările noi din depozitul extern. |
push --prefix=DIR DEPOZIT RAMURĂ |
Trimite înapoi în depozitul extern commit-urile care au atins DIR. |
split --prefix=DIR [-b RAMURĂ] |
Creează un istoric separat doar cu subdirectorul DIR (pentru export). |
--squash |
Salvează istoricul extern ca un singur commit comprimat. |
-m MESAJ |
Mesajul commit-ului de îmbinare (la add și pull). |
Exemple
Exemplul 1: Adăugarea unei biblioteci de componente într-un subdirector
Biblioteca biblioteca-ui ajunge în vendor/ui/. Cu --squash, istoricul ei apare ca un singur commit.
git init -q -b main biblioteca-ui
cd biblioteca-ui
git config user.name "Ana Popescu" && git config user.email "ana@exemplu.ro"
echo 'buton { color: green; }' > buton.css
git add . && git commit -q -m "Stil buton"
cd ..
git init -q -b main site
cd site
git config user.name "Ana Popescu" && git config user.email "ana@exemplu.ro"
echo '<h1>Magazin Iasi</h1>' > index.html
git add . && git commit -q -m "Pagina principala"
git subtree add --prefix=vendor/ui ../biblioteca-ui main --squash >/dev/null 2>&1
git log --format='%s' --graph
ls vendor/ui
Rezultat
* Merge commit 'aa97b51cca75d031c7528c13f9dee245c4c65231' as 'vendor/ui'
|\
| * Squashed 'vendor/ui/' content from commit 0cf1e45
* Pagina principala
buton.css
Exemplul 2: Aducerea actualizărilor din bibliotecă
Biblioteca primește un stil nou; în proiect îl aducem cu subtree pull.
git init -q -b main biblioteca-ui
cd biblioteca-ui
git config user.name "Ana Popescu" && git config user.email "ana@exemplu.ro"
echo 'buton { color: green; }' > buton.css
git add . && git commit -q -m "Stil buton"
cd ..
git init -q -b main site
cd site
git config user.name "Ana Popescu" && git config user.email "ana@exemplu.ro"
git commit -q --allow-empty -m "Start"
git subtree add --prefix=vendor/ui ../biblioteca-ui main --squash >/dev/null 2>&1
cd ../biblioteca-ui
echo 'buton:hover { color: darkgreen; }' >> buton.css
git commit -q -am "Hover buton"
cd ../site
git subtree pull --prefix=vendor/ui ../biblioteca-ui main --squash -m "Actualizare UI" >/dev/null 2>&1
cat vendor/ui/buton.css
git log -1 --format='%s'
Rezultat
buton { color: green; }
buton:hover { color: darkgreen; }
Actualizare UI
Exemplul 3: Trimiterea modificărilor înapoi în bibliotecă
Ai adăugat card.css în vendor/ui/ și vrei ca modificarea să ajungă și în depozitul bibliotecii, pe o ramură nouă.
git subtree push --prefix=vendor/ui git@github.com:firma/biblioteca-ui.git card-nou
Ieșire în terminal
git push using: git@github.com:firma/biblioteca-ui.git card-nou
To github.com:firma/biblioteca-ui.git
* [new branch] 48c9e511b9ab15b2c5b0024ad74cf584a47f1d6f -> card-nou
Greșeli frecvente
- Amestecarea, în același commit, a modificărilor din subdirector cu modificări din restul proiectului:
subtree pushle separă, dar mesajele devin confuze pentru cei care lucrează doar pe bibliotecă. - Folosirea alternativă a lui
--squash(uneori cu, alteori fără) pentru același subdirector: Git nu mai găsește corect punctul comun și apar conflicte lapull. Alege o variantă și păstreaz-o.
Comenzi înrudite
git submodule: Integrează și sincronizează alte depozite Git ca subproiecte în interiorul depozitului curent.git merge: Îmbină istoricul și modificările dintr-o altă ramură în ramura curentă.git remote: Gestionează lista serverelor și depozitelor la distanță conectate la proiectul local.