Ühendamine
Pitmaster ühendab harusid kolmesuunalise ühendamise abil nagu git merge. See tuvastab kiiredasiedastuse võimalused, arvutab ühendamise baasid, ühendab puu- ja sisutasemel ning lisab failikonfliktide korral standardsed konfliktimarkerid.
Ühendamise alused
$result = $repo->merge('feature/login');
if ($result->clean) {
echo "Merged successfully: {$result->commitId->hex}\n";
} else {
echo "Conflicts:\n";
foreach ($result->conflictPaths as $path) {
echo " {$path}\n";
}
}
MergeResult
Klass MergeResult on kirjutuskaitstud väärtusobjekt:
use Pitmaster\Merge\MergeResult;
$result->clean; // bool: true if merge completed without conflicts
$result->commitId; // ?ObjectId: the merge commit (null if conflicts)
$result->conflictPaths; // array: list of file paths with conflicts
$result->mergedContents; // array: path => content with conflict markers (if conflicts)
Kui ühendamine peatub konfliktide tõttu, kirjutatakse konfliktiolek indeksisse ja tööpuusse. Lahendage failid, lisage need add() abil ning kutsuge välja $repo->mergeContinue() või taastage ühendamiseelne olek käsuga $repo->mergeAbort().
Enne ühendamist kinnitage või pange kohalikud muudatused kõrvale: ühendamine koostab tööpuu tulemusest uuesti ja kirjutab jälgitavates failides kinnitamata muudatused üle (#2).
Kiiredasiedastusega ühendamised
Kui praegune HEAD on sihtharu eelkäija, teeb Pitmaster kiiredasiedastusega ühendamise: see liigutab HEAD-i lihtsalt sihtsissekandele, ilma ühendamississekannet loomata.
Before: After fast-forward:
A---B (main) A---B---C---D (main)
\
C---D (feature)
$result = $repo->merge('feature');
// $result->clean === true
// $result->commitId points to D
// No merge commit created
Tagurpidi juhu tuvastamine pole veel teostatud: juba HEAD-is sisalduva haru ühendamisel luuakse muutumatu puuga uus ühendamississekanne, selle asemel et teatada "Already up to date" (#6).
Kolmeosaline ühendamine
Kui harud on lahknenud, teeb Pitmaster kolmesuunalise ühendamise:
- Leia ühendamise baas (madalaim ühine eellane)
- Võrdle puutasemel baasi meie ja baasi nende puuga
- Tee mõlemas harus muudetud failide puhul sisutasemel ühendamine
- Loo kahe vanemaga ühendamississekanne
Before: After merge:
C---D (feature) C---D
/ / \
A---B---E---F (main) A---B---E---F---G (main)
Ühendamise baas
Ühendamise baas on kahe sissekande kõige hilisem ühine eellane. Pitmaster leiab selle sissekannete graafi läbides. Kui ühendamise baase on mitu (ristuv ajalugu), ühendab merge() need esmalt ja kasutab tulemust baasina.
$base = $repo->mergeBase(
$repo->resolve('main'),
$repo->resolve('feature/login'),
);
if ($base !== null) {
echo "Common ancestor: {$base->hex}\n";
}
Otse juurdepääsuks algoritmile MergeBase:
use Pitmaster\Merge\MergeBase;
$finder = new MergeBase($repo->objectDatabase());
$base = $finder->find($commitA, $commitB);
// All merge bases (criss-cross histories can have more than one)
$bases = $finder->findAll($commitA, $commitB);
// Check ancestry
$isAncestor = $finder->isAncestor($oldCommit, $newCommit);
Haru ühendamise kontroll
if ($repo->isBranchMerged('feature/done')) {
// All commits in feature/done are reachable from default branch
$repo->deleteBranch('feature/done');
}
// Check against a specific target
if ($repo->isBranchMerged('feature/done', 'develop')) {
// Merged into develop
}
Konfliktimarkerid
Kui faili on muudetud mõlemas harus ja muudatused kattuvad, lisab Pitmaster standardsed konfliktimarkerid. merge() märgib pooled kui HEAD ja ühendatud haru nime:
<<<<<<< HEAD
return $this->value + 1;
=======
return $this->value * 2;
>>>>>>> feature
Klass ConflictMarker ümbritseb kahte versiooni markeritega:
use Pitmaster\Merge\ConflictMarker;
$marked = ConflictMarker::mark($oursContent, $theirsContent, 'HEAD', 'feature');
// diff3 style, with the base section
$marked = ConflictMarker::mark($oursContent, $theirsContent, 'HEAD', 'feature', $baseContent, 'base');
Kolmesuunaline ühendamine sisutasemel
Klass ThreeWayMerge ühendab bloobide sisu (mitte faile):
use Pitmaster\Merge\ThreeWayMerge;
$result = ThreeWayMerge::merge($baseContent, $oursContent, $theirsContent, 'HEAD', 'feature');
$result['content']; // merged text, with conflict markers if needed
$result['clean']; // true when nothing conflicted
$result['conflicts']; // number of conflict regions
See võtab kolm stringi (baasversiooni, meie versiooni ja nende versiooni), valikulised sildid ning konfliktistiili (vaikimisi 'merge' või 'diff3', mis lisab ka baasiosa).
Ühendamisstrateegiad
Rekursiivne ühendamine
Vaikestrateegia ($repo->merge($branch)) käsitleb ristuvate ühendamiste ajalugu mitme ühendamisbaasiga. CLI aktsepteerib selle jaoks ka väärtusi -s ort ja -s recursive.
Meie poole ühendamine
Salvestab ühendamississekande, jättes HEAD-i puu muutmata. Kasulik haruajaloo säilitamiseks ilma muudatusi kaasamata.
$result = $repo->merge('feature/old', 'ours');
Kaheksajalgühendamine
Ühendab kaks või enam haru üheks ühendamississekandeks. Kui mõnes harus tekib konflikt, tagastab see mittepuhas tulemuse, kirjutamata ühendamisolekut ega loomata sissekannet.
$result = $repo->mergeOctopus(['feature/a', 'feature/b', 'feature/c']);
Klassid RecursiveMerge, OursMerge ja OctopusMerge moodulis Pitmaster\Merge on sisutaseme abivahendid; Repository rakendab ülaltoodud strateegiad ise.
Rerere (salvestatud lahenduse taaskasutamine)
Pitmaster sisaldab iseseisvat klassi Rerere, mis salvestab lahendused git-i kataloogistruktuuri rr-cache järgi:
use Pitmaster\Merge\Rerere;
$rerere = new Rerere($repo->gitDir());
if ($rerere->isEnabled()) { // rerere.enabled = true in .git/config
$rerere->record($conflicted, $resolved); // remember a resolution
$resolved = $rerere->resolve($conflicted); // replay it, or null
}
merge() ei kutsu seda välja: lahendused salvestatakse ja taasesitatakse ainult siis, kui teie kood seda teeb. isEnabled() otsib stringi rerere.enabled = true failist .git/config ega tunne ära sektsiooni [rerere], mille kirjutab git config rerere.enabled true (#20).
Puutasemel ühendamise voog
Ühendamise täielik protsess:
MergeBase::findAll()leiab ühised eellased- Võrdleb baasi, meie ja nende puid tee kaupa
- Kui faili muudeti ainult ühes harus, võtab selle muudatuse üle
- Kui faili muudeti mõlemas harus:
- Kui mõlemad muudeti ühtemoodi, võtab ükskõik kumma muudatuse (need kattuvad)
- Kui muudatused erinevad, käivitab sisul
ThreeWayMerge::merge()
- Kui kõik ühendamised õnnestuvad, koostab ühendatud puu ja loob ühendamississekande
- Kui tekib konflikt, tagastab
MergeResultkoos väärtusegaclean = falseja konfliktsete radadega
CLI kasutamine
./vendor/bin/pitmaster merge feature/login
Eduka toimingu väljund:
Merge successful.
Väljund konflikti korral:
CONFLICT in: src/File.php, src/Other.php