Я объединяюсь в удаленной ветке, которая может иметь много конфликтов. Как я могу определить, будут ли конфликты или нет?
Я не вижу ничего похожего --dry-run
на git-merge
.
Я объединяюсь в удаленной ветке, которая может иметь много конфликтов. Как я могу определить, будут ли конфликты или нет?
Я не вижу ничего похожего --dry-run
на git-merge
.
Ответы:
Как отмечалось ранее, передайте --no-commit
флаг, но чтобы избежать фиксации перемотки вперед, также передайте --no-ff
, например, так:
$ git merge --no-commit --no-ff $BRANCH
Для изучения поэтапных изменений:
$ git diff --cached
И вы можете отменить слияние, даже если это ускоренное слияние:
$ git merge --abort
git merge --only-if-there-wont-be-any-conflicts
или git diff --show-conflicts <commit>
было бы очень удобно. Позор, это еще не возможно, или я что-то упустил?
git pull --ff-only
!
Мне просто нужно было реализовать метод, который автоматически находит конфликты между хранилищем и его удаленным. Это решение выполняет слияние в памяти, поэтому оно не затрагивает ни индекс, ни рабочее дерево. Я думаю, что это самый безопасный способ решить эту проблему. Вот как это работает:
git fetch origin master
git merge-base FETCH_HEAD master
git merge-tree mergebase master FETCH_HEAD
( mergebase - шестнадцатеричный идентификатор, который merge-base напечатал на предыдущем шаге)Теперь предположим, что вы хотите объединить удаленный мастер с вашим локальным мастером, но вы можете использовать любые ветви. git merge-tree
выполнит объединение в памяти и выведет результат на стандартный вывод. Grep для шаблона <<
или >>
. Или вы можете распечатать вывод в файл и проверить это. Если вы обнаружите строку, начинающуюся с «изменено в обоих», то, скорее всего, возникнет конфликт.
git merge-tree `git merge-base FETCH_HEAD master` FETCH_HEAD master
git merge-tree `git merge-base clieop master` clieop master | grep -A3 "changed in both"
просто потрясающе! +100
+<<<<<<< .our
поэтому я использую выражение grep, например,grep -q '^+<* \.our$'
Мое простое решение проблемы грубой силы:
Создайте ветку «pre-master» (конечно же, от мастера)
Объедините все, что вы хотите, с этим предварительным мастером.
Тогда вы сможете увидеть, как произошло слияние, не касаясь мастера.
В любом случае, я бы следовал совету @ orange80.
git merge --abort
если есть конфликты, git reset --hard HEAD~1
если произошло слияние или git reset --hard origin/master
. Создание другой ветки дает вам чувство безопасности, но если вы узнаете, как работает git, вы поймете, что это неуместный страх. Когда проблема заключается в том, чтобы не менять рабочую копию, это не дает решения.
git merge --no-commit
не прервет слияние, если его можно быстро переслать. git merge --abort
не работает, если он был объединен. Если вы хотите написать это как скрипт, это неловко, так git merge
как не отвечает достаточно хорошими кодами ошибок, чтобы объяснить различные типы конфликтов. Работа со свежей веткой не позволяет сломанному сценарию оставлять репо в состоянии, требующем ручного вмешательства. Конечно, вы ничего не можете потерять. Но проще построить иначе.
Отменить слияние с git так легко, что вам даже не стоит беспокоиться о пробном запуске:
$ git pull $REMOTE $BRANCH
# uh oh, that wasn't right
$ git reset --hard ORIG_HEAD
# all is right with the world
РЕДАКТИРОВАТЬ: Как отмечено в комментариях ниже, если у вас есть изменения в вашем рабочем каталоге или промежуточной области, вы, вероятно, захотите сохранить их перед выполнением вышеупомянутых действий (в противном случае они исчезнут после git reset
вышеуказанного)
git branch --contains HEAD
или даже более прямой, просто используйтеgit merge --ff-only
--dry-run
не будет «просто проверять, будет ли слияние ускоренным». Он вернул бы точный результат, который произойдет при слиянии: файлы, конфликты и т. Д. Будет ли ff не очень интересным, не так ли?
git stash; git reset --hard
? @BrianPhillips
Я сделал псевдоним для этого и работает как шарм, я делаю это:
git config --global alias.mergetest '!f(){ git merge --no-commit --no-ff "$1"; git merge --abort; echo "Merge aborted"; };f '
Теперь я просто звоню
git mergetest <branchname>
Чтобы выяснить, есть ли какие-либо конфликты.
Просто сравните вашу текущую ветку с удаленной веткой, это скажет вам, что изменится, когда вы сделаете вытягивание / слияние.
#see diff between current master and remote branch
git diff master origin/master
Я использую команду request-pull git для этого. Это позволяет вам видеть все изменения, которые могут произойти при слиянии, но без каких-либо изменений в локальных или удаленных репозиториях .
Например, представьте, что вы хотите объединить ветку с именем «feature-x» в вашу основную ветку
git request-pull master origin feature-x
покажет вам сводку того, что произойдет (не делая ничего):
The following changes since commit fc01dde318:
Layout updates (2015-06-25 11:00:47 +0200)
are available in the git repository at:
http://fakeurl.com/myrepo.git/ feature-x
for you to fetch changes up to 841d3b41ad:
----------------------------------------------------------------
john (2):
Adding some layout
Refactoring
ioserver.js | 8 +++---
package.json | 7 +++++-
server.js | 4 +--
layout/ldkdsd.js | 277 +++++++++++++++++++++++++++++++++++++
4 files changed, 289 insertions(+), 7 deletions(-)
create mode 100644 layout/ldkdsd.js
Если вы добавите -p
параметр, вы также получите полный текст патча, точно так же, как если бы вы делали git diff для каждого измененного файла.
master
и origin
делать в параметрах командной строки, и что если я, например, нахожусь в локальной сети branch1
и хочу сделать request-pull
локальную ветвь функций branch2
? Мне все еще нужно origin
? Конечно, всегда можно прочитать документацию.
Я удивлен, что никто еще не предложил использовать патчи.
Допустим , вы хотите проверить слияние с your_branch
в master
(я предполагаю , что вы master
проверили):
$ git diff master your_branch > your_branch.patch
$ git apply --check your_branch.patch
$ rm your_branch.patch
Это должно делать свое дело.
Если вы получаете ошибки, такие как
error: patch failed: test.txt:1
error: test.txt: patch does not apply
это означает, что патч не был успешным, и слияние приведет к конфликтам. Отсутствие вывода означает, что патч чистый, и вы сможете легко объединить ветку
Обратите внимание, что это на самом деле не изменит ваше рабочее дерево (кроме создания файла исправления, конечно, но вы можете безопасно удалить его впоследствии). Из документации git-apply:
--check
Instead of applying the patch, see if the patch is applicable to the
current working tree and/or the index file and detects errors. Turns
off "apply".
Примечание для тех, кто умнее / более опытен с git, чем я: пожалуйста, дайте мне знать, если я ошибаюсь, и этот метод показывает поведение, отличное от обычного слияния. Кажется странным, что за 8 с лишним лет, когда этот вопрос существовал, никто не предложил бы это, казалось бы, очевидное решение.
git diff master your_branch | git apply --check
.
Это может быть интересно: из документации:
Если вы попытались выполнить слияние, которое привело к сложным конфликтам, и хотите начать заново , вы можете восстановить с помощью git merge --abort .
Но вы также можете сделать это наивным (но медленным) способом:
rm -Rf /tmp/repository
cp -r repository /tmp/
cd /tmp/repository
git merge ...
...if successful, do the real merge. :)
(Примечание: это не сработает, просто клонируя в / tmp, вам понадобится копия, чтобы быть уверенным, что незафиксированные изменения не будут конфликтовать).
cp -r repository/.git /tmp/repository/.git
, cd /tmp/repository
, git reset --hard
, git add --all
, git reset --hard
(для хорошей меры), git status
(убедиться , что он чист).
Я знаю, что это старый вопрос, но он появляется первым в поиске Google.
Git ввел опцию --ff-only при слиянии.
От: http://git-scm.com/docs/git-merge
--ff только
Отказаться от слияния и выхода с ненулевым статусом, если текущий HEAD уже не обновлен или слияние не может быть разрешено как ускоренная перемотка вперед.
Выполнение этого попытается объединить и выполнить перемотку вперед, и если это не удастся, он прекратит работу и предложит вам, что перемотка вперед не может быть выполнена, но оставит вашу рабочую ветку нетронутой. Если он может выполнить ускоренную перемотку вперед, он выполнит объединение в вашей рабочей ветви. Эта опция также доступна на git pull
. Таким образом, вы можете сделать следующее:
git pull --ff-only origin branchA #See if you can pull down and merge branchA
git merge --ff-only branchA branchB #See if you can merge branchA into branchB
Я использую git log, чтобы увидеть, что изменилось в ветви функций из основной ветви.
git log does_this_branch..contain_this_branch_changes
например, чтобы увидеть, что коммиты находятся в ветви функций, которые были / не объединены с master:
git log master..feature_branch
Если вы хотите быстро перейти от B к A, то вы должны убедиться, что git log B..A ничего не показывает, то есть A не имеет ничего, чего нет у B. Но даже если у B..A есть что-то, вы все равно сможете объединяться без конфликтов, поэтому вышеизложенное показывает две вещи: что будет ускоренная перемотка вперед, и, следовательно, у вас не будет конфликта.
Мое решение состоит в том, чтобы слиться в обратном направлении.
Вместо того, чтобы объединить вашу ветку с удаленной «целевой» веткой, объедините эту ветку с вашей.
git checkout my-branch
git merge origin/target-branch
Вы увидите, есть ли какие-либо конфликты и сможете спланировать, как их решить.
После этого вы можете либо прервать слияние с помощью git merge --abort
, либо (если не было никаких конфликтов и произошло слияние) откатиться к предыдущей фиксации с помощьюgit reset --hard HEAD~1