Jak pokazać zmiany, które zostały wprowadzone?

2137

Zainscenizowałem kilka zmian do zatwierdzenia; jak mogę zobaczyć różnicę wszystkich plików, które są przenoszone do następnego zatwierdzenia? Jestem świadomy statusu git , ale chciałbym zobaczyć rzeczywiste różnice - nie tylko nazwy plików, które są inscenizowane.

Widziałem, że strona podręcznika git-diff (1) mówi

git diff [--options] [-] […]

Ten formularz służy do przeglądania dokonanych zmian w stosunku do indeksu (obszar przejściowy dla następnego zatwierdzenia). Innymi słowy, różnice są co mógłby powiedzieć git kolejny dodatek do indeksu, ale nadal nie ma. Możesz wprowadzić te zmiany za pomocą git-add (1).

Niestety nie mogę tego zrozumieć. Musi być jakiś przydatny liniowiec, dla którego mógłbym stworzyć alias, prawda?

Frerich Raabe
źródło
76
git status -vteż działa. Zobacz moją odpowiedź poniżej
VonC
3
@VonC Zawsze używam tego, ale przesyłam strumieniowo less, jak w: git status -v | less- porcje do zarządzania :)
Mr Office

Odpowiedzi:

2607

Powinno to być po prostu:

git diff --cached

--cachedoznacza pokazanie zmian w pamięci podręcznej / indeksie (tj. zmiany etapowe) w stosunku do prądu HEAD. --stagedjest synonimem --cached.

--stagedi --cachednie wskazuje HEAD, tylko różnica w odniesieniu do HEAD. Jeśli wybierzesz opcję zatwierdzenia za pomocą git add --patch(lub git add -p), --stagedzwróci to, co zostało ustawione.

CB Bailey
źródło
35
Jeśli chcesz tylko nazwy plików, wykonaj następujące czynności git diff --name-only --cacheddla posta na stackoverflow.com/a/4525025/255187
Michel Hébert
4
Użyj tego git difftool --stagedzamiast zamiast git diff --stageduruchamiać domyślne narzędzie wizualnego porównywania dla każdego pliku. difftoolmożna zastąpić diffdowolnymi innymi argumentami.
LightCC
I możesz użyć git difftool --staged -ddo różnicowania dwóch katalogów w narzędziu wizualnym zamiast jednego pliku na raz.
Robert Bernstein,
ponieważ ten jest oznaczony jako odpowiedź i pokazuje najpierw, że powinien zawierać git diff na górze, a następnie git [[inne]], tylko moje 2 centy
Vitaliy Terziev
Aby wyświetlić zmiany w pojedynczym pliku git diff --cached -- <stagedfile>
pomostowym
1604

Prosta grafika czyni to jaśniejszym:

Proste różnice w Git

git diff

Pokazuje zmiany między katalogiem roboczym a indeksem. Pokazuje to, co zostało zmienione, ale nie jest wystawiane dla zatwierdzenia.

git diff --cached

Pokazuje zmiany między indeksem a HEAD (który jest ostatnim zatwierdzeniem w tej gałęzi). To pokazuje, co zostało dodane do indeksu i ustawione dla zatwierdzenia.

git diff HEAD

Pokazuje wszystkie zmiany między katalogiem roboczym a HEAD (w tym zmiany w indeksie). Pokazuje wszystkie zmiany od ostatniego zatwierdzenia, bez względu na to, czy zostały one wprowadzone w życie, czy nie.

Również :

365Git zawiera nieco więcej szczegółów .

