Svenska ▾ Topics ▾ Latest version ▾ git-merge-base last updated in 2.43.0

NAMN

git-merge-base - Hitta så bra gemensamma förfäder som möjligt för en sammanslagning

SYNOPSIS

git merge-base [-a | --all] <incheckning> <incheckning>…​
git merge-base [-a | --all] --octopus <incheckning>…​
git merge-base --is-ancestor <incheckning> <incheckning>
git merge-base --independent <incheckning>…​
git merge-base --fork-point <ref> [<incheckning>]

BESKRIVNING

git merge-base hittar den/de bästa gemensamma förfadern/förfäderna mellan två incheckningar att använda i en trevägssammanslagning. En gemensam förfader är bättre än en annan gemensam förfader om den senare är en förfader till den förra. En gemensam förfader som inte har någon bättre gemensam förfader är en bästa gemensamma förfader, dvs. en sammanslagningsbas. Observera att det kan finnas mer än en sammanslagningsbas för ett par incheckningar.

DRIFTLÄGEN

I det vanligaste specialfallet innebär det att ange endast två incheckningar på kommandoraden att man beräknar sammanslagningsbasen mellan de givna två incheckningar.

Mer generellt, bland de två incheckning att beräkna sammanslagings-basen från, specificeras den ena av det första incheckning-argumentet på kommandoraden; den andra incheckning är en (möjligen hypotetisk) incheckning som är en samanslaging över alla återstående incheckning på kommandoraden.

Som en konsekvens av detta finns inte nödvändigtvis merge base med i vart och ett av incheckning-argumenten om fler än två incheckning anges. Detta skiljer sig från git-show-branch[1] när det används med alternativet --merge-base.

--octopus

Beräkna de bästa gemensamma förfäderna för alla angivna incheckningar, som förberedelse för en n-vägs merge. Detta härmar beteendet hos git show-branch --merge-base.

--independent

Istället för att skriva ut sammanslagningsbaser, skriv ut en minimal delmängd av de angivna incheckningar med samma förfäder. Med andra ord, bland de angivna incheckningarna, lista de som inte kan nås från någon annan. Detta imiterar beteendet hos git show-branch --independent.

--is-ancestor

Kontrollera om den första <incheckning> är en föregångare till den andra <incheckning>, och avsluta med status 0 om sant, eller med status 1 om inte. Fel signaleras av en status som inte är noll men inte är 1.

--fork-point

Hitta punkten där en gren (eller någon historik som leder till <incheckning>) avgrenades från en annan gren (eller någon referens) <ref>. Detta letar inte bara efter den gemensamma förfadern till de två incheckning, utan tar också hänsyn till refloggen för <ref> för att se om historiken som leder till <incheckning> avgrenades från en tidigare inkarnation av grenen <ref> (se diskussion om detta läge nedan).

ALTERNATIV

-a
--all

Skriv ut alla sammanslagings-baser för incheckningar, istället för bara en.

DISKUSSION

Givet två incheckning A och B, kommer git merge-base A B att mata ut en incheckning som är nåbar från både A och B via den överordnade relationen.

Till exempel, med denna topologi:

	 o---o---o---B
	/
---o---1---o---o---o---A

Sammanslagningsbasen mellan A och B är 1.

Givet tre incheckning A, B och C, kommer git merge-base A B C att beräkna sammanslagingsbasen mellan A och en hypotetisk incheckning M, vilket är en merge mellan B och C. Till exempel, med denna topologi:

       o---o---o---o---C
      /
     /   o---o---o---B
    /   /
---2---1---o---o---o---A

Resultatet av git merge-base A B C är 1. Detta beror på att den ekvivalenta topologin med en sammanslagings-incheckning M mellan B och C är:

       o---o---o---o---o
      /                 \
     /   o---o---o---o---M
    /   /
---2---1---o---o---o---A

och resultatet av git merge-base A M är 1. Incheckning 2 är också en gemensam förfader mellan A och M, men 1 är en bättre gemensam förfader, eftersom 2 är en förfader till 1. Därför är 2 inte en sammanslagings-bas.

Resultatet av git merge-base --octopus A B C är 2, eftersom 2 är den bästa gemensamma förfadern till alla incheckningar.

