Is er een snelle manier om “git diff” te gebruiken vanaf het punt of de vertakkingsoorsprong?

Ik heb verschillende SO-antwoorden bekeken over het gebruik van git diffen git-revisies (HEAD, ORIG_HEAD, FETCH_HEAD, enz.) en ik heb nog steeds geen gemakkelijke manier gevonden om de wijzigingen op te sommen. gemaakt sinds het begin van de lokale vestiging, of sinds de laatste rebase.

Met eenvoudigbedoel ik zonder dat ik commit SHA hoef op te zoeken en te plakken of te hoeven tellen hoeveel commits ik terug wil zien.

git diff origin/masteris dichtbij, maar het verwijst naar remote die mogelijk is afgeweken sinds ik er een nieuwe branch van heb uitgecheckt.

Ik zou verwachten dat iets als git diff BASE_HEADbeschikbaar zou zijn.

…tenzij er al een manier is om dat te doen. Heeft iemand het antwoord?


Antwoord 1, autoriteit 100%

Je kunt het vertakkingspuntvinden met git merge-base. Beschouw masterde hoofdregel en devde branch waarvan je de geschiedenis bent geïnteresseerd. Om het punt te vinden waarop devwerd vertakt van master, voer uit:

git merge-base --fork-point master dev

We kunnen nu devvergelijken met deze basis:

git diff $(git merge-base --fork-point master dev)..dev

Als devde huidige takis, wordt dit vereenvoudigd tot:

git diff $(git merge-base --fork-point master)

Zie voor meer informatie de git-merge-basedocumentatie.


Antwoord 2, autoriteit 85%

Gebruik git diff @{u}...HEAD, met drie punten.

Met twee stippen, of met weggelaten HEAD, worden de verschillen van wijzigingen aan beide kanten weergegeven.

Met drie stippen toont het alleen verschillen van wijzigingen aan jouw kant.

Bewerken: voor mensen met iets andere behoeften, ben je misschien geïnteresseerd in git merge-base(merk op dat het veel meer opties heeft dan het andere antwoord gebruikt).


Antwoord 3, autoriteit 31%

U kunt de huidige vertakking van het beginpunt van de vertakking onderscheiden met:

git diff (start point)...

Waarbij (startpunt) een branchnaam, een commit-id of een tag is.

Als u bijvoorbeeld aan een feature-branch werkt die is vertakt van develop, kunt u het volgende gebruiken:

git diff develop...

voor alle wijzigingen op de huidige vertakking sinds het vertakkingspunt.

Dit werd al genoemd in een opmerking, maar ik denk dat het de antwoordstatus verdient. Ik weet niet wat het zal doen sinds de laatste rebase.


Antwoord 4, autoriteit 11%

Voor diffs wil je de driepuntsnotatie. Als je branch devheet en het is vertakt van master:

% git diff master...dev

Voor log wilt u de notatie met twee punten:

% git log master..dev

De revisiesyntaxis r1..r2(met twee punten) betekent “alles bereikbaar vanaf r2(inclusief) maar niet bereikbaar vanaf r1(inclusief)”. De normale manier om dit te gebruiken is om r1en r2te zien als het specificeren van een bereik in een reeks commits (r1exclusief, r2inclusief), dus als je 10 revisies hebt, zal 3..7je de wijzigingen 4, 5, 6 en 7 laten zien. Het is {1, 2, 3, 4, 5, 6, 7}min {1, 2, 3}. Maar r1hoeft niet per se een voorouder van r2te zijn. Zie het meer als een set-operatie waarbij r1de volledige afkomst van r1omgekeerd vertegenwoordigt, en r2de volledige afkomst van r2achteruit, en je trekt de eerste set van de tweede set af.

Dus dan:

git log master..dev

is de hele geschiedenis van de branch minus de hele geschiedenis van master. Met andere woorden, alleen de tak.


Antwoord 5, autoriteit 6%

Om te diff tegen de remote master branch:

git diff $(git merge-base HEAD origin/master)..

Antwoord 6, autoriteit 5%

De huidige oplossingvermeldt

Gebruik git diff @{u}...HEAD, met drie punten.

