Как я могу просмотреть слияние в Git? - PullRequest
350 голосов
/ 28 апреля 2011

У меня есть ветка git (например, mainline), и я хочу объединиться в другую ветку разработки. Или я?

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

Пока лучшее, что я могу придумать, это merge --no-ff --no-commit, а затем diff HEAD.

Ответы [ 11 ]

371 голосов
/ 28 апреля 2011
  • git log ..otherbranch
    • список изменений, которые будут объединены в текущую ветвь.
  • git diff ...otherbranch
    • diff от общего предка (базы слияния) до главы того, что будет объединено. Обратите внимание на три точки , которые имеют особое значение по сравнению с двумя точками (см. Ниже).
  • gitk ...otherbranch
    • графическое представление ветвей с момента их объединения в последний раз.

Пустая строка подразумевает HEAD, поэтому просто ..otherbranch вместо HEAD..otherbranch.

Две или три точки имеют немного другое значение для diff, чем для команд, которые перечисляют ревизии (log, gitk и т. Д.). Для журнала и других две точки (a..b) означают все, что находится в b, но не a, а три точки (a...b) означают все, что находится только в одной из a или b. Но diff работает с двумя ревизиями, и там более простой случай, представленный двумя точками (a..b), представляет собой простую разницу от a до b, а три точки (a...b) означают разницу между общим предком и b (git diff $(git merge-base a b)..b).

241 голосов
/ 28 мая 2015

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

Стратегия 1: Безопасный путь - объединить временную ветку:

git checkout mybranch
git checkout -b mynew-temporary-branch
git merge some-other-branch

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

Это в основном пробный прогон.

Стратегия 2: когда вы определенно хотите объединиться, но только если нет конфликтов

git checkout mybranch
git merge some-other-branch

Если git сообщает о конфликтах (и ТОЛЬКО ЕСЛИ конфликты), вы можете сделать:

git merge --abort

Если слияние прошло успешно, вы не можете отменить его (только сброс).

Если вы не готовы к слиянию, используйте более безопасный способ выше.

[РЕДАКТИРОВАТЬ: 2016-ноябрь - я поменял стратегию 1 на 2, потому что похоже, что большинство людей ищут «безопасный путь». Стратегия 2 теперь больше напоминает, что вы можете просто прервать слияние, если у слияния есть конфликты, с которыми вы не готовы иметь дело. Имейте в виду, если читаете комментарии!]

18 голосов
/ 02 ноября 2012

Если вы похожи на меня, вы ищете эквивалент svn update -n.Следующее, кажется, делает трюк.Обратите внимание, что сначала нужно сделать git fetch, чтобы в вашем локальном репо были соответствующие обновления для сравнения.

$ git fetch origin
$ git diff --name-status origin/master
D       TableAudit/Step0_DeleteOldFiles.sh
D       TableAudit/Step1_PopulateRawTableList.sh
A       manbuild/staff_companies.sql
M       update-all-slave-dbs.sh

или если вы хотите использовать diff от вашей головы до пульта:

$ git fetch origin
$ git diff origin/master

ИМО, это решение намного проще и менее подвержено ошибкам (и, следовательно, намного менее рискованно), чем топовое решение, которое предлагает «объединить, а затем прервать».

6 голосов
/ 03 февраля 2013

Если вы уже загрузили изменения, мой фаворит:

git log ...@{u}

Это требует git 1.7.x Хотя я верю.Запись @{u} является «сокращением» для ветки upstream, поэтому она немного более универсальна, чем git log ...origin/master.

Примечание: если вы используете zsh и функцию расширенного glog, вам, вероятно, придется что-то делатькак:

git log ...@\{u\}
6 голосов
/ 05 сентября 2012

В дополнение к существующим ответам можно создать псевдоним для отображения различий и / или журнала до слияния.Во многих ответах пропускается fetch, который необходимо выполнить перед «предварительным просмотром» слияния;это псевдоним, который объединяет эти два шага в один (эмулируя что-то похожее на hg incoming / outgoing) Mercurial

Итак, основываясь на "git log ..otherbranch", вы можете добавить следующее к ~/.gitconfig:

...
[alias]
    # fetch and show what would be merged (use option "-p" to see patch)
    incoming = "!git remote update -p; git log ..@{u}"

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

    # what would be pushed (currently committed)
    outgoing = log @{u}..

И затем вы можете запустить "git incoming "чтобы показать много изменений, или" git incoming -p ", чтобы показать патч (то есть," diff ")," git incoming --pretty=oneline ", для краткой сводки и т. д. Затем вы можете (необязательно) выполнить" git pull "на самом деле слить.(Хотя, поскольку вы уже получили, слияние может быть выполнено напрямую.)

Аналогично, "git outgoing" показывает, что будет выдвинуто, если вы запустите "git push".

3 голосов
/ 28 февраля 2019

Большинство ответов здесь либо требуют чистого рабочего каталога и нескольких интерактивных шагов (плохо для сценариев), либо не работают для всех случаев, например прошлые слияния, которые уже вносят некоторые выдающиеся изменения в вашу целевую ветку, или вишневые пики, делающие то же самое.

Чтобы действительно увидеть, что изменится в ветви master, если вы объедините develop в нее, прямо сейчас:

git merge-tree $(git merge-base master develop) master develop

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

git merge-tree $(git merge-base master develop) master develop | colordiff | $(git var GIT_PAGER)

- https://git.seveas.net/previewing-a-merge-result.html

(спасибо Дэвиду Нормингтону за ссылку)

P.S:.

Если вы получите конфликты слияния, они будут отображаться с обычными маркерами конфликта в выходных данных, например ::1010

$ git merge-tree $(git merge-base a b ) a b 
added in both
  our    100644 78981922613b2afb6025042ff6bd878ac1994e85 a
  their  100644 61780798228d17af2d34fce4cfbdf35556832472 a
@@ -1 +1,5 @@
+<<<<<<< .our
 a
+=======
+b
+>>>>>>> .their

P.S. 2: на моей машине (vanilla Mac OS X) строка GIT_PAGER заканчивается использованием less, который не любит цветной ввод. Мне пришлось добавить export LESS=FRX к моему ~ / .bashrc, чтобы сделать его приемлемым. Благодаря https://unix.stackexchange.com/questions/153943/git-pager-is-less-but-what-is-causing-the-output-coloring

3 голосов
/ 06 апреля 2017

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

3 голосов
/ 28 апреля 2011

git log currentbranch..otherbranch выдаст вам список коммитов, которые войдут в текущую ветку, если вы сделаете слияние. Обычные аргументы в журнале, которые дают подробности о коммитах, дадут вам больше информации.

git diff currentbranch otherbranch даст вам разницу между двумя коммитами, которые станут одним. Это будет diff, который даст вам все, что будет объединено.

Поможет ли это?

2 голосов
/ 19 апреля 2016

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

Сказав это, вот метод, который прибывает незначительноclose:

git log TARGET_BRANCH...SOURCE_BRANCH --cherry

Это дает точное представление о том, какие коммиты попадут в слияние.Чтобы увидеть различия, добавьте -p.Чтобы увидеть имена файлов, добавьте любой из --raw, --stat, --name-only, --name-status.

Проблема с подходом git diff TARGET_BRANCH...SOURCE_BRANCH (см. Ответ Яна Худека) заключается в том, что вы увидитеразличия для изменений уже в вашей целевой ветви, если ваша исходная ветвь содержит перекрестные слияния.

1 голос
/ 28 апреля 2011

Может быть, это может вам помочь? git-diff-tree - Сравнивает содержимое и режим BLOB-объектов, найденных с помощью двух объектов дерева

...