Rozpoznanie różnicy między dwoma repozytoriami

184

Jak możemy poznać różnicę między dwoma repozytoriami git?

Scenariusz: mamy repo_a i repo_b. Ten ostatni został utworzony jako kopia repo_a. Później nastąpił równoległy rozwój obu repozytoriów. Czy jest sposób, abyśmy mogli wymienić różnice między aktualnymi wersjami tych dwóch repozytoriów?

sanjayav
źródło
2
możliwy duplikat Jak mogę porównać dwa repozytoria git?
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功

Odpowiedzi:

250

W repo_a:

git remote add -f b path/to/repo_b.git
git remote update
git diff master remotes/b/master
git remote rm b
iamamac
źródło
3
Co jeśli chcesz porównać repo_a / master z określonym tagiem repo_b?
David Torres,
2
nie działa dla mnie, rzuca: fatal: niejednoznaczny argument 'zdalne / b / master': nieznana wersja lub ścieżka nie znajduje się w drzewie roboczym. Użyj znaku „-”, aby oddzielić ścieżki od wersji, na przykład: „git <command> [<revision> ...] - [<file> ...]” Jakieś pomysły?
Andrew Heekin
2
Dostaję to samo, co @AndrewHeekin. Czy ktoś ma rozwiązanie?
parlament
4
Wydaje mi się, że potrzebuję origin/masterraczej sprecyzowania niż nagiego master. Znajduje to również różnicę między gałęziami głównymi, więc co zrobić, jeśli chcesz znaleźć wszystkie inne gałęzie? Np. Aby sprawdzić stan kopii zapasowej repozytorium?
davidA
1
Czy możesz wyjaśnić, co robi każda linia? Dzięki !
Enrique
34

Meld może porównywać katalogi:

meld directory1 directory2

Po prostu użyj katalogów dwóch repozytoriów git, a otrzymasz ładne porównanie graficzne:

wprowadź opis obrazu tutaj

Kiedy klikniesz na jeden z niebieskich elementów, możesz zobaczyć, co się zmieniło.

Martin Thoma
źródło
1
Połączenie zawiesza się podczas porównywania projektów w moim rozwiązaniu VS, BeyondCompare nie.
Sasha Bond
4
w OSX: diff -rq folder1 folder2
Mark
1
Cudowny link! Bardzo prosty program, teraz używam go jako mojego programu porównującego dla OSX.
dmanexe
1
To jest absolutnie cudowne! Dzięki za udostępnienie.
Shihab Khan
Nie jestem pewien, czy meld jest w stanie obsłużyć pliki, które są ignorowane przez gita - powinieneś wziąć to pod uwagę podczas korzystania z niego
noamgot
11

Możesz najpierw dodać inne repozytorium jako zdalne do bieżącego repozytorium:

git remote add other_name PATH_TO_OTHER_REPO

następnie pobierz brach z tego pilota:

git fetch other_name branch_name:branch_name

spowoduje to utworzenie tej gałęzi jako nowej gałęzi w obecnym repozytorium, a następnie możesz porównać tę gałąź z dowolną gałęzią, na przykład, aby porównać bieżącą gałąź z nową gałęzią (nazwa_gałęzi):

git diff branch_name
M.Kouchi
źródło
8

Gdy masz już obie gałęzie w jednym repozytorium, możesz wykonać plik git diff. A pobranie ich w jednym repozytorium jest równie łatwe jak

