Получение разницы между двумя репозиториями


184

Как мы можем получить разницу между двумя git-репозиториями?

Сценарий: у нас есть repo_a и repo_b. Последний был создан как копия repo_a. После этого в обоих хранилищах произошла параллельная разработка. Есть ли способ, которым мы можем перечислить различия текущих версий этих двух репозиториев?


Ответы:


250

В 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

3
Что если вам нужно сравнить repo_a / master с определенным тегом repo_b?
Дэвид Торрес

2
не работает для меня, это бросает: fatal: неоднозначный аргумент 'remotes / b / master': неизвестная ревизия или путь не в рабочем дереве. Используйте '-', чтобы отделить пути от ревизий, например так: 'git <command> [<revision> ...] - [<file> ...]' Есть идеи здесь?
Эндрю Хекин

2
Я получаю то же самое, что и @AndrewHeekin. у кого-нибудь есть решение?
парламент

4
Кажется, мне нужно указать, origin/masterа не голые master. Кроме того, это находит разницу между основными ветвями, так что, если вы хотите найти все ветви, которые отличаются? Например, чтобы проверить состояние резервной копии репозитория?
Давид А

1
Можете ли вы объяснить, что делает каждая строка? Спасибо !
Энрике

34

Мелд может сравнить каталоги:

meld directory1 directory2

Просто используйте каталоги двух репозиториев git, и вы получите хорошее графическое сравнение:

введите описание изображения здесь

Когда вы нажимаете на один из синих пунктов, вы можете увидеть, что изменилось.


1
Мелд зависает, в то время как сравнивает проекты в моем решении VS, BeyondCompare - нет.
Саша Бонд

4
в OSX: дифф -rq folder1 folder2
Mark

1
Замечательная ссылка! Очень простая программа, сейчас я использую ее в качестве моей разностной программы для OSX.
dmanexe

1
Это абсолютно прекрасно! Спасибо, что поделился.
Шихаб Хан

Я не уверен, что meld способен обрабатывать файлы, которые игнорируются git - вы должны учитывать это при его использовании
noamgot

11

Вы можете сначала добавить другое репо в качестве удаленного к текущему репо:

git remote add other_name PATH_TO_OTHER_REPO

затем возьмите брач с этого пульта:

git fetch other_name branch_name:branch_name

это создает эту ветвь как новую ветку в вашем текущем репо, и вы можете сравнить эту ветку с любой из ваших ветвей, например, чтобы сравнить текущую ветку с новой веткой (имя_рукава):

git diff branch_name

8

После того как вы обе ветви в одном хранилище вы можете сделать git diff. И получить их в одном хранилище так же просто, как

git fetch /the/other/repo/.git refs/heads/*:refs/remotes/other/*

Есть ли способ сделать историю выбора вишни с небольшими изменениями: например, в удаленном репо файл помещается в один каталог, но я хочу применить изменения к тому же файлу, который находится в другом каталоге локального репо?
Евгений Коньков

Если вы говорите о небольших изменениях, я думаю, что проще всего будет просто сделать diff и затем применить его к другому файлу с помощью patch.
Майкл Крелин - хакер

Патч не применяется из-за разных имен файлов, несмотря на то, что это те же файлы
Евгений Коньков

О, я думал только о разных каталогах, а не об именах файлов (каталоги могут быть легко обработаны с помощью опций патча). Ну, для имен файлов я бы просто изменил их вручную или через скрипт. Тем не менее, я не говорю, что нет лучшего решения, просто то, что я могу придумать, никуда не копаясь.
Майкл Крелин - хакер

что если я захочу сравнить все ветки?
эндолит

7
git diff master remotes/b

Это неверно remotes/bэто удаленная, но не ветка.

Чтобы заставить это работать, я должен был сделать:

git diff master remotes/b/master

2
Это действительно должен быть комментарий к соответствующему ответу.
EntangledLoops

6

Смотрите http://git.or.cz/gitwiki/GitTips , раздел «Как сравнить два локальных репозитория» в разделе «Общие».

Короче говоря, вы используете переменную среды GIT_ALTERNATE_OBJECT_DIRECTORIES для доступа к базе данных объектов другого репозитория и используете git rev-parse с--git-dir / GIT_DIR для преобразования символического имени в другом репозитории в идентификатор SHA-1.

Современная версия будет выглядеть примерно так (при условии, что вы находитесь в 'repo_a'):

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

где ../repo_b/.gitпуть к объектной базе данных в repo_b (это был бы repo_b.git, если бы это был пустой репозиторий). Конечно, вы можете сравнивать произвольные версии, а не только заголовки.


Обратите внимание, что если repo_a и repo_b - это один и тот же репозиторий, может оказаться более целесообразным поместить их обоих в один и тот же репозиторий, либо используя « git remote add -f ...» для создания псевдонимов для репозитория для повторных обновлений, либо отключив « git fetch ...»; как описано в других ответах.


5

Я использую PyCharm, который имеет большие возможности для сравнения папок и файлов.

Просто откройте родительскую папку для обоих репозиториев и дождитесь индексации. Затем вы можете использовать правую кнопку мыши на папке или файле Compare to...и выбрать соответствующую папку / файл на другой стороне.

Он показывает не только какие файлы отличаются, но и их содержимое. Гораздо проще, чем командная строка.


2

Лучше всего иметь оба репозитория на локальном компьютере и использовать команду linux diff с двумя каталогами в качестве параметров:

diff -r repo-A repo-B


2
Единственный способ сделать это полезным - переименовать один из каталогов .git. это сводит к двум строкам страницы различий, которые не имеют значения. Был там, сделал это, пришел сюда в поисках лучшего ответа.
hildred

2

Простой способ сделать это, не касаясь конфигурации вашего пульта. Из репо А в мастер (предположим, вы хотите сравнить основные филиалы):

git fetch path/to/repo_b.git master
git diff FETCH_HEAD

0

Вы можете использовать следующую команду:

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

или для бок о бок вы можете использовать:

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

В случае раскрашивания каждого файла различий вы можете использовать:

diff -x .git -W200 -y -r repo-A repo-B | sed -e "s/\(^diff .*\)/\x1b[31m\1\x1b[0m/"

основанный на решении @ Andrew-Heekin
Джерард

0

Напоминание самому себе ... сначала загрузите, иначе хранилище не имеет локального хэша (наверное).

Шаг 1. Настройте пульт дистанционного управления и выше ^

Дифференцирование одного файла следует этой схеме:

git diff localBranch uptreamBranch --spacepath / singlefile

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.