Abizern
źródło
8
Obawiam się, że jest to naiwne (jak zwykle w przypadku każdego wyjaśnienia git). Jeśli masz lokalne modyfikacje foo.ci nie wykonujesz ich git add foo.c, niefoo.c ma tego w indeksie ; nie jest wystawiany na zatwierdzenie. Gdyby git diff foo.cnaiwnie porównać do pracy foo.cz indeksem, musiałby pokazać gigantyczną różnicę między pustym / nieistniejącym plikiem a całą zawartością foo.c. Tak więc, gdy plik nie istnieje w indeksie, git diffwycofuje się dla tego pliku przy użyciu HEADkopii.
Kaz
9
@Kaz ściśle mówiąc, indeks nie jest pustym kontem. Jest to wirtualna kopia, HEADna której wprowadzane są zmiany etapowe. Pamiętaj, że Git działa poprzez zapisywanie zmian, a nie przez zapisywanie całych plików. Gdy wykonujesz etap, plik przechowuje tylko wprowadzone zmiany. Jeśli indeks jest pusty, jak sugerujesz, nie wiedziałby, jak zapisać zmiany w indeksie i musiałby zapisać cały plik jako „nowo dodany” - co jest złe.
ADTC
8
@Kaz Zarówno indeks, jak i HEADbędą miały niezmienioną wersję foo.cpliku (nie są kopiami fizycznymi, ale tylko logicznymi kopiami dla ciebie i dla mnie. Dla Git są one tym samym strumieniem danych, do którego odnosi się każde zatwierdzenie, które kiedykolwiek dotyczyło tego pliku ). Więc kiedy robisz to git diffna całkowicie nieetapowanym, foo.cto tak naprawdę nie wraca do HEADtego, że robi różnicę z indeksem (który akurat zawiera dokładnie taką samą wersję pliku jak to HEADrobi). Więc grafika jest poprawna.
ADTC
2
Witam, chciałbym wiedzieć, co to znaczy „ indeks ” w tym kontekście? Dzięki!
Gab 是 好人
2
@TomRussell git status -vjest równoważny git diff --cached(plus git statusoczywiście)
szczęśliwemu
54

Jeśli interesuje Cię wizualny widok obok siebie, narzędzie do rozproszenia wizualnego porównania może to zrobić. Pokażą nawet trzy panele, jeśli zostaną wprowadzone niektóre, ale nie wszystkie zmiany. W przypadku konfliktu będą nawet cztery panele.

Zrzut ekranu przedstawiający rozproszenie ze zmianami etapowymi i nieetapowymi

Wywołaj to za pomocą

diffuse -m

w kopii roboczej Git.

Jeśli mnie zapytasz, najlepsza grafika różni się od dekady. Ponadto nie jest specyficzny dla Git: współpracuje z wieloma innymi VCS, w tym SVN, Mercurial, Bazaar, ...

Zobacz także: Pokazywać drzewo etapowe i robocze w git diff?

krlmlr
źródło
1
Dzięki, to wygląda na miłe narzędzie. Odkryłem, że Meld jest jak dotąd najlepszym narzędziem do różnicowania wizualnego dla Linuksa, ale brakowało mi możliwości różnicowania tekstu ze schowka - Meld wymaga plików do wprowadzania. Diffuse pozwala na to, a także na ręczne wyrównanie. Wypróbuję to przez chwilę.
Drew Noakes
Zepsuty link do diffuse.sourceforge.net, na razie użyj sourceforge.net/projects/diffuse .
user1133275,
1
brew install diffusedziała w systemie OS X. Nie wyświetla 3 okienek, jeśli zarówno zmiany niestacjonarne, jak i etapowe - czy miałeś na myśli zmiany, których jeszcze nie ma w indeksie?
Brent Faust
Jaką masz wersję rozproszoną? Tak - jeśli dodasz plik, a następnie zmodyfikujesz go lokalnie, powinien wyświetlić trzy panele.
krlmlr
Możesz także ustawić rozproszenie jako domyślny difftool i użyć tego wbudowanego mechanizmu / narzędzia / aliasu, aby go uruchomić. Zobacz moją odpowiedź tutaj: < stackoverflow.com/a/45684512/6501141 >
LightCC
50

Pamiętaj, że pokazuje git status -v także zmiany etapowe! (co oznacza, że ​​musisz mieć inscenizację - git add- niektóre zmiany. Bez zmian etapowych, bez różnic git status -v.
Robi to od Git 1.2.0, luty 2006 )

W swojej długiej formie (domyślnie) git statusma nieudokumentowaną opcję „szczegółową”, która faktycznie wyświetla różnicę między HEAD a indeksem.

I wkrótce będzie jeszcze bardziej kompletny: patrz „ Pokazywanie drzewa etapowego i roboczego w git diff? ” (Git 2.3.4+, II kw. 2015):

git status -v -v
VonC
źródło
Ostatnia linia powinna byćgit diff HEAD
artur
2
@artur dlaczego? Celem odpowiedzi jest wspomnienie, które git status -vvobejmuje również to, co git diff HEADrobi.
VonC
Nie działa na git version 1.8.3.1. Wiem, że jest stary, ale jeśli to możliwe, zwróć uwagę na datę wprowadzenia tej flagi.
onebree
2
@onebree 1.8.3.1 to czerwiec 2013, naprawdę stary. Ale git status -vjest starszy ( github.com/git/git/commit/… , git 1.2.0, luty 2006!). Zauważ, że wyświetla różnicę między indeksem a HEAD: jeśli dodałeś coś do indeksu (nie git add), to git status -vnie wyświetliłby żadnej różnicy. git status -v -vjest nowszy (Git 2.3.4, marzec 2015)
VonC
@VonC to był mój błąd ... zrobiłem git diff -v.
onebree
25

