Ako mergnúť dva Git projekty
V Gite zvyčajne robíte merge pull requestov pozostávajúcich z pár commitov. Niekedy však potrebujete mergnúť dva samostatné Git projekty, ktoré nemajú žiadnu spoločnú históriu. Zvyčajne sa to stáva, keď sa experimentálny komponent najprv vyvíja v samostatnom repozitári a až neskôr je integrovaný do jadra projektu v hlavnom Git repozitári. Takýto merge je komplikovanejší než bežný merge pull requestov.
Existuje niekoľko dotazov na StackOverflow (1, 2) a článkov na rôznych stránkach a blogoch (napr. 1, 2, 3), ale všetky sú v niečom nenápadne nesprávne. Zjavne nesprávne články ani nespomínam. Preto som sa rozhodol spísať štandardný návod na mergovanie Git projektov.
Najskôr spomeniem najčastejšie chyby, na ktoré si treba dať pozor:
- Rýchle a špinavé riešenie je jednoducho skopírovať súbory. Zložitejšie metódy, vrátane tejto, sú o zachovaní histórie. História je hodnotná a jej zachovanie nezaberie veľa času, tak to urobte správne.
- Projekty zvyčajne nemožno mergnuť tak, ako sú, pretože by to spôsobilo veľa konfliktov v koreňovom adresári. Väčšina repozitárov vyžaduje určitú prípravu. Často ich treba presunúť do podadresára.
- Niektorí ľudia odporúčajú prepisovanie histórie rôznymi spôsobmi. Nerobte to. Stačí obyčajný merge.
- Tagy by zvyčajne nemali byť mergnuté, pretože sú globálne a tak spôsobujú konflikty, najmä tagy releasov (napr. v1.0.0). Dajú sa premenovať, ale to je málokedy to, čo chcete.
- Štandardne sa merguje iba master. Ak máte aj iné vetvy, ktoré chcete zachovať, budete musieť tento postup zopakovať pre každú vetvu.
No a tu je sľúbený štandardný postup. Repozitár "beta" budeme mergovať do repozitára "alpha".
Krok 1: Pridajte repozitár beta ako nový remote do repozitára alpha a fetchnite ho. Remote je len dočasný. Neskôr ho možno odstrániť. Tu hneď aj zakážeme import tagov, aby sme sa vyhli konfliktom.
cd /path/to/alpha-directory git remote add --no-tags beta-remote /path/to/beta-directory git fetch beta-remote
Krok 2: K remote branchu pridajte tracking branch, aby sme mohli vykonať zmeny pred mergom. Tracking branch je len dočasný. Neskôr ho možno odstrániť.
git checkout -b beta-branch beta-remote/master
Krok 3: Vykonajte potrebné zmeny a commitnite ich. Väčšinou treba presunúť kód do podadresára a odstrániť súbory, ktoré sa už nachádzajú v druhom projekte. Cieľom je vyhnúť sa konfliktom počas mergovania.
mkdir beta mv src README.md beta/ git stage . git commit -m "Moved beta code into a subdirectory"
Krok 4: Prepnite sa späť do mastra a mergnite upravenú vetvu.
git switch master git merge --allow-unrelated-histories --no-commit beta-branch git commit -m "Merged the beta code"
Krok 5: Upratovanie. Odstráňte predtým vytvorenú vetvu aj remote.
git branch -D beta-branch git remote remove beta-remote
A je to. Ak sa teraz pozriete na históriu repozitára alpha, uvidíte, že posledný commit je merge oboch repozitárov a že sú zachované verzie z oboch histórií.