2016-02-12 20 views
6

Używam:git diff przemianowany/przeniesiony i zmodyfikowane pliki, ale przejdź przemianowany/przeniesiony i identyczne pliki

git diff HEAD --diff-filter=R -M 

z meldunku zewnętrznego narzędzia diff aby zobaczyć pliki, które zostały obie nazwy zostały zmienione/przenosić i modyfikować. Zawsze robię różnicę git przed wykonaniem zatwierdzenia, aby sprawdzić zarówno moją pracę, jak i poprawnie zmontować komunikat zatwierdzenia. Często będę zmieniać nazwy/przenosić pliki, co będzie również wymagać pewnych zmian ścieżek w plikach, które odwołują się do niektórych plików o zmienionej nazwie/przeniesionych.

Moim problemem jest to, że aby pokazać różnicę pliku, który został przemianowany, a następnie zmodyfikowany, git diff wyskakuje również kilka meldujących się okien dla plików, które zostały zmienione, ale nie zostały zmienione. To może być bardzo denerwujące. Jak uzyskać rozszerzenie git, aby pominąć pliki o zmienionej nazwie, ale niezmodyfikowane? Zamierzam zobaczyć wszystkie wymienione pliki jako zmienione/przeniesione, gdy wpisuję status git w znacznie czystszy sposób, więc nie chcę wyskakujących okienek dla identycznych plików z git diff.

Odpowiedz

1

Mam ten sam problem i wpadł aliasu że wystarczyły (używam git 2.8.3)

[alias] 
    difftoolr = "!git difftool \"[email protected]\" -- . $((git diff \"$1\" -M100% --diff-filter=R --name-only & git diff \"$1\" -M100% --diff-filter=R --name-only -R) | sed 's/\\(.*\\)/:(exclude)\\1/g') #" 

Jak używać:

difftoolr commit1..commit2 -M 

(patrz na dole po więcej przykładów)

Jak to działa:

Wyobraź sobie, że masz trzy pliki, których nazwa została zmieniona. Jeden z nich rzeczywiście się zmienił (więc chcesz go sprawdzić za pomocą twojego difftoola), ale pozostałe dwa są identyczne, z wyjątkiem ścieżki lub nazwy (i chcesz je zignorować).

(different) path/file.old -> newPath/file.new 
(identical) path/fileB.old -> newPath/fileB.new 
(identical) path/fileC.old -> newPath/fileC.new 

Co alias nie generuje specyfikacje ścieżkę, która wyraźnie wykluczyć fileB i fileC, to znaczy te pliki, które pomimo zmiany nazwy mają zawartość niezmienione.
Innymi słowy mamy do generowania tych filespecs:

-- . :(exclude)path/fileB.old :(exclude)newPath/fileB.new :(exclude)path/fileC.old :(exclude)newPath/fileC.new 

Zawiadomienie (chyba najtrudniejsza) części: stare ścieżki pliku i nowa ścieżka pliku musi być zarówno wyraźnie wyłączone.

Aby to zrobić, możemy wydać git diff z następującymi wytycznymi:

  • -M100%: wykonaj Zmienia nazwę. Co oznacza, że ​​git zakłada, że ​​dokonano jakiejś zmiany nazwy i uwzględni te informacje, aby dokonać porównań parami. Próg wynosi 100%, co nakazuje git rozważenie przemianowania tych plików, które mają dokładnie tę samą treść, ale nie te, które zostały zmienione.
  • --diff-filter=R: wyświetla tylko te pliki, które git uważa za zmienione, pomijając pozostałe.
  • --names-only: po prostu wypisz nazwy plików, nie ma innych informacji
  • -R: Odwróć. W jednym kawałku skryptu zamieniamy kolejność porównywania (rodzaj przełączania lewej i prawej strony), więc wypisze również stare nazwy plików. Na przykład dyrektywa -R wymienia plik newPath/fileB.new jako path/fileB.old.
  • ...sed...: i na końcu dołączamy dyrektywę wykluczającą :(exclude) na początek wszystkich nazw plików.

Aby zająć się innymi przypadkami, utworzyłem trzy różne aliasy (niezbyt eleganckie, chciałbym coś bardziej elastycznego), aby można było użyć do określenia różnych rodzajów porównania.

git difftoolr0 -M 
git difftoolr1 HEAD~1..HEAD -M 
git difftoolr2 HEAD --cached -M 

We wszystkich przypadkach „boki” (porównań zobowiązuje, --cached lub cokolwiek) musi być określona jako pierwszy parametr (y). Na przykład git difftoolr2 -M HEAD --cached nie będzie działać (ponieważ najpierw pojawia się -M).

[alias] 
# takes no parameter: sample usage: git difftoolr0 -M 
difftoolr0 = "!git difftool \"[email protected]\" -- . $((git diff -M100% --diff-filter=R --name-only & git diff -M100% --diff-filter=R --name-only -R) | sed 's/\\(.*\\)/:(exclude)\\1/g') #" 

# takes 1 parameter in first position: sample usage: git difftoolr1 HEAD~1..HEAD -M 
difftoolr1 = "!git difftool \"[email protected]\" -- . $((git diff \"$1\" -M100% --diff-filter=R --name-only & git diff \"$1\" -M100% --diff-filter=R --name-only -R) | sed 's/\\(.*\\)/:(exclude)\\1/g') #" 

# takes 2 parameters in first positions: sample usage: git difftoolr2 HEAD --cached -M 
difftoolr2 = "!git difftool \"[email protected]\" -- . $((git diff \"$1\" \"$2\" -M100% --diff-filter=R --name-only & git diff \"$1\" \"$2\" -M100% --diff-filter=R --name-only -R) | sed 's/\\(.*\\)/:(exclude)\\1/g') #" 

Wreszcie, BeyondCompare może również odpowiadać twoim potrzebom (i moim).
Pozwala to łatwo zmienić różnicę na "niestrukturalne".

Ta ostatnia usuwa foldery i pozostawia tylko imiona. Jeśli nazwa pliku jest taka sama (ale ścieżki mogą się różnić), są one traktowane jako dwie wersje tego samego pliku (na przykład path/file.png i newPath/file.png). W takim przypadku, jeśli zawartość nie uległa zmianie, można je łatwo pominąć za pomocą przycisku na górnym pasku.

W przypadku wystąpienia konfliktów "nazywania" (kilka plików po tej samej stronie porównania ma tę samą nazwę, pod różnymi ścieżkami), wybrałaby jedną z nich do porównania i zignorowała pozostałe.

Powiązane problemy