Sapludināšana
Pitmaster veic zaru sapludināšanu, izmantojot trīsvirzienu sapludināšanu, tāpat kā git merge. Tā nosaka ātrās pārsūtīšanas iespējas, aprēķina sapludināšanas bāzes, veic koka un satura līmeņa sapludināšanu un konfliktu gadījumā izveido standarta konfliktu marķierus.
Pamata sapludināšana
$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
Klase MergeResult ir tikai lasāms vērtību objekts:
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)
Ja sapludināšana apstājas konfliktu dēļ, konflikta stāvoklis tiek ierakstīts indeksā un darba kokā. Atrisiniet konfliktus failos, pievienojiet add() un izsauciet $repo->mergeContinue() vai izsauciet $repo->mergeAbort(), lai atjaunotu stāvokli pirms sapludināšanas.
Pirms sapludināšanas apstipriniet lokālās izmaiņas vai noglabājiet tās: sapludināšanas rezultāts atjauno darba koku un pārraksta neapstiprinātās izmaiņas izsekotajos failos (#2).
Ātrās pārsūtīšanas sapludināšana
Ja pašreizējais HEAD ir mērķa zara priekštecis, Pitmaster veic ātrās pārsūtīšanas sapludināšanu: tas vienkārši pārvieto HEAD uz mērķa komitu, neveidojot sapludināšanas komitu.
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
Pretējais gadījums vēl netiek noteikts: sapludinot zaru, kas jau ir iekļauts HEAD, tiek izveidots jauns sapludināšanas komits ar nemainītu koku, nevis ziņots “Already up to date” (#6).
Trīspusēja apvienošana
Ja zari ir atšķīrušies, Pitmaster veic trīsvirzienu sapludināšanu:
- Atrod sapludināšanas bāzi (zemāko kopīgo priekšteci)
- Salīdzina bāzi ar mūsu un viņu versiju kokiem
- Katram failam, kas mainīts abos zaros, veic satura līmeņa sapludināšanu
- Izveido sapludināšanas komitu ar diviem vecākiem
Before: After merge:
C---D (feature) C---D
/ / \
A---B---E---F (main) A---B---E---F---G (main)
Sapludināšanas bāze
Sapludināšanas bāze ir divu komitu jaunākais kopīgais priekštecis. Pitmaster to atrod, pārmeklējot komitu grafu. Ja ir vairākas sapludināšanas bāzes (krusteniska vēsture), merge() vispirms tās sapludina un izmanto rezultātu kā bāzi.
$base = $repo->mergeBase(
$repo->resolve('main'),
$repo->resolve('feature/login'),
);
if ($base !== null) {
echo "Common ancestor: {$base->hex}\n";
}
Lai piekļūtu algoritmam MergeBase tieši:
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);
Zaru sapludināšanas pārbaude
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
}
Konfliktu marķieri
Ja fails ir modificēts abos zaros un izmaiņas pārklājas, Pitmaster izveido standarta konfliktu marķierus. merge() marķē puses ar HEAD un sapludinātā zara nosaukumu:
<<<<<<< HEAD
return $this->value + 1;
=======
return $this->value * 2;
>>>>>>> feature
Klase ConflictMarker ietver divas versijas marķieros:
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');
Satura līmeņa trīsvirzienu sapludināšana
Klase ThreeWayMerge sapludina blob saturu (nevis failus):
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
Tā pieņem trīs virknes (bāzes versiju, mūsu versiju un viņu versiju), kā arī izvēles etiķetes un konflikta stilu (pēc noklusējuma 'merge' vai 'diff3', lai iekļautu bāzes sadaļu).
Sapludināšanas stratēģijas
Rekursīvā sapludināšana
Noklusējuma stratēģija ($repo->merge($branch)) apstrādā krusteniskas sapludināšanas vēstures ar vairākām sapludināšanas bāzēm. CLI pieņem arī -s ort un -s recursive.
Mūsu puses sapludināšana
Izveido sapludināšanas komitu, kas saglabā nemainītu HEAD koku. Noderīgi, lai uzturētu zara vēsturi, neiekļaujot tajā izmaiņas.
$result = $repo->merge('feature/old', 'ours');
Astoņkāju sapludināšana
Sapludina divus vai vairākus zarus vienā sapludināšanas komitā. Ja kādā zarā ir konflikts, tiek atgriezts nekorekts rezultāts, neierakstot sapludināšanas stāvokli un neveidojot komitu.
$result = $repo->mergeOctopus(['feature/a', 'feature/b', 'feature/c']);
Klases RecursiveMerge, OursMerge un OctopusMerge, kas atrodas Pitmaster\Merge, ir satura līmeņa palīgrīki; Repository pašas īsteno iepriekš minētās stratēģijas.
Rerere (ierakstīto atrisinājumu atkārtota izmantošana)
Pitmaster ietver atsevišķu klasi Rerere, kas glabā atrisinājumus git rr-cache izkārtojumā:
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() to neizsauc: atrisinājumi tiek ierakstīti un atkārtoti izmantoti tikai tad, ja jūsu kods to dara. isEnabled() meklē burtisko tekstu rerere.enabled = true failā .git/config un neatpazīst sadaļu [rerere], ko raksta git config rerere.enabled true (#20).
Sapludināšanas plūsma koka līmenī
Pilns sapludināšanas process:
MergeBase::findAll()atrod kopīgos priekštečus- Bāzes, mūsu un viņu koki tiek salīdzināti pa ceļiem
- Failiem, kas mainīti tikai vienā zarā, tiek pārņemtas šīs izmaiņas
- Failiem, kas mainīti abos zaros:
- Ja abas puses mainījušas vienādi, tiek pārņemtas šīs izmaiņas
- Ja izmaiņas atšķiras, saturam tiek veikta sapludināšana, izmantojot
ThreeWayMerge::merge()
- Ja visas sapludināšanas norit bez konfliktiem, tiek izveidots sapludinātais koks un sapludināšanas komits
- Ja ir konflikti, tiek atgriezts
MergeResultarclean = falseun konfliktu ceļiem
CLI lietojums
./vendor/bin/pitmaster merge feature/login
Izvade veiksmīgas izpildes gadījumā:
Merge successful.
Izvade konflikta gadījumā:
CONFLICT in: src/File.php, src/Other.php