Поскольку ветвление с Git обходится дешево, почему бы не получить копию, и тогда вам не нужно делать пробный прогон? Вы можете просто выбросить копию позже.
Это здорово, но все равно изменит вашу рабочую копию. Если ваш репозиторий является живым веб-сервером, то вы можете обслуживать файлы с конфликтами.
dave1010
21
Вы действительно не можете сделать слияние, не затрагивая рабочую копию.
Мипади
55
Правда, но что-то вроде git merge --only-if-there-wont-be-any-conflictsили git diff --show-conflicts <commit>было бы очень удобно. Позор, это еще не возможно, или я что-то упустил?
dave1010
344
@ dave1010 Вы никогда не должны обрабатывать слияния на живом веб-сервере !!! Вот для чего предназначена ваша разработка! Исправьте ветку "prod" и затем отправьте ее на настоящий веб-сервер.
jpswain
52
Если вы работаете на живом / производственном сервере, вы никогда не захотите ничего делать, кроме git pull --ff-only!
ThiefMaster
237
Мне просто нужно было реализовать метод, который автоматически находит конфликты между хранилищем и его удаленным. Это решение выполняет слияние в памяти, поэтому оно не затрагивает ни индекс, ни рабочее дерево. Я думаю, что это самый безопасный способ решить эту проблему. Вот как это работает:
Принесите пульт в ваш репозиторий. Например:
git fetch origin master
Запустите git merge-tree: git merge-tree mergebase master FETCH_HEAD( mergebase - шестнадцатеричный идентификатор, который merge-base напечатал на предыдущем шаге)
Теперь предположим, что вы хотите объединить удаленный мастер с вашим локальным мастером, но вы можете использовать любые ветви. git merge-treeвыполнит объединение в памяти и выведет результат на стандартный вывод. Grep для шаблона <<или >>. Или вы можете распечатать вывод в файл и проверить это. Если вы обнаружите строку, начинающуюся с «изменено в обоих», то, скорее всего, возникнет конфликт.
ИМХО этот ответ недооценен, поскольку это чистое решение, не затрагивающее рабочую копию или указатель.
sschuberth
23
Кстати, шаги 2 и 3 можно объединить в один шаг, используя оператор backtick консоли Linux, который оценивает его содержимое на месте:git merge-tree `git merge-base FETCH_HEAD master` FETCH_HEAD master
jakub.g
15
Добавьте к [alias] в .gitconfig: dry = "! F () {git merge-tree` git merge-base $ 2 $ 1` $ 2 $ 1;}; f "# проверьте, как будет происходить слияние dev в master: git dry Мастер разработки
Ноэль
8
Моя новая любимая линия GIT: git merge-tree `git merge-base clieop master` clieop master | grep -A3 "changed in both"просто потрясающе! +100
Руди
4
При тестировании этого я обнаружил, что для слияния флагов «изменено в обоих» было обнаружено, что обе ветви изменяют один и тот же файл, даже если они не приводят к конфликту слияния. Чтобы определить только реальные конфликты, я счел необходимым использовать grep для разметки конфликтов, которая начинается следующим образом: +<<<<<<< .ourпоэтому я использую выражение grep, например,grep -q '^+<* \.our$'
Guy
55
Мое простое решение проблемы грубой силы:
Создайте ветку «pre-master» (конечно же, от мастера)
Объедините все, что вы хотите, с этим предварительным мастером.
Тогда вы сможете увидеть, как произошло слияние, не касаясь мастера.
Объединить pre-master в master ИЛИ
Объедините все ветки, выпущенные подражателями, в мастера
Мне нравится решение @akostajti, но это еще один недооцененный вариант. На самом деле я предпочитаю защищаться и создавать новую временную ветвь (конечно, только когда я ожидаю конфликтов, иначе это будет перебор), и если что-то пойдет не так, просто удалите его.
jakub.g
1
Не знаю, грязное ли это решение или нет, но оно действительно делает свою работу. Мне это нравится! (Y)
Сара
3
Это должно быть принятое решение, IMO. Это быстрый, простой, безопасный, обратимый, интуитивно понятный интерфейс, и до тех пор, пока перед запуском не произойдет никаких изменений, у него не будет побочных эффектов.
Боб Рэй
3
Это решение говорит вам, что вы не понимаете, как работает git. Ветви - это просто указатели, а вы создаете только избыточный указатель. У вас плохое предчувствие, что вы можете как-то повредить слияние веток, но не можете. Вы всегда можете сделать, git merge --abortесли есть конфликты, git reset --hard HEAD~1если произошло слияние или git reset --hard origin/master. Создание другой ветки дает вам чувство безопасности, но если вы узнаете, как работает git, вы поймете, что это неуместный страх. Когда проблема заключается в том, чтобы не менять рабочую копию, это не дает решения.
Тибо Д.
@ thibault-d Подумайте, насколько сложным является решение, когда вы не начинаете с чистой ветки. git merge --no-commitне прервет слияние, если его можно быстро переслать. git merge --abortне работает, если он был объединен. Если вы хотите написать это как скрипт, это неловко, так git mergeкак не отвечает достаточно хорошими кодами ошибок, чтобы объяснить различные типы конфликтов. Работа со свежей веткой не позволяет сломанному сценарию оставлять репо в состоянии, требующем ручного вмешательства. Конечно, вы ничего не можете потерять. Но проще построить иначе.
Эрик Аронесты
47
Отменить слияние с git так легко, что вам даже не стоит беспокоиться о пробном запуске:
$ git pull $REMOTE $BRANCH
# uh oh, that wasn't right
$ git reset --hard ORIG_HEAD
# all is right with the world
РЕДАКТИРОВАТЬ: Как отмечено в комментариях ниже, если у вас есть изменения в вашем рабочем каталоге или промежуточной области, вы, вероятно, захотите сохранить их перед выполнением вышеупомянутых действий (в противном случае они исчезнут после git resetвышеуказанного)
Просто проверить, будет ли слияние ускоренной (FF), - это вопрос проверки списка git branch --contains HEADили даже более прямой, просто используйтеgit merge --ff-only
Brian Phillips
7
git reset --hard - это одна из немногих команд git, которая позволяет удалять информацию, не имея при этом отказа, поэтому ее следует использовать с особой осторожностью. Таким образом, -1
Kzqai
8
@Tchalvak еще есть рефлог.
Киссаки
3
--dry-runне будет «просто проверять, будет ли слияние ускоренным». Он вернул бы точный результат, который произойдет при слиянии: файлы, конфликты и т. Д. Будет ли ff не очень интересным, не так ли?
Руди
3
как насчет git stash; git reset --hard? @BrianPhillips
код Whisperer
41
Я сделал псевдоним для этого и работает как шарм, я делаю это:
Интересная идея. Как бы я посмотрел на этот вывод и определил, будет ли слияние работать или нет?
MatrixFrog
6
Это не скажет вам, возникнут ли какие-либо конфликты ... но это даст вам общее представление о том, что произойдет, если вы сделали вытягивание / слияние.
Тим
10
Это только скажет вам разницу между двумя ветвями, но не скажет, каким будет результат слияния. Это важное различие, так как в некоторых случаях слияние будет автоматически принимать изменения из разных веток в зависимости от того, когда они были зафиксированы. Таким образом, по сути, выполнение diff может заставить вас думать, что некоторые из ваших изменений будут отменены, когда в действительности процесс слияния автоматически примет более новые изменения по сравнению со старыми. Надеюсь, что это имеет смысл.
markquezada
3
Если опираться на комментарий @ mirthlab, между diff и merge будет существенная разница, если кто-то ранее выполнил слияние со "нашей" стратегией слияния (или некоторыми другими ручными исправлениями слияния); Разница также покажет вам различия, которые уже считаются «объединены».
Тао
21
Я использую команду 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? Конечно, всегда можно прочитать документацию.
Ela782
К сожалению, эта команда работает, только если Rev # 2 является именем ветви, она не работает для хэшей: /
Джаред Грубб,
20
Я удивлен, что никто еще не предложил использовать патчи.
Допустим , вы хотите проверить слияние с your_branchв master(я предполагаю , что вы masterпроверили):
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 не смог использовать« рекурсивную »стратегию слияния» и «файл патча дает ошибку для новых файлов». В противном случае кажется великолепным.
neno
1
Более короткий путь без создания временного файла заплатки: git diff master your_branch | git apply --check.
ks1322
9
Это может быть интересно: из документации:
Если вы попытались выполнить слияние, которое привело к сложным конфликтам, и хотите начать заново , вы можете восстановить с помощью 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(убедиться , что он чист).
ADTC
8
Я знаю, что это старый вопрос, но он появляется первым в поиске Google.
Отказаться от слияния и выхода с ненулевым статусом, если текущий 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
Это сделает слияние, если это можно сделать с помощью ускоренной перемотки вперед, а это не то, что я хотел в первоначальном вопросе. Я думаю, что у принятого ответа есть другая половина, которая это исправляет.
Отто
Правда, причудливые подсказки мерзавцев избавляют меня от необходимости в подобных вещах.
Отто
2
Это не совсем то же самое. Выход с ненулевым статусом, потому что слияние не может быть решено, так как ускоренная перемотка вперед не означает, что есть конфликты . Это просто означает, что история разошлась и необходим коммит слияния.
ADTC
7
Я использую git log, чтобы увидеть, что изменилось в ветви функций из основной ветви.
Если вы хотите быстро перейти от B к A, то вы должны убедиться, что git log B..A ничего не показывает, то есть A не имеет ничего, чего нет у B. Но даже если у B..A есть что-то, вы все равно сможете объединяться без конфликтов, поэтому вышеизложенное показывает две вещи: что будет ускоренная перемотка вперед, и, следовательно, у вас не будет конфликта.
Вы увидите, есть ли какие-либо конфликты и сможете спланировать, как их решить.
После этого вы можете либо прервать слияние с помощью git merge --abort, либо (если не было никаких конфликтов и произошло слияние) откатиться к предыдущей фиксации с помощьюgit reset --hard HEAD~1
Ответы:
Как отмечалось ранее, передайте
--no-commit
флаг, но чтобы избежать фиксации перемотки вперед, также передайте--no-ff
, например, так:Для изучения поэтапных изменений:
И вы можете отменить слияние, даже если это ускоренное слияние:
источник
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 reset
вышеуказанного)источник
git branch --contains HEAD
или даже более прямой, просто используйтеgit merge --ff-only
--dry-run
не будет «просто проверять, будет ли слияние ускоренным». Он вернул бы точный результат, который произойдет при слиянии: файлы, конфликты и т. Д. Будет ли ff не очень интересным, не так ли?git stash; git reset --hard
? @BrianPhillipsЯ сделал псевдоним для этого и работает как шарм, я делаю это:
Теперь я просто звоню
Чтобы выяснить, есть ли какие-либо конфликты.
источник
Просто сравните вашу текущую ветку с удаленной веткой, это скажет вам, что изменится, когда вы сделаете вытягивание / слияние.
источник
Я использую команду request-pull git для этого. Это позволяет вам видеть все изменения, которые могут произойти при слиянии, но без каких-либо изменений в локальных или удаленных репозиториях .
Например, представьте, что вы хотите объединить ветку с именем «feature-x» в вашу основную ветку
покажет вам сводку того, что произойдет (не делая ничего):
Если вы добавите
-p
параметр, вы также получите полный текст патча, точно так же, как если бы вы делали git diff для каждого измененного файла.источник
master
иorigin
делать в параметрах командной строки, и что если я, например, нахожусь в локальной сетиbranch1
и хочу сделатьrequest-pull
локальную ветвь функцийbranch2
? Мне все еще нужноorigin
? Конечно, всегда можно прочитать документацию.Я удивлен, что никто еще не предложил использовать патчи.
Допустим , вы хотите проверить слияние с
your_branch
вmaster
(я предполагаю , что выmaster
проверили):Это должно делать свое дело.
Если вы получаете ошибки, такие как
это означает, что патч не был успешным, и слияние приведет к конфликтам. Отсутствие вывода означает, что патч чистый, и вы сможете легко объединить ветку
Обратите внимание, что это на самом деле не изменит ваше рабочее дерево (кроме создания файла исправления, конечно, но вы можете безопасно удалить его впоследствии). Из документации git-apply:
Примечание для тех, кто умнее / более опытен с git, чем я: пожалуйста, дайте мне знать, если я ошибаюсь, и этот метод показывает поведение, отличное от обычного слияния. Кажется странным, что за 8 с лишним лет, когда этот вопрос существовал, никто не предложил бы это, казалось бы, очевидное решение.
источник
git diff master your_branch | git apply --check
.Это может быть интересно: из документации:
Но вы также можете сделать это наивным (но медленным) способом:
(Примечание: это не сработает, просто клонируя в / 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 при слиянии.
Выполнение этого попытается объединить и выполнить перемотку вперед, и если это не удастся, он прекратит работу и предложит вам, что перемотка вперед не может быть выполнена, но оставит вашу рабочую ветку нетронутой. Если он может выполнить ускоренную перемотку вперед, он выполнит объединение в вашей рабочей ветви. Эта опция также доступна на
git pull
. Таким образом, вы можете сделать следующее:источник
Я использую git log, чтобы увидеть, что изменилось в ветви функций из основной ветви.
например, чтобы увидеть, что коммиты находятся в ветви функций, которые были / не объединены с master:
источник
Если вы хотите быстро перейти от B к A, то вы должны убедиться, что git log B..A ничего не показывает, то есть A не имеет ничего, чего нет у B. Но даже если у B..A есть что-то, вы все равно сможете объединяться без конфликтов, поэтому вышеизложенное показывает две вещи: что будет ускоренная перемотка вперед, и, следовательно, у вас не будет конфликта.
источник
Мое решение состоит в том, чтобы слиться в обратном направлении.
Вместо того, чтобы объединить вашу ветку с удаленной «целевой» веткой, объедините эту ветку с вашей.
Вы увидите, есть ли какие-либо конфликты и сможете спланировать, как их решить.
После этого вы можете либо прервать слияние с помощью git
merge --abort
, либо (если не было никаких конфликтов и произошло слияние) откатиться к предыдущей фиксации с помощьюgit reset --hard HEAD~1
источник
Сделайте временную копию вашей рабочей копии, затем объединитесь с ней и разведите их.
источник