Różnica Git między aktualną gałęzią a główną, ale bez nierozłącznych zatwierdzeń głównych

171

Chcę mieć różnicę wszystkich zmian w gałęzi, która nie jest jeszcze scalona z wzorcem.

Próbowałem:

git diff master
git diff branch..master
git diff branch...master

Jednak w każdym z tych przypadków różnica zawiera zawartość w master, która nie została jeszcze włączona do mojej gałęzi.

Czy istnieje sposób na zrobienie różnicy między moją gałęzią a wzorcem, który wyklucza zmiany w wzorcu, które nie zostały jeszcze włączone do mojej gałęzi?

pillarOfLight
źródło
9
Jeśli odwrócić wokół drugą wersję, masz co chcesz: git diff master..branch. Możesz go skrócić do, git diff master..jeśli jesteś w oddziale. r1..r2Składnia jest skrótem ^r1 r2, który oznacza „pokaż mi, że wszystko pochodzi od r2i nie jest osiągalny z r1”. git help gitrevisionszawiera informacje na temat różnych składni, których możesz użyć.
John Szakmeister
1
Rozszerzyłem swoją odpowiedź po tym, jak przeczytałem więcej na temat ...składni git diff. Twój komentarz jest błędny, @jszakmeister, ponieważ zakresy wersji opisane w gitrevisionsnie mają z tym nic wspólnego git diff. Różnica porównuje dwa punkty w historii, nie może działać z zakresem.
Palec
Masz rację. Zawsze zapominam, że git diffdziała to inaczej niż inne polecenia ... to frustrujące. :-(
John Szakmeister
upewnij się, że aktualizujesz lokalną kopię mastera przed porównaniem
joe

Odpowiedzi:

232
git diff `git merge-base master branch`..branch

Podstawa seryjnej jest punkt, w którym branchodbiega od master.

Git diff obsługuje w tym celu specjalną składnię:

git diff master...branch

Nie możesz zamienić stron, bo wtedy dostaniesz drugą gałąź. Chcesz wiedzieć, co się zmieniło, branchodkąd odeszło master, a nie na odwrót.

Luźno powiązane:


Zauważ, że ..i ...składnia nie ma takiej samej semantyki, jak w innych narzędziach Git. Różni się od znaczenia określonego w man gitrevisions.

Cytowanie man git-diff:

  • git diff [--options] <commit> <commit> [--] [<path>…]

    Ma to na celu przeglądanie zmian między dwoma arbitralnymi <commit>.

  • git diff [--options] <commit>..<commit> [--] [<path>…]

    Jest to synonimem poprzedniej formy. Pominięcie <commit>jednej strony będzie miało taki sam efekt, jak użycie HEADzamiast tego.

  • git diff [--options] <commit>...<commit> [--] [<path>…]

    Ten formularz służy do przeglądania zmian w gałęzi zawierającej i do drugiej <commit>, zaczynając od wspólnego przodka obu <commit>. „ git diff A...B” jest równoważne z „ git diff $(git-merge-base A B) B”. Możesz pominąć dowolną z nich <commit>, co ma taki sam efekt, jak użycie HEADzamiast tego.

Na wszelki wypadek, jeśli robisz coś egzotycznego, należy zauważyć, że wszystkie z <commit>powyższego opisu, z wyjątkiem dwóch ostatnich form, które używają notacji „..”, mogą być dowolne <tree>.

Aby uzyskać pełniejszą listę sposobów pisania <commit>, zobacz sekcję „OKREŚLANIE ZMIAN” w gitrevisions[7]. Jednak „różnica” dotyczy porównywania dwóch punktów końcowych, a nie zakresów, a notacje zakresów („ <commit>..<commit>” i „ <commit>...<commit>”) nie oznaczają zakresu zdefiniowanego w sekcji „OKREŚLANIE ZAKRESÓW” w gitrevisions[7].

Palec
źródło
Dla mnie $ git diff master...branchwyprodukowane fatal: ambiguous argument 'master...branch': unknown revision or path not in the working tree.- czy jest to polecenie zależne od wersji?
Joel Peltonen
Właściwie właśnie zdałem sobie sprawę, że "oddział" musi być nazwą twojego oddziału, pomyślałem, że to odniesienie do obecnego oddziału
Joel Peltonen
4
Masz rację, moja odpowiedź opiera się na wywołaniu oddziału branch. Zdecydowałem się trzymać nazwy, którą OP wybrał w pytaniu. Jeśli chcesz korzystać z bieżącej gałęzi, wymienić branchz HEAD.
Palec
14
Zauważ, że możesz użyć, git diff master...aby uniknąć określania gałęzi (bieżąca zostanie pobrana).
VasiliNovikov
1
Czy oryginalne polecenie działa po wymeldowaniu devel, @ChrisGuest? Prawdopodobnie Git utworzył dla Ciebie gałąź podczas realizacji transakcji, jako lokalną kopię zdalnego oddziału (zazwyczaj origin/devel). Gdyby tak było, git diff origin/devel...bugfix/API-353-api-allows-database-access-whendziałałby jeszcze przed kasą.
Palec
44

Oto, co zadziałało dla mnie:

git diff origin/master...

Pokazuje tylko zmiany między moją aktualnie wybraną gałęzią lokalną a zdalną gałęzią główną i ignoruje wszystkie zmiany w mojej gałęzi lokalnej, które pochodzą z zatwierdzeń scalających.

Jeshurun
źródło
Dla porównania, jeśli potrzebujesz referencji zatwierdzeń do zatwierdzeń, które zawierają te zmiany, użyj git cherry origin/master.
jaytibann
Jeśli to pokazuje garść śmieci, których się nie spodziewałeś, masterbyć może zmieniono bazę zestawów zatwierdzeń spod ciebie.
Michael - Where's Clay Shirky
21

Jak zauważyli również John Szakmeister i VasiliNovikov, najkrótszym poleceniem, aby uzyskać pełny różnicę z perspektywy mistrza w twojej gałęzi, jest:

git diff master...

To używa twojej lokalnej kopii master.

Aby porównać użycie określonego pliku:

git diff master... filepath

Przykład danych wyjściowych:

Przykładowe użycie

Andrew Schreiber
źródło