Możesz użyć tego polecenia.

git diff --cached --name-only

--cachedOpcja git diffznaczy dostać wystawił pliki, a --name-onlyśrodki opcja dostać tylko nazwy plików.

Yash Patadia
źródło
2
Edytuj, podając więcej informacji. Odradzane są tylko kody i odpowiedzi „wypróbuj to”, ponieważ nie zawierają one treści, które można przeszukiwać, i nie wyjaśniają, dlaczego ktoś powinien „wypróbować”.
abarisone
2
Nie jestem pewien, dlaczego miałbym tego chcieć, z --name-onlyopcją równie dobrze mógłbym użyć zwykłegogit status
Simon Forsberg
16

Od wersji 1.7 i nowszych powinno to być:

git diff --staged
ML13
źródło
15

UŻYWANIE NARZĘDZIA WIZUALNEGO DIFF

Domyślna odpowiedź (w wierszu poleceń)

Najważniejsze odpowiedzi tutaj poprawnie pokazują, jak wyświetlić buforowane / przemieszczane zmiany w Index:

$ git diff --cached

lub $ git diff --stagedktóry jest pseudonimem.


Zamiast tego uruchamia się narzędzie Visual Diff

Domyślna odpowiedź wypluwa zmiany w git bash (tj. W wierszu poleceń lub w konsoli). Dla tych, którzy wolą wizualną reprezentację różnic między plikami etapowymi, w git dostępny jest skrypt, który uruchamia wizualne narzędzie różnicowania dla każdego oglądanego pliku, zamiast pokazywać je w wierszu poleceń, o nazwie difftool:

$ git difftool --staged

Robi to tak samo, jak za git diff --stagedkażdym razem, gdy uruchamiane jest narzędzie diff (tj. Za każdym razem, gdy plik jest przetwarzany przez diff), uruchomi domyślne narzędzie wizualne diff (w moim środowisku jest to kdiff3 ).

Po uruchomieniu narzędzia skrypt git diff zatrzyma się do momentu zamknięcia narzędzia wizualnego porównywania. Dlatego musisz zamknąć każdy plik, aby zobaczyć następny.


Zawsze możesz używać difftoolzamiast diffpoleceń git

Dla wszystkich twoich potrzeb wizualnego różnicowania, git difftoolbędzie działać zamiast każdego git diffpolecenia, w tym wszystkich opcji.

Na przykład, aby uruchomić wizualne narzędzie do porównywania bez pytania, czy zrobić to dla każdego pliku, dodaj -yopcję (myślę, że zwykle będziesz tego chciał !!):

$ git difftool -y --staged

W takim przypadku będzie pobierał każdy plik w wizualnym narzędziu porównywania, jeden po drugim, wyświetlając następny plik po zamknięciu narzędzia.

Lub spojrzeć na różnicę określonego pliku, który jest umieszczony w Index:

$ git difftool -y --staged <<relative path/filename>>

Wszystkie opcje znajdziesz na stronie man:

$ git difftool --help


Konfigurowanie narzędzia Visual Git

Aby użyć wizualnego narzędzia git innego niż domyślny, użyj -t <tool>opcji:

$ git difftool -t <tool> <<other args>>

Lub zobacz stronę podręcznika difftool, aby dowiedzieć się, jak skonfigurować git, aby używał innego domyślnego narzędzia do wizualnego porównywania.


Przykładowe .gitconfigwpisy dla vscode jako narzędzia porównywania / scalania

Część konfiguracji difftool obejmuje zmianę .gitconfigpliku, albo za pomocą komend git, które zmieniają go za sceną, albo bezpośrednio go edytować.

Możesz go znaleźć .gitconfigw swoim katalogu domowym, na przykład ~w c:\users\<username>systemie Unix lub normalnie w systemie Windows).

Lub możesz otworzyć użytkownika .gitconfigw domyślnym edytorze Git za pomocą git config -e --global.

Oto przykładowe wpisy mojego globalnego użytkownika .gitconfigdla VS Code jako narzędzia do porównywania i scalania:

[diff]
    tool = vscode
    guitool = vscode
[merge]
    tool = vscode
    guitool = vscode
[mergetool]
    prompt = true
[difftool "vscode"]
    cmd = code --wait --diff \"$LOCAL\" \"$REMOTE\"
    path = c:/apps/vscode/code.exe