git fetch /the/other/repo/.git refs/heads/*:refs/remotes/other/*
Michael Krelin - haker
źródło
Czy jest sposób, aby wybrać historię z małą zmianą: Na przykład w zdalnym repozytorium plik jest umieszczony w jednym katalogu, ale chcę zastosować zmiany do tego samego pliku, ale który jest umieszczony w innym katalogu w lokalnym repozytorium?
Eugen Konkov
Jeśli mówisz o małej zmianie, myślę, że najłatwiej byłoby po prostu utworzyć różnicę, a następnie ponownie zastosować ją do innego pliku za pomocą łatki.
Michael Krelin - haker
Łatka nie została zastosowana z powodu różnych nazw plików, mimo że są to te same pliki
Eugen Konkov,
Och, myślałem tylko o różnych katalogach, a nie nazwach plików (katalogi można łatwo obsługiwać za pomocą opcji łatek). Cóż, nazwy plików zmieniłem ręcznie lub za pomocą skryptu. To powiedziawszy, nie mówię, że nie ma lepszego rozwiązania, tylko to, co mogę wymyślić bez kopania w dowolnym miejscu.
Michael Krelin - haker
co jeśli chcę porównać wszystkie gałęzie?
endolit
7
git diff master remotes/b

To jest niepoprawne. remotes/bto odległy, ale nie oddział.

Aby to zadziałało, musiałem zrobić:

git diff master remotes/b/master
James
źródło
2
To naprawdę powinien być komentarz do odpowiedniej odpowiedzi.
EntangledLoops
6

Zobacz http://git.or.cz/gitwiki/GitTips , sekcja „Jak porównać dwa lokalne repozytoria” w sekcji „Ogólne”.

Krótko mówiąc, używasz zmiennej środowiskowej GIT_ALTERNATE_OBJECT_DIRECTORIES, aby mieć dostęp do bazy danych obiektów innego repozytorium, i używasz git rev-parse z --git-dir/ GIT_DIR do konwersji nazwy symbolicznej w innym repozytorium na identyfikator SHA-1.

Nowoczesna wersja wyglądałaby mniej więcej tak (zakładając, że jesteś w 'repo_a'):

GIT_ALTERNATE_OBJECT_DIRECTORIES = .. / repo_b / .git / objects \
   git diff $ (git --git-dir = .. / repo_b / .git rev-parse --verify HEAD) HEAD

gdzie ../repo_b/.gitjest ścieżką do bazy danych obiektów w repo_b (byłoby to repo_b.git, gdyby było to czyste repozytorium). Oczywiście możesz porównać dowolne wersje, nie tylko HEAD.


Zauważ, że jeśli repo_a i repo_b są tym samym repozytorium, bardziej sensowne może być umieszczenie ich obu w tym samym repozytorium, albo używając " git remote add -f ..." do stworzenia pseudonimu (-ów) dla repozytorium dla powtarzających się aktualizacji, albo odejdź " git fetch ..."; jak opisano w innych odpowiedziach.

Jakub Narębski
źródło
5

Używam PyCharm, który ma świetne możliwości porównywania folderów i plików.

Po prostu otwórz folder nadrzędny dla obu repozytoriów i poczekaj, aż się zindeksuje. Następnie możesz kliknąć prawym przyciskiem myszy folder lub plik Compare to...i wybrać odpowiedni folder / plik po drugiej stronie.

Pokazuje nie tylko, jakie pliki są różne, ale także ich zawartość. O wiele łatwiejsze niż wiersz poleceń.

Pan
źródło
2

Najlepszym rozwiązaniem jest posiadanie obu repozytoriów na komputerze lokalnym i użycie polecenia linux diff z dwoma katalogami jako parametrami:

diff -r repo-A repo-B

Andrew Heekin
źródło
2
Jedynym sposobem uczynienia tego użytecznym jest zmiana nazwy jednego z katalogów .git. redukuje to do dwóch wierszy stron różnic, które nie mają znaczenia. Byłem tam, zrobiłem to, przybyłem tutaj, szukając lepszej odpowiedzi.
hildred
2

Łatwy sposób na zrobienie tego bez dotykania konfiguracji pilota. Z repozytorium A, w głównym (załóżmy, że chcesz porównać główne gałęzie):

git fetch path/to/repo_b.git master
git diff FETCH_HEAD
jorisv92
źródło
0

Możesz użyć następującego polecenia:

diff -x .git -r repo-A repo-B

lub obok siebie możesz użyć:

diff -x .git -W200 -y -r repo-A repo-B

W przypadku kolorowania każdego pliku różnicowego możesz użyć:

diff -x .git -W200 -y -r repo-A repo-B | sed -e "s/\(^diff .*\)/\x1b[31m\1\x1b[0m/"
Gerard
źródło
w oparciu o rozwiązanie @ andrew-heekin
Gerard
0

Przypomnienie o samodzielnym ... pobierz najpierw, w przeciwnym razie repozytorium nie ma lokalnego skrótu (chyba).

krok 1. Skonfiguruj nadrzędnego pilota zdalnego sterowania i wyższego ^

porównywanie pojedynczego pliku przebiega według tego wzorca:

git diff localBranch uptreamBranch --spacepath / singlefile

git diff master upstream/nameofrepo -- src/index.js

Hillsie
źródło