Как проверить настоящий git diff перед слиянием с удаленной ветки? - PullRequest
51 голосов
/ 09 февраля 2011

Я хочу проверить реальную разницу между удаленной веткой и локальной веткой.Как я могу это сделать?

Выполнение приведенной ниже команды частично работает, но также показывает разницу новых изменений в моей локальной ветке.

git diff remote/branch

Ответы [ 3 ]

125 голосов
/ 30 июля 2011

Поскольку эта тема часто возникает и может сбивать с толку, не имея представления о том, как работает git, я подумал, что попытаюсь объяснить самый простой возможный случай, но с достаточной глубиной, чтобы новички могли справиться с этой задачей.чтобы провести дополнительное исследование.

Если вы настроили свой git-репозиторий с помощью обычного «клона» и у вас есть refspecs по умолчанию, это означает, что ваш пульт называется «origin», а вы извлекаете / выбираете из ветки «master»', вам иногда может понадобиться посмотреть, что находится в удаленном репозитории, прежде чем вытащить его.

Поскольку "git pull" выполняет автоматическое слияние (если нет конфликтов), было бы неплохо увидеть, что происходит" следующий.Если вы не знакомы с тем, как работает git и каким образом управляются refspecs, это может быть немного не интуитивно понятно.

Предположим, что кто-то вносит изменения в удаленный репозиторий (для иллюстрации добавьте строку в удаленный репозиторий, зафиксировав изменение и нажав на нее) и введите:

$ git diff origin/master

Вы, вероятно, не увидите никаких изменений;однако, если вы сделаете следующее:

$ git fetch; git diff ..origin/master 

вы увидите разницу между тем, что было передано в ваш локальный репозиторий git, и тем, что находится в удаленном репозитории.Вы НЕ увидите никаких изменений, которые находятся в вашей локальной файловой системе или размещены в вашем индексе.

Хорошо, почему мы это делаем?origin / master - это refspec (см. справочные страницы).Короче говоря, это то, к чему мы обращаемся для того, чтобы сравнивать, извлекать или извлекать данные и нажимать.Все следующее функционально эквивалентно:

origin/master
remotes/origin/master
refs/remotes/origin/master

Чтобы начать распутывать это, просто взгляните на структуру каталогов .git вашего репозитория.Типичный макет выглядит следующим образом:

.git/refs
.git/refs/heads
.git/refs/heads/master
.git/refs/remotes
.git/refs/remotes/origin
.git/refs/remotes/origin/HEAD
.git/refs/remotes/origin/master
.git/refs/tags

Посмотрите на .git / refs / remotes / origin / HEAD;в случае по умолчанию он будет указывать на ветвь, из которой вы будете тянуть, и нажимать на.В моем случае, поскольку я нахожусь на master, содержимое этого текстового файла выглядит следующим образом:

ref: refs/remotes/origin/master

Это говорит мне, что HEAD моего пульта идентифицируется по refspec 'refs / remotes / origin/ master '(который имеет псевдонимы, упомянутые выше).

Это нам мало что говорит;в каком состоянии удаленный репозиторий?Посмотрите на состояние удаленного мастера:

$ cat .git/refs/heads/master     
6d0fb0adfdfa5af861931bb06d34100b349f1d63

Хорошо, это хеш SHA1;вероятно коммит.Как это помещается в этот файл?Что ж, всякий раз, когда вы делаете извлечение или выборку, этот файл обновляется с использованием самого последнего коммита с удаленного устройства, которое было извлечено или извлечено.Это объясняет, почему мы должны git fetch до выполнения различий.Помните, git fetch просто обновляет вашу локальную копию удаленной ветви, но не объединяет ее с вашей рабочей копией.Это абсолютно безопасно.git fetch; git merge эквивалентно git pull.

Как только вы выполните выборку, git сможет увидеть самый последний коммит в удаленном репозитории на момент выборки.

Вы можете использовать различные комбинации спецификаторов для перехода ксмотрите свои разностные файлы по своему усмотрению (в следующих примерах локальная рабочая копия используется в качестве неявного первого коммита):

$ git diff remote/origin   
This shows the incoming remote additions as deletions; any additions in your local 
repository are shown as additions.

$ git diff ...remote/origin
Shows incoming remote additions as additions; the triple-dot excludes changes
committed to your local repository.

$ git diff ..remote/origin
Shows incoming remote additions as additions; the double-dot includes changes
committed to your local repository as deletions (since they are not yet pushed).

Информацию о ".." против "..." см. также git help diffкак отличная документация на выбор редакции git-scm: диапазоны коммитов Вкратце, для приведенных выше примеров синтаксис с двумя точками показывает все коммиты, доступные из origin / master, но не из вашей рабочей копии.Точно так же синтаксис с тройными точками показывает все коммиты, доступные из любого коммита (неявная рабочая копия, удаленный / источник), но не из обоих.

Я прохожу этот шаг за шагом, потому что я довольно новgit, и это именно тот тип вещей, который me смутил ... Я уверен, что эксперты по git могут найти недостатки с деталями ... Я просто надеюсь, что этот ответ преодолеет пробел для некоторых людейкто находит все различные посты немного краткими.

14 голосов
/ 09 февраля 2011

Из документации :

git diff [--options] <commit>...<commit> [--] [<path>…]

Эта форма предназначена для просмотра изменений на ветвь, содержащая и до второй <commit>, начиная с общего предок обоих <commit>. "git diff A ... B "эквивалентно" git diff $ (git-merge-base A B) B ". Вы можете опустить любой из <commit>, который имеет тот же эффект, что и при использовании HEAD.

ты пробовал это?

7 голосов
/ 09 февраля 2011

То, что вы хотите сделать, это как подсказал Евгений Бодунов:

git diff ...remote/branch

Это будет отличать изменения от удаленного / ветвления и игнорировать изменения от вашего текущего HEAD.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...