2011-12-20 11 views
18

Czy istnieje sposób na sprawdzenie, czy dwa różnice lub poprawki są równoważne?Czy istnieje sposób porównania dwóch różnic lub poprawek?

Powiedzmy, że masz następujące git commit historię, gdzie dysponuje F i G są czysto rebaseable do E:

 G 
    /
A--B--C--D--E 
\ 
    F 

Ze względu na ograniczenia w naszym obecnym procesie wdrażania, mamy następujące, nieco pokrewny wykres (nie jest wersja kontrolowane)

   G' 
      /
------------E' 
      \ 
       F' 

F „i G” ostatecznie zostaną zastosowane do głowicy E”w niektórych być określona kolejność tak, że kończy się ona jak

------------E'--G'--F' 

Czy istnieje sposób na sprawdzenie, czy różnica z E 'na G' jest taka sama, jak łata wygenerowana przez zatwierdzenie git G z B?

W pełni zdaję sobie sprawę, że w idealnym świecie kontrola wersji rozwiązałaby ten problem, a my do tego dojdziemy, ale to nie jest miejsce, w którym obecnie się znajdujemy.

Można zasadniczo odtwarzać obie łatki na oddzielnych kasach i porównywać wyniki, ale wydaje się to dość niezgrabne. Porównanie samych diffów nie przyniesie skutku, ponieważ numery linii mogą się zmienić. Nawet jeśli G 'i F' byłyby ponownie wyeksportowane do E ', łatka dla F' ostatecznie byłaby zastosowana do G ', czyniąc różnicowy kontekst łatki inny.

+2

Próbowałaś diff na dyferencjału? – Geoffroy

+0

Gnu diff ma przełącznik wiersza poleceń do określania wyrażenia regularnego dla linii, które mają być ignorowane podczas generowania diff. – holygeek

+0

Dla partii, 'git patch-id' i' git cherry' (zobacz także opcje '--cherry *' dla logu git) mogą być użyte jako szybka odpowiedź, ale jest zbyt rygorystyczna i może uważać pewne drobne zmiany za ważne. Różnica różnic jest sposobem, aby przejść, gdy potrzebujesz pewnej odpowiedzi – max630

Odpowiedz

1

Chciałbym tylko niech git spróbować i zobaczyć:

git checkout E -b FG 
git cherry-pick F' G' 
git checkout E -b GF 
git cherry-pick G' F' 
git diff FG GF 
git branch -D FG GF 
+0

"Główne" zatwierdzenia nie są w kontroli wersji. W rzeczywistości nie są zobowiązaniami, są łatkami opartymi na prawdziwych zatwierdzeniach E i F. Ale mogą, ale nie muszą, być skażone przez inne dane (co testuję). –

+0

Czy możesz po prostu zastosować łatki? Diffy nie są stworzone, aby je odróżnić, ale git jest w tym naprawdę dobry. Może sytuacja z młotkiem/gwoździem, ale jestem pewien, że to zadziała. :) – dahlbyk

+0

Co masz na myśli "po prostu nałóż łatki"? Mam dwie różnice i chcę tylko zastosować łatę, jeśli są one równoważne. Jeśli nie, łatka nie powinna być w ogóle stosowana. –

23
diff <(git show COMMIT1SHA) <(git show COMMIT2SHA) 
+2

Czy możesz dodać kontekst, w jaki sposób to odpowiada na pytanie? – Chrismas007

+1

Porównuje (porównuje) dwie różnice (w tym przypadku różnice dwóch różnych zatwierdzeń). – mrbrdo

+1

Wprowadza różnicę w faktycznych zmianach dokonanych zatwierdzeń, a także metadanych zatwierdzeń (sha, author, date, commit itd.). Użyłem tego do sprawdzenia, czy dwa zatwierdzenia w oddzielnych oddziałach wprowadzają tę samą zmianę, aby mieć pewność, że mogę użyć jednego z nich do wyboru. –

0

Z korzyścią dla czytelnika, tutaj jest aktualizacja do the answer of @mrbrdo z trochę uszczypnąć:

  • Dodaje git sdiff alias dla łatwego dostępu do tego. sdiff oznacza show diff.
  • Zignoruj ​​przypisane etykiety nagłówków, używając przyrostka ^{}.
  • Pozwól diff opcje mają być używane jak -u itp

Run to raz w każdym z kont w której używają git:

git config --global alias.sdiff '!'"bash -c 'O=(); A=(); while x=\"\$1\"; shift; do case \$x in -*) O+=(\"\$x\");; *) A+=(\"\$x^{}\");; esac; done; g(){ git show \"\${A[\$1]}\" && return; echo FAIL \${A[\$1]}; git show \"\${A[\$2]}\"; }; diff \"\${O[@]}\" <(g 0 1) <(g 1 0)' --" 

Następnie można użyć tego:

git sdiff F G 

Należy pamiętać, że wymaga to bash wersja 3 lub nowsza.

Poradnik:

  • git config --global alias.sdiff dodaje alias o nazwie git sdiff do globalnego ~/.gitconfig.

  • ! uruchamia alias jako polecenia powłoki

  • bash -c musimy bash (lub ksh), jak <(..) nie działa w dash (aka. /bin/sh).

  • O=(); A=(); while x="$1"; shift; do case $x in -*) O+=("$x");; *) A+=("$x^{}");; esac; done; oddziela opcje (-something) i argumenty (wszystko inne). Opcje są w tablicy O, podczas gdy argumenty są w tablicy A. Zauważ, że wszystkie argumenty są również dołączone do atrybutu ^{}, który przeskakuje nad adnotacjami (takimi, że możesz używać znaczników z adnotacjami).

  • g(){ git show "${A[$1]}" && return; echo FAIL ${A[$1]}; git show "${A[$2]}"; }; tworzy funkcję pomocniczą, która ma git show dla pierwszego argumentu. Jeśli to się nie powiedzie, wypisuje "FAIL first-argument", a następnie wyprowadza drugi argument. To jest sztuczka, aby zmniejszyć narzut w przypadku awarii. (Właściwa managment błąd byłoby zbyt wiele.)

  • diff "${O[@]}" <(g 0 1) <(g 1 0)diff biegnie z podanych opcji w stosunku do pierwszego argumentu i drugi argument (ze wspomnianym FAIL błędów awaryjna do drugiego argumentu, aby zmniejszyć diff).

  • -- pozwala przekazać diff -opcje (-something) do tego aliasu/skryptu.

Bugs:

  • Ilość argumentów nie jest zaznaczona. Wszystko za drugim argumentem jest ignorowane, a jeśli dasz mu za mało, zobaczysz tylko FAIL lub nic.

  • Błędy działają trochę dziwnie i zakłócają wydruk. Jeśli ci się to nie podoba, uruchom go pod numerem 2>/dev/null (lub odpowiednio zmień skrypt).

  • Nie zwraca błędu, jeśli coś się zepsuje.

  • Prawdopodobnie chcesz domyślnie wprowadzić to do pagera.

Należy pamiętać, że to jest łatwe do zdefiniowania jeszcze kilka aliasów jak:

git config --global alias.udiff '!git sdiff -u' 
git config --global alias.bdiff '!git sdiff -b' 

git config --global alias.pager '!pager() { cd "$GIT_PREFIX" && git -c color.status=always -c color.ui=always "[email protected]" 2>&1 | less -XFR; }; pager' 
git config --global alias.ddiff '!git pager udiff' 

Mam nadzieję, że to nie musi być wyjaśnione dalej.

Więcej aliasów tak, może spojrzeć na my GitHub repo

Powiązane problemy