Jak „pokazać git” zatwierdzenie scalania z połączonym wyjściem różnicowym, nawet jeśli każdy zmieniony plik zgadza się z jednym z rodziców?


186

Po wykonaniu „prostego” scalenia (jednego bez konfliktów) git showzwykle pokazuje tylko coś podobnego

commit 0e1329e551a5700614a2a34d8101e92fd9f2cad6 (HEAD, master)
Merge: fc17405 ee2de56
Author: Tilman Vogel <email@email>
Date:   Tue Feb 22 00:27:17 2011 +0100

Merge branch 'testing' into master

Wynika to z tego, że do scalania git showużywa połączonego formatu różnicowego, który pomija pliki, które zgadzają się z jedną z wersji nadrzędnych.

Czy istnieje sposób, aby zmusić git, aby nadal pokazywał wszystkie różnice w połączonym trybie różnicowym?

Wykonanie git show -mspowoduje pokazanie różnic (przy użyciu różnic par odpowiednio między nową i wszystkimi wersjami nadrzędnymi), ale wolałbym mieć to z różnicami oznaczonymi +/- w odpowiednich kolumnach, jak w trybie łączonym.


1
@ Tilman Vogel: przejrzyj zaakceptowaną odpowiedź - Wygląda na to, że są lepsze odpowiedzi
Jayan

1
@Jayan Podczas gdy inne odpowiedzi są bardziej popularne, ponieważ zawierają użyteczne wskazówki, w rzeczywistości nie zbliżają się do mojego problemu, ponieważ robią tylko dwukierunkowe różnice. Szukałem trójdrożnego mechanizmu różnicowego.
Tilman Vogel

Odpowiedzi:


-3

Nie, nie da się tego zrobić git show. Ale z pewnością byłoby to czasem miłe i prawdopodobnie byłoby względnie łatwe do zaimplementowania w kodzie źródłowym git (w końcu musisz po prostu powiedzieć mu, aby nie wycinało tego, co uważa za obce wyjście), więc łatka, aby to zrobić prawdopodobnie zostałby zaakceptowany przez opiekunów git.

Uważaj jednak na to, czego sobie życzysz; połączenie gałęzi ze zmianą jednowierszową, która została rozwidlona trzy miesiące temu, nadal będzie miało ogromny różnicę w porównaniu z linią główną, a więc taka pełna różnica byłaby prawie całkowicie nieprzydatna. Dlatego git tego nie pokazuje.


12
Nie mów „nie da się tego zrobić” tak wyraźnie, jak to możliwe - zobacz inne odpowiedzi. Jest to bardzo mylące.
kgadek

1
git show HEAD ^ ... HEAD; # na rozwiązanie @ hesham_EE.
Michael Dimmitt

git show HEAD ~ 1 ... HEAD ~ 0 - tylko nazwa; # lepsza składnia. Do iterujących pr.
Michael Dimmitt,

256

Spójrz na komunikat zatwierdzenia:

commit 0e1329e551a5700614a2a34d8101e92fd9f2cad6 (HEAD, master)
Merge: fc17405 ee2de56
Author: Tilman Vogel <email@email>
Date:   Tue Feb 22 00:27:17 2011 +0100

Merge branch 'testing' into master

zauważ linię:

Merge: fc17405 ee2de56

weź te dwa identyfikatory zatwierdzenia i odwróć je. więc aby uzyskać żądaną różnicę, zrobiłbyś:

git diff ee2de56..fc17405

aby wyświetlić tylko nazwy zmienionych plików:

git diff --name-only ee2de56..fc17405

i aby je wyodrębnić, możesz dodać to do swojego gitconfig:

exportfiles = !sh -c 'git diff $0 --name-only | "while read files; do mkdir -p \"$1/$(dirname $files)\"; cp -vf $files $1/$(dirname $files); done"'

następnie użyj go, wykonując:

git exportfiles ee2de56..fc17405 /c/temp/myproject

Dzięki za sugestię, ale myślę, że to nie rozwiązuje mojego problemu. Ze względu na ograniczone znaczniki i formatowanie komentarzy dodałem swój komentarz do Twojej odpowiedzi. Przepraszam za to! Musi zostać sprawdzony, dopóki nie będzie widoczny.
Tilman Vogel,

