Используя Git, как найти изменения между локальным и удаленным


152

Вот два разных вопроса, но я думаю, что они связаны.

  1. При использовании Git как узнать, какие изменения я зафиксировал локально, но еще не отправил в удаленную ветку? Я ищу что-то похожее на команду Mercurial hg outgoing.

  2. Когда я использую Git, как мне найти изменения, которые произошла в удаленной ветке перед выполнением проверки? Я ищу что-то похожее на команду Mercurial hg incoming.

Для второго: есть ли способ увидеть, что доступно, а затем выбрать те изменения, которые я хочу вытащить?


11
Глядя на ответы, кажется, что существует некоторая путаница относительно того, что hg incomingи на hg outgoingсамом деле делать. Ближайший эквивалент Git, который я нашел - это --dry-runопция. Просто git pull --dry-runи вы увидите список всех вещей, которые должны произойти.
Роман Старков

Ответы:


97

Git не может отправлять такую ​​информацию по сети, как Hg может. Но вы можете запустить git fetch(который больше похож , hg pullчем hg fetch) , чтобы получать новые коммиты из удаленных серверов.

Итак, если у вас есть ветвь с именем masterи удаленная origin, после запуска git fetchвы должны также вызвать ветку origin/master. Вы можете получить git logиз всех фиксаций , что masterдолжно быть надмножеством origin/masterделая git log master..origin/master. Обратить эти два, чтобы получить противоположное.

Мой друг, Дэвид Доллар, создал пару скриптов git shell для симуляции hg incoming/outgoing. Вы можете найти их на http://github.com/ddollar/git-utils .


113

Начиная с Git 1.7.0, существует специальный синтаксис, который позволяет вам в общем случае ссылаться на ветку upstream: @{u}или @{upstream}.

Чтобы подражать hg incoming:

git log ..@{u}

Чтобы подражать hg outgoing:

git log @{u}..

Я использую следующее incomingи outgoingпсевдонимы, чтобы упростить использование вышеуказанного:

git config --global alias.incoming '!git remote update -p; git log ..@{u}'
git config --global alias.outgoing 'log @{u}..'

git log .. @ {u} дает мне эти ошибки. (У меня есть и источник, и исходный репозиторий в моей конфигурации git). ошибка: не найдена восходящая ветвь для '' ошибка: не найдена восходящая ветвь для '..' ошибка: не найдена восходящая ветвь для '..' fatal: неопределенный аргумент '.. @ {u}': неизвестная ревизия или путь не указан рабочее дерево. Используйте '-', чтобы отделить пути от ревизий
Хенрик

6
Вы получите эти ошибки, если ваша локальная ветвь не настроена с апстримом. Чтобы исправить, беги git branch --set-upstream foo origin/foo.
Ричард Хансен

git log @{u}..перечисляет каждое изменение в репо для меня. Там нет, как они еще не существуют.
Роман Старков

@romkyns: возможно, в вашей локальной ветке неверная удаленная ветка настроена как восходящая. Убедитесь, что git rev-parse --symbolic-full-name @{u}печатает соответствующий удаленный справочник. Кроме того, git log @{u}..показаны коммиты, которые недоступны ветке upstream, которая может включать в себя коммиты, которые уже находятся в удаленном репозитории (если они достижимы по другой ссылке). Это произойдет сразу после того, как вы слились в уже выдвинутой ветке.
Ричард Хансен

@RichardHansen Боюсь, я слишком нуб, чтобы знать, что подходит для удаленной ссылки, однако это было только что клонированное репо, на котором я сделал только a checkout <somebranch>и merge <otherbranch>. В этот момент я сделал log @{u}..и увидел все изменения в списке.
Роман Старков

42

Не полный ответ, но git fetch извлечет удаленное хранилище и не сделает слияние. Затем вы можете сделать

git diff master origin / master


1
Работал для меня (но наоборот) -git diff origin/master master
Ник Grealy

34
  1. Используйте "git log origin..HEAD"

  2. Используйте "git fetch", а затем "git log HEAD..origin". Вы можете выбрать отдельные коммиты с помощью перечисленных идентификаторов коммитов.

Вышеприведенное предполагает, конечно, что «origin» - это имя вашей удаленной ветви отслеживания (как, если вы использовали клон с параметрами по умолчанию).


3
(И если вы не отслеживаете удаленную ветку, это «git log origin / master..HEAD».)
plindberg

4
«origin» - это не имя удаленной ветви отслеживания, это имя удаленного. И просто указание удаленного имени не работает, вы должны указать удаленную ветвь отслеживания, которая будет origin / master.
Робинст

22

Также есть, для сравнения всех веток:

git log --branches --not --remotes=origin

Вот что говорит об этом man-страница git log:

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

Выше для outgoing. Для incoming, только свопа:

git log --remotes=origin --not --branches

8

я бы сделал

$ git fetch --dry-run

для hg incomingи

$ git push --dry-run

для hg outgoing.


Извините, я упустил из виду, что это уже было сказано в качестве комментария к ФП.
Крис

1

Git-Out - это скрипт, который hg outgoingочень точно имитирует . Он анализирует вывод "push -n", поэтому он производит точный вывод, если вам нужно указать дополнительные аргументы для push.


0

мерзавец входящий

$ git fetch && git log ..origin/master --stat
OR
$ git fetch && git log ..origin/master --patch

мерзавец исходящий

$ git fetch && git log origin/master.. --stat
OR
$ git fetch && git log origin/master.. --patch

0

Когда ответы "git log" и @ {u} первоначально выдавали мне ошибки "неизвестной ревизии", я опробовал предложение Chris / romkyns о git push --dry-run.

Вы получите вывод, такой как «5905..4878 master-> master». 5905 - это последний коммит, который удаленный имеет и фиксирует через (и включая) 4878, который будет применен к удаленному.

Затем вы можете использовать 5905..4878 в качестве аргументов нескольких других команд git для получения более подробной информации:

git diff 5905..4878 # Gives full code changes in diff style

git log --online 5905..4878 # Displays each commit's comment

-1

Когда вы выполняете git fetch, все содержимое, включая ветви, теги (ссылки), временно сохраняются в .git / FETCH_HEAD, содержимое которого можно просмотреть с помощью команды: git log FETCH_HEAD Если вы не используете суффикс -a с git fetch, тогда по умолчанию , Содержимое FETCH_HEAD будет перезаписано новым содержимым. Из этого содержимого вы можете просмотреть и решить, в какую ветку вы хотите объединить их, если вы это сделаете, или вы можете просто выбрать вишню, если вы хотите всего несколько коммитов из того, что было получено извлечением.

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