[mergetool "vscode"]
    cmd = code --wait \"$MERGED\"
    path = c:/apps/vscode/code.exe
LightCC
źródło
14

Dla porównania obszaru pomostowego vs repozytorium (ostatnie zatwierdzenie)

 $git diff --staged

Polecenie porównuje $ git add fileNamezmiany etapowe ( ) z ostatnim zatwierdzeniem. Jeśli chcesz zobaczyć, co zainscenizowałeś, co przejdzie do następnego zatwierdzenia, możesz użyć git diff --staged. To polecenie porównuje zmiany etapowe z ostatnim zatwierdzeniem.

Dla porównania Porównanie pracy i pracy

$ git diff 

Polecenie porównuje zawartość katalogu roboczego z tym, co znajduje się w obszarze testowym. Ważne jest, aby pamiętać, że git diff sam w sobie nie pokazuje wszystkich zmian dokonanych od czasu ostatniego zatwierdzenia - tylko zmiany, które są wciąż nieetapowane. Jeśli wprowadziłeś wszystkie zmiany ( $ git add fileName), git diff nie da ci żadnych wyników.

Ponadto, jeśli wykonasz etap pliku ( $ git add fileName), a następnie go edytujesz, możesz użyć git diff, aby zobaczyć zmiany w pliku, które są przemieszczane i zmiany, które nie są przenoszone.

Goyal Vicky
źródło
„Dla porównania Porównanie pracy z repozytorium $ git diff . Jestem prawie pewien, że git diffporównuje między Working a Staging. Zobacz stackoverflow.com/a/1587952
wisbucky
8

Jeśli masz zamiar wycelować w gałąź zdalnego repo, a twoje pierwsze przejście w dzienniku zmian zatwierdzenia było niepełne, możesz poprawić instrukcję zatwierdzenia przed wypychaniem w ten sposób.

Lokalnie

... dokonaj zmian ...

git diff # look at unstaged changes

git commit -am"partial description of changes"

... przywołuje więcej zmian niewymienionych w commit ...

git diff origin / master # spójrz na zmiany etapowe, ale nie wypchnięte

... zmienić etapowe oświadczenie zatwierdzenia ...

git commit --amend -m"i missed mentioning these changes ...."

git push
Marc Condon
źródło
7

Jeśli masz więcej niż jeden plik ze zmianami etapowymi, bardziej praktyczne może być użycie git add -i, a następnie wybranie 6: diffi wybranie pliku (ów), który Cię interesuje.

Fred Schoen
źródło
6

Domyślnie git diff służy do pokazywania zmian, które nie są dodawane do listy zaktualizowanych plików git. Ale jeśli chcesz, aby pokazać zmiany, które są dodawane lub stagged wtedy trzeba zapewnić dodatkowe opcje, które pozwolą git wie, że jesteś zainteresowany stagged lub dodanych plików diff .

$ git diff          # Default Use
$ git diff --cached # Can be used to show difference after adding the files 
$ git diff --staged # Same as 'git diff --cached' mostly used with latest version of git 

Przykład

$ git diff 
diff --git a/x/y/z.js  b/x/y/z.js index 98fc22b..0359d84 100644
--- a/x/y/z.js 
+++ b/x/y/z.js @@ -43,7 +43,7 @@ var a = function (tooltip) {

-        if (a)
+        if (typeof a !== 'undefined')
             res = 1;
         else
             res = 2;

$ git add x/y/z.js
$ git diff
$

Po dodaniu plików nie można użyć domyślnej opcji „git diff”. Musisz wykonać następujące czynności: -

$ git diff --cached
diff --git a/x/y/z.js  b/x/y/z.js index 98fc22b..0359d84 100644
    --- a/x/y/z.js 
    +++ b/x/y/z.js @@ -43,7 +43,7 @@ var a = function (tooltip) {

    -        if (a)
    +        if (typeof a !== 'undefined')
                 res = 1;
             else
                 res = 2;
Deepak Dixit
źródło
2

git guii git-colasą narzędziami graficznymi, które pozwalają przeglądać indeks i manipulować nim. Oba zawierają proste wizualne różnice dla plików przemieszczanych, a git-colatakże mogą uruchamiać bardziej zaawansowane narzędzie wizualnego porównywania.

Zobacz moją ściśle powiązaną odpowiedź na stronie Jak usunąć plik z indeksu w git? , a także ten oficjalny katalog klientów Git - GUI .

nobar
źródło
0

Pomyśl także o gitknarzędziu, wyposażonym w git i bardzo przydatnym, aby zobaczyć zmiany

sam
źródło