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

184

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

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

sanjayav
источник
2
Возможный дубликат Как я могу сравнить два репозитория git?
Сиро Сантилли 郝海东 冠状 病 六四 事件 法轮功

Ответы:

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
iamamac
источник
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
M.Kouchi
источник
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...и выбрать соответствующую папку / файл на другой стороне.

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

MRE
источник
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
jorisv92
источник
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/"
Gerard
источник
основанный на решении @ Andrew-Heekin
Джерард
0

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

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

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

git diff localBranch uptreamBranch --spacepath / singlefile

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

Hillsie
источник