Maar… dit kan het beste met Git 2.28 (Q3 2020).
Vroeger werd “git diff” gebruikt om argumenten in willekeurige en onzinnige notatie te nemen, b.v. “git diff A..B C“, “git diff A..B C...D” , enz., die is opgeruimd.

Zie commit b7e10b2, commit 8bfcb3a(12 juni 2020), en commit bafa2d7(09 juni 2020) door Chris Torek (chris3torek).
(Samengevoegd door Junio ​​C Hamano — gitsterin commit 1457886, 25 juni 2020)

git diff: bereikverwerking verbeteren

Uitgeschreven door: Chris Torek

Als git diffeen symmetrisch verschil krijgt A...B, het kiest een merge-base uit de twee gespecificeerde commits (zoals gedocumenteerd).

Dit mislukt echter als er geensamenvoegbasis is: in plaats daarvan zie je de verschillen tussen A en B, wat zeker niet is wat je verwacht.

Bovendien, als aanvullende revisies zijn opgegeven op de opdrachtregel (“git diff A...B C“), worden de resultaten een beetje raar:

  • Als er een symmetrische basis voor het samenvoegen van verschillen is, wordt deze gebruikt als de linkerkant van het verschil.
    De laatste laatste ref wordt gebruikt als de rechterkant.

  • Als er geen samenvoegbasis is, gaat de symmetrische status volledig verloren.
    We zullen in plaats daarvan een gecombineerd verschil maken.

Vergelijkbare vreemdheid treedt op als je bijvoorbeeld “git diff C A...B D“. Evenzo, het gebruik van meerdere bereiken met twee punten, of het plaatsen van extra revisiespecificaties in de opdrachtregel met bereiken met twee punten, of het mengen van twee en drie puntenbereiken, produceren allemaal onzin.

Om dit alles te voorkomen, voegt u een routine toe om de bereikgevallen op te vangen en controleert u of de argumenten kloppen.

Als bijwerking, maak een waarschuwing die laat zien welkesamenvoegbasis wordt gebruikt als er meerdere keuzes zijn; sterf als er geen samenvoegbasis is.

De documentatienu omvat:

'git diff' [<options>] <commit> [<commit>...] <commit> [--] [<path>...]:

Dit formulier is om de resultaten van een merge-commit te bekijken.

De eerste lijst moet de samenvoeging zelf zijn; de resterende twee of meer commits moeten de ouders zijn.
Een handige manier om de gewenste reeks revisies te produceren, is door het achtervoegsel {caret}@te gebruiken.
Als masterbijvoorbeeld een merge-commit benoemt, geeft git diff master master^@hetzelfde gecombineerde diff als git show master.


Antwoord 7

Ik heb een alias in mijn .gitconfiggeschreven om deze taak op te lossen:

[alias]
    # See changes since branching off of main branch
    changes = "!f() { \
        current=$(git rev-parse --abbrev-ref HEAD); \
        main=$(git symbolic-ref refs/remotes/origin/HEAD | sed 's@^refs/remotes/origin/@@'); \
        commit=$(git merge-base --fork-point \"$main\" \"$current\"); \
        git diff \"$commit\"...; \
    }; f"

Lijn voor regel, deze alias:

  1. Definieert een shell-functie, f, die
  2. berekent de huidige taknaam,
  3. berekent de naam van de hoofdtak (dit kan hoofd, hoofd, ontwikkel enz. zijn),
  4. berekent de commit waarvan deze twee branches afwijken, en
  5. voert git diffuit om de veranderingen sinds deze vastlegging te zien

Antwoord 8

In Visual Studio 2017 is er een comfortabele manier om verschillen te tonen:

  1. In Team Explorer -> Vertakkingenklik met de rechtermuisknop op de vertakking en selecteer Geschiedenis bekijken

Geschiedenis bekijken

  1. Selecteer in het besturingselement Geschiedenis – branchde commits waarvan je de diff wilt hebben en selecteer Commits vergelijken

Toezeggingen vergelijken

Je krijgt een mooi diff-overzicht en je kunt de bestanden openen in de vergelijkingsmodus.

Other episodes