Laten we zeggen dat we de volgende situatie in Git hebben:
Een aangemaakte repository:
mkdir GitTest2
cd GitTest2
git init
Enkele wijzigingen in de master vinden plaats en worden gecommit.
echo "On Master" > bestand
git commit -a -m "Initiële commit"
Feature1 branched van master en er is wat werk gedaan:
git branch feature1
git checkout feature1
echo "Feature1" > featureFile
git commit -a -m "Commit voor feature1"
Ondertussen is er een bug ontdekt in de master-code en een hotfix-branch is opgezet
git checkout master
git branch hotfix1
git checkout hotfix1
De bug is gerepareerd in de hotfix branch en teruggemerged in de master (misschien na een pull request/code review):
echo "Bugfix" > bugfixFile
git commit -a -m "Bugfix Commit"
git checkout master
git merge --no-ff hotfix1
Ontwikkeling op feature1 gaat door:
git checkout feature1
Stel dat ik de hotfix nodig heb in mijn feature branch, misschien omdat de bug daar ook voorkomt. Hoe kan ik dit bereiken zonder de commits te dupliceren in mijn feature branch?
Ik wil voorkomen dat ik twee nieuwe commits op mijn feature branch krijg die geen relatie hebben met de feature implementatie. Dit lijkt vooral belangrijk voor mij als ik pull requests gebruik: Al deze commits zullen ook worden opgenomen in de pull request en moeten worden gereviewd, hoewel dit al is gedaan (omdat de hotfix al in de master zit).
Ik kan geen git merge master --ff-only
doen: "fatal: Not possible to fast-forward, aborting.", maar ik weet niet zeker of dit me geholpen heeft.
Hoe voegen we de master branch samen in de feature branch? Gemakkelijk:
git checkout feature1
git merge master
Het heeft geen zin om hier een fast forward samenvoeging te forceren, omdat het niet gedaan kan worden. Je hebt zowel in de feature branch als in de master branch gecommit. Snel vooruitspoelen is nu onmogelijk.
Kijk eens naar GitFlow. Het is een branching model voor Git dat gevolgd kan worden, en dat heb je onbewust al gedaan. Het is ook een uitbreiding op Git die een aantal commando's toevoegt voor de nieuwe workflow stappen die automatisch dingen doen die je anders handmatig zou moeten doen.
Dus wat heb je goed gedaan in je werkstroom? Je hebt twee branches om mee te werken, je feature1 branch is in principe de "develop" branch in het GitFlow model.
Je hebt een hotfix branch van master gemaakt en die terug samengevoegd. En nu zit je vast.
Het GitFlow model vraagt je om de hotfix ook te mergen naar de development branch, welke "feature1" is in jouw geval.
Dus het echte antwoord zou zijn:
git checkout feature1
git merge --no-ff hotfix1
Dit voegt alle wijzigingen die in de hotfix gemaakt zijn toe aan de feature branch, maar alleen die wijzigingen. Ze kunnen conflicteren met andere ontwikkel wijzigingen in de branch, maar ze zullen niet conflicteren met de master branch mocht je de feature branch uiteindelijk terug samenvoegen met master.
Wees heel voorzichtig met rebasen. Rebaseer alleen als de wijzigingen die je gedaan hebt lokaal in je repository blijven, je hebt bijvoorbeeld geen branches naar een ander repository gepushed. Rebasen is een geweldig gereedschap voor je om je lokale commits in een bruikbare volgorde te zetten voordat je ze de wereld in duwt, maar achteraf rebasen zal de dingen in de war schoppen voor git beginners zoals jij.
Je zou in staat moeten zijn om je branch te rebasen op master:
git checkout feature1
git rebase master
Manage alle conflicten die ontstaan. Als je bij de commits komt met de bugfixes (die al in master zitten), zal Git zeggen dat er geen veranderingen waren en dat ze misschien al toegepast waren. Je gaat dan verder met de rebase (terwijl je de commits die al in master zitten overslaat) met
git rebase --skip
Als je een git log
uitvoert op je feature branch, zul je'de bugfix commit maar één keer zien verschijnen, en in het master gedeelte.
Voor een meer gedetailleerde discussie, kijk eens naar de Git boek documentatie over git rebase
(https://git-scm.com/docs/git-rebase) die dit exacte gebruik geval behandelen.
================ Bewerk voor extra context ====================
Dit antwoord is speciaal gemaakt voor de vraag van @theomega, rekening houdend met zijn specifieke situatie. Merk dit deel op:
Ik wil voorkomen dat [...] commits op mijn feature branch die geen relatie hebben met de feature implementatie.
Rebasen van zijn private branch op master is precies wat dat resultaat zal opleveren. In tegenstelling, master in zijn branch samenvoegen zou precies doen wat hij specifiek niet wil dat er gebeurt: een commit toevoegen die niet gerelateerd is aan de feature implementatie waar hij aan werkt via zijn branch.
Om de gebruikers aan te spreken die de titel van de vraag lezen, de eigenlijke inhoud en context van de vraag overslaan, en dan alleen het bovenste antwoord blindelings lezen in de veronderstelling dat het altijd van toepassing zal zijn op hun (andere) gebruikssituatie, sta me toe om het uit te leggen:
git merge master
zoals in @Sven's antwoord).Tenslotte, als je'ontevreden bent met het feit dat dit antwoord niet het beste past bij jouw situatie, ook al was het dat wel voor @theomega, dan zal het toevoegen van een commentaar hieronder'niet bijzonder behulpzaam zijn: Ik bepaal niet welk antwoord wordt geselecteerd, dat doet alleen @theomega.
Je zou in staat kunnen zijn om een "cherry-pick" te doen om de exacte commit(s) die je nodig hebt in je feature branch te trekken.
Doe een git checkout hotfix1
om op de hotfix1 branch te komen. Doe dan een git log
om de SHA-1 hash (grote serie van willekeurige letters en cijfers die een commit uniek identificeert) van de commit in kwestie te krijgen. Kopieer dat (of de eerste 10 karakters of zo).
Dan, git checkout feature1
om terug te gaan naar je feature branch.
Dan, git cherry-pick <de SHA-1 hash die je net gekopieerd hebt>
Dat zal die commit, en alleen die commit, naar je feature branch halen. Die verandering zal in de branch zitten - je hebt hem er net in ge-cherry-picked". Ga dan verder met je werk, bewerk, commit, push, etc. naar hartenlust.
Als je uiteindelijk een andere samenvoeging uitvoert van een branch naar je feature branch (of vice-versa), zal Git herkennen dat je die specifieke commit al hebt samengevoegd, weten dat het die niet opnieuw hoeft te maken, en er gewoon "overheen " gaan.