6
Wygląda na to, że moja edycja została odrzucona. Podsumowując: Twój plik różnicowy nie pokazuje, które dodatki pochodzą z której gałęzi. I nie można rozróżnić, czy zmiany zostały dodane w drugiej, czy usunięte w pierwszej gałęzi.
Tilman Vogel,

45
Lepszym rozwiązaniem jest git diff fc17405...ee2de56- pokaże to wszystkie zmiany na ee2de56, które są osiągalne z zatwierdzeń na fc17405, co moim zdaniem jest tym, czego chcesz. Zwróć uwagę na 3 kropki zamiast dwóch.
Kris Nuttycombe,

1
@KrisNuttycombe 3 kropki i zamówienie. Twój komentarz jest tym, czego szukałem, co moim zdaniem bardziej przypomina to, czego chciał PO.
Izkata,

@KrisNuttycombe To jakoś nie działa git log, co nadal pokazuje wszystkie zatwierdzenia, podobnie jak ..wariant. ..i ...zrobić to samo log, ale dla diffnich są różne !? Jak uzyskać listę zatwierdzeń, które zostały scalone w tym oddziale?
Rudie,

77

Lepsze rozwiązanie (wspomniane przez @KrisNuttycombe):

git diff fc17405...ee2de56

dla zatwierdzenia scalania:

commit 0e1329e551a5700614a2a34d8101e92fd9f2cad6 (HEAD, master)
Merge: fc17405 ee2de56
Author: Tilman Vogel <email@email>
Date:   Tue Feb 22 00:27:17 2011 +0100

aby pokazać wszystkie zmiany, ee2de56które są dostępne po zatwierdzeniu fc17405. Zwróć uwagę na kolejność skrótów zatwierdzeń - jest taka sama, jak pokazano w informacjach dotyczących scalania:Merge: fc17405 ee2de56

Zwróć także uwagę na 3 kropki ...zamiast dwóch !

Aby wyświetlić listę zmienionych plików, możesz użyć:

git diff fc17405...ee2de56 --name-only

To właśnie byłem po +1.
geedoubleya

To faktycznie pokazuje wynik konfliktu scalania, podczas gdy druga odpowiedź nie.
Pod

12

Możesz utworzyć gałąź z HEAD ustawionym na jedno zatwierdzenie przed scaleniem. Następnie możesz wykonać:

git merge --squash testing

Spowoduje to scalenie, ale nie zatwierdzenie. Następnie:

git diff

5

Wygląda na to, że odpowiedziałem tutaj: https://public-inbox.org/git/7vd392ezhx.fsf@alter.siamese.dyndns.org/

W podobny sposób działa

$ git diff --cc $ M $ M ^ 1 $ M ^ 2 $ (git merge-base $ M ^ 1 $ M ^ 2)

powinien pokazywać połączoną łatkę, która wyjaśnia stan na poziomie $ M w stosunku do stanów zarejestrowanych u jego rodziców i bazy scalania.


czy wiesz, czy jakieś narzędzie można skonfigurować tak, aby wyświetlało taką różnicę równolegle, potencjalnie w kilku kolumnach (np. w oknie rozwiązywania konfliktu scalania IntelliJ)? Twoja odpowiedź jest dokładnie tym, czego szukałem
Max

@ Max Nie, obawiam się, że nie. Googling „n-way visual diff” zawiera pewne linki, więc spróbowałem tych.
max630

4

Myślę, że potrzebujesz po prostu „git show -c $ ref”. Wypróbowanie tego w repozytorium git na a8e4a59 pokazuje połączoną różnicę (znaki plus / minus w jednej z 2 kolumn). Jak wspomina instrukcja git-show, prawie deleguje się do „drzewa git diff”, więc te opcje wyglądają na przydatne.


3
Nie, dla „prostego” scalenia git show -c $refpokazuje takie same wyniki, jak cytowałem, tj. Żadnych różnic. -cwybiera połączony tryb różnicowy bardzo podobny do trybu domyślnego dla zatwierdzeń scalania, którym jest „--cc”, patrz git help showi git help diff-tree. Oba całkowicie pomijają pliki, które są zgodne z jedną z nadrzędnych wersji tego pliku.
Tilman Vogel