När historiken innefattar kors- och tvärgående sammanslagningar kan det finnas mer än en "bästa" gemensam förfader för två incheckningar. Till exempel, med denna topologi:

---1---o---A
    \ /
     X
    / \
---2---o---o---B

Både 1 och 2 är sammanslagningsbaser för A och B. Ingen av dem är bättre än den andra (båda är bästa sammanslagningsbaser). När alternativet --all inte anges är det ospecificerat vilken som är bäst och som matas ut.

Ett vanligt uttryck för att kontrollera "snabbspola framåt" mellan två incheckningar A och B är (eller brukade åtminstone vara) att beräknsammanslagnings-basen mellan A och B, och kontrollera om den är densamma som A, i vilket fall A är en förfader till B. Du kommer att se detta uttryck ofta använt i äldre skript.

A=$(git rev-parse --verify A)
if test "$A" = "$(git merge-base A B)"
then
	...A är en förfader till B ...
fi

I modern git kan man säga detta på ett mer direkt sätt:

if git merge-base --is-ancestor A B
then
	... A är en förfader till B ...
fi

i stället.

Discussion on fork-point mode

Efter att ha arbetat med grenen ämne som skapades med git switch -c ämne origin/master, kan historiken för fjärrspårningsgrenen origin/master ha spolats tillbaka och byggts om, vilket lett till en historik av denna form:

		 o---B2
		/
---o---o---B1--o---o---o---B (origin/master)
	\
	 B0
	  \
	   D0---D1---D (ämne)

där origin/master brukade peka på incheckningar B0, B1, B2 och nu pekar på B, och din topic-gren startades ovanpå den när origin/master var på B0, och du byggde tre commits, D0, D1 och D, ovanpå den. Tänk dig att du nu vill ombasera det arbete du gjorde på topic ovanpå den uppdaterade origin/master.

I ett sådant fall skulle git merge-base origin/master ämne returnera föräldern till B0 i bilden ovan, men B0^..D är inte det intervall av incheckningar du vill spela upp ovanpå B (det inkluderar B0, vilket inte är vad du skrev; det är en incheckning som den andra sidan ignorerade när den flyttade sin top från B0 till B1).

git merge-base --fork-point origin/master topic är utformad för att hjälpa till i ett sådant fall. Den tar inte bara hänsyn till B utan även B0, B1 och B2 (dvs. gamla toppar från de fjärrspårningsgrenar som ditt förvar reflog känner till) för att se vilken incheckning din ämnesgren byggdes på och hittar B0, vilket gör att du bara kan spela upp incheckningar på ditt ämne, exklusive de incheckningar som den andra sidan senare kasserade.

Därför

$ fork_point=$(git merge-base --fork-point origin/master topic)

kommer att hitta B0, och

$ git rebase --onto origin/master $fork_point topic

kommer att spela upp D0, D1 och D ovanpå B för att skapa en ny historik för denna form:

		 o---B2
		/
---o---o---B1--o---o---o---B (origin/master)
	\                   \
	 B0                  D0'--D1'--D' (ämne - uppdaterat)
	  \
	   D0---D1---D (ämne - gammalt)

A caveat is that older reflog entries in your repository may be expired by git gc. If B0 no longer appears in the reflog of the remote-tracking branch origin/master, the --fork-point mode obviously cannot find it and fails, avoiding to give a random and useless result (such as the parent of B0, like the same command without the --fork-point option gives).

Dessutom måste den fjärrspårningsgren som du använder --fork-point-läget med vara den som ditt ämne avgrenades från sin spets. Om du grenadeav från en äldre incheckning än spetsen, skulle detta läge inte hitta avgrenings-punkten (tänk dig att i exemplet ovan existerade historiken B0 inte, origin/master startade vid B1, flyttade till B2 och sedan B, och du avgrenade ditt ämne vid origin/master^ när origin/master var B1; historikens form skulle vara densamma som ovan, utan B0, och föräldern till B1 är vad git merge-base origin/master topic korrekt hittar, men --fork-point-läget gör det inte, eftersom det inte är en av de incheckningar som brukade vara vid topen av origin/master).

GIT

En del av git[1]-sviten