Skip to content

Latest commit

 

History

History
103 lines (84 loc) · 7.33 KB

subtree-merges.asc

File metadata and controls

103 lines (84 loc) · 7.33 KB
Спајање подстабла

Идеја код спајања подстабла је да имате два пројекта и један од пројеката се мапира у поддиректоријум другог и обрнуто. Када задате спајање подстабла, програм Гит је често довољно паметан да одреди ако је један подстабло оног другог, па да споји на погодан начин.

Проћи ћемо кроз пример додавања одвојеног пројекта у постојећи пројекат, па затим спајање кода другог у поддиректоријум првог.

На почетку, додајмо Rack апликацију нашем пројекту. Rack пројекат додајемо као удаљену референцу у пројекат, па је затим одјављујемо у њену сопствену грану:

$ 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"

Сада у rack_branch имамо корен Rack пројекта и наш пројекат у master грани. Ако одјавите један па онда други, видећете да им се корени пројекта разликују:

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

Ово је прилично чудан концепт. Не морају све гране у вашем репозиторијуму да буду гране истог пројекта. Није уобичајено, јер је ретко од помоћи, али је прилично једноставно да имате гране које садрже потпуно различите историје.

У овом случају желимо да повучемо Rack пројекат у наш master пројекат као поддиректоријум. У програму Гит то можемо да урадимо помоћу git read-tree. Научићете више о read-tree и његовим другарима у ch10-git-internals.asc, али за сада је довољно да знате да она учитава корено стабло једне од грана у ваш текући стејџ и радни директоријум. Управо смо се вратили у вашу master грану и повлачимо rack_branch грану у rack поддиректоријум наше master гране главног пројекта:

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

Када комитујемо, изгледа као да у том поддиректоријуму имамо све Rack фајлове – као да смо их прекопирали из tarball архиве. Оно што је интересантно је да прилично једноставно можемо да спојимо измене из једне гране у другу. Дакле, ако се Rack пројекат ажурира, узводне промене можемо да повучемо тако што се пребацимо на ту грану и повучемо:

$ git checkout rack_branch
$ git pull

Те измене затим можемо да спојимо назад у нашу master грану. Да бисте повукли измене и унапред попунили комит подруку, употребите --squash опцију, као и -Xsubtree опцију рекурзивне стратегије спајања. Рекурзивна стратегија је овде и иначе подразумевана, али је због јаснијег приказа овде наводимо.

$ 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

Све измене из Rack пројекта су спојене и спремне за локално комитовање. Такође можете да урадите и супротно – направите измене у rack поддиректоријуму ваше master гране па их спојите у rack_branch да их касније предате одржаваоцима или да их гурнете узводно.

Ово нам омогућава начин да имамо сличан процес рада као у случају подмодула само без потребе да се користе подмодули (које ћемо обрадити у ch07-git-tools.asc). У нашем репозиторијуму можемо да држимо гране са осталим повезаним пројектима и да их повремено спајамо као подстабло у наш пројекат. То је на неки начин фино, на пример сав кôд се комитује на једно место. Међутим, постоје и лоше стране јер је донекле комплексно и лакше је да се направе грешке приликом реинтеграције измена или нехотичног гурања гране у неповезани репозиторијум.

Још једна помало чудна ствар је начин на који добијате разлику између онога што се налази у rack поддиректоријуму и кода у rack_branch грани – како бисте видели да ли је потребно да их спојите – не можете употребити обичну diff команду. Уместо ње морате извршити git diff-tree са граном коју желите да упоредите:

$ git diff-tree -p rack_branch

Или, да бисте упоредили оно што се налази у rack поддиректоријуму са оним из master гране на серверу последњи пут кад сте преузели са њега, можете да извршите:

$ git diff-tree -p rack_remote/master