a8e4a59mam na myśli, że rzeczywiście nie należy do kategorii zatwierdzeń scalania. To zatwierdzenie scalania rzeczywiście zawiera jeden plik, który różni się od obu jego wersji nadrzędnych. Documentation/git-fast-import.txtma pewne rzeczy dodane od jednego rodzica, a niektóre od drugiego. Powoduje to, że dane wyjściowe są niepuste git diff-tree --cc. Wyświetlane są jednak tylko zmiany w tej „sprzecznej” sprawie. Wszystkie „czyste” wyniki scalania, spójrz git show -m a8e4a59, nie są wcale wyświetlane.
Tilman Vogel

1
@TilmanVogel: Dziękujemy za wskazanie, że „nieciekawe” scalenia plików są pomijane git show -c. ( man git-diff-treemówi „Co więcej, zawiera tylko pliki, które zostały zmodyfikowane od wszystkich rodziców”. Ale ja na pewno tego nie zauważyłem.)
Paul Whittaker

3

w twoim przypadku wystarczy

git diff HEAD^ HEAD^2

lub po prostu hash dla Ciebie:

git diff 0e1329e55^ 0e1329e55^2

4
Nie, to tylko zwykła dwukierunkowa różnica między obojgiem rodziców. Co ja z prośbą o to tryb, który jednocześnie pokazuje diff między git merge-base HEAD^ HEAD^2a HEAD^i HEAD^2w tym samym stylu, jak to się dzieje w przypadku plików, które zostały połączone z konfliktami.
Tilman Vogel

3

Jeśli zatwierdzenie scalania to zatwierdzenie 0e1329e5, jak wyżej, możesz uzyskać różnicę zawartą w tym scaleniu poprzez:

git diff 0e1329e5^..0e1329e5

Mam nadzieję, że to pomoże!


3

Jeśli siedzisz przy zatwierdzeniu scalania, to pokazuje różnice:

git diff HEAD~1..HEAD

Jeśli nie jesteś na zatwierdzeniu scalania, po prostu zamień HEAD na zatwierdzenie scalania. Ta metoda wydaje się najprostsza i najbardziej intuicyjna.


1
To nie jest wyjście „połączone diff”. Uzyskiwanie różnic między każdą parą rodziców a HEAD nie jest tutaj problemem.
Tilman Vogel

2

Możesz użyć komendy diff-tree z flagą -c. To polecenie pokazuje, jakie pliki uległy zmianie w zatwierdzeniu scalania.

git diff-tree -c {merged_commit_sha}

Dostałem opis flagi -c od Git-Scm :

Ta flaga zmienia sposób wyświetlania zatwierdzenia scalania (co oznacza, że ​​przydaje się tylko wtedy, gdy podano jedno z poleceń lub --stdin). Pokazuje różnice między poszczególnymi rodzicami dla wyniku scalania jednocześnie zamiast pokazywania różnic parowych między rodzicem a wynikiem pojedynczo (co robi opcja -m). Ponadto zawiera tylko pliki zmodyfikowane przez wszystkich rodziców.



1

Zbudowałem podejście ogólnego przeznaczenia do wykonywania różnych operacji na zatwierdzeniach scalania.

Krok pierwszy : Dodaj alias do git, edytując ~/.gitconfig:

[alias]
  range = "!. ~/.githelpers && run_on_merge_range"

Krok drugi : W ~/.githelperszdefiniuj funkcję bash:

run_on_merge_range() {
  cmd=$1; shift
  commit=$1; shift
  range=$(git show $commit | grep Merge: | awk '{print $2 "..." $3}')
  echo "git $cmd $range $@"
  if [ -z $range ]; then
    echo "No merge detected"
    exit 1
  fi
  git $cmd $range $@
}

Krok trzeci : zysk!

git range log <merge SHA> --oneline
git range diff <merge SHA> --reverse -p
git range diff <merge SHA> --name-only

Prawdopodobnie jest tu dużo miejsca na ulepszenia, po prostu zebrałem to razem, aby uniknąć irytującej sytuacji. Możesz śmiać się z mojej składni i / lub logiki bash.


Zauważ, że możesz chcieć zmienić „...” na „..” w „awk”, w zależności od tego, czego potrzebujesz i jakiej komendy używasz: stackoverflow.com/questions/462974/…
Nerdmaster
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.