Git Merge без автоматической фиксации

404

Можно ли это сделать git merge, но без коммита?

"man git merge" говорит так:

With --no-commit perform the merge but pretend the merge failed and do not autocommit,
to give the user a chance to inspect and further tweak the merge result before
committing.

Но когда я пытаюсь использовать git mergeс --no-commitэтим все еще авто-коммиты. Вот что я сделал:

$> ~/git/testrepo$ git checkout master
Switched to branch 'master'

$> ~/git/testrepo$ git branch
* master
  v1.0

$> ~/git/testrepo$ git merge --no-commit v1.0
Updating c0c9fd2..18fa02c
Fast-forward
 file1 |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

$> ~/git/testrepo$ git status
# On branch master
# Your branch is ahead of 'origin/master' by 1 commit.
#
nothing to commit (working directory clean)

Последующее git logпоказывает все коммиты из ветки v1.0, объединенные с master.

selbie
источник

Ответы:

618

Обратите внимание на вывод при выполнении слияния - это говорит Fast Forward

В таких ситуациях вы хотите сделать:

git merge v1.0 --no-commit --no-ff
manojlds
источник
7
Что делать, если есть конфликт.
Юрген Пол
20
@PineappleUndertheSea Быстрые перемотки никогда не вызывают конфликтов. В случае «реального» слияния без ускоренной перемотки --no-commitкоммутатор действует только в том случае, если не возникает конфликта, в случае конфликта git никогда не будет автоматически фиксироваться.
Гроностай
38
К вашему сведению: если вы хотите объединить изменения, а затем зафиксировать, как если бы вы вручную ввели все изменения, которые вы объединили (в отличие от традиционного слияния), вам нужно запустить rm .git/MERGE_HEADпозже, что заставит git забыть, что слияние произошло.
Джон
7
К вашему сведению: Вот пример выходных данных для успешного слияния:Automatic merge went well; stopped before committing as requested
kevinarpe
6
Видимо, git merge BRANCHENAME --no-commit --no-ffоставил мою рабочую область в состоянии "мергинг" мерзавец. Не совсем уверен, что именно это делает, но простой git stash saveи git stash popцикл, казалось, вернул все на круги своя; с только что измененными файлами из целевой ветви на месте, как предполагалось, и больше не статус MERGING.
MoonLite
49

Вы неправильно понимаете значение слияния здесь.

В --no-commitпрепятствует тому , MERGE COMMIT произойдет, и это происходит только тогда , когда вы объединяете две расходящиеся ветви истории; в вашем примере это не так, поскольку Git указывает, что это было слияние «ускоренной перемотки», и тогда Git только последовательно применяет коммиты, уже присутствующие в ветви.

Samus_
источник
12
Это (я) не обязательно прояснит путаницу; Я думаю, что это один (относительно редкий) раз, когда документы на самом деле чисты: git help merge=> "При --no-commitвыполнении слияния, но притворяется, что слияние не выполнено и не выполняется автоматическая фиксация, чтобы дать пользователю возможность проверить и дополнительно настроить результат слияния перед фиксацией. " Ключ, конечно, использует его в сочетании с--no-ff
Майкл
6
... возможно, было бы менее запутанным отказаться от строгой терминологии и описать ее таким образом: «мерзавец слияния», который выполняет ускоренную перемотку вперед, не имеет фиксации слияния, потому что на самом деле слияния вообще нет. На самом деле это идеальная ситуация: быстрые форварды - хорошая вещь, и отсутствие такого дополнительного «слияния» имеет смысл. Это хорошее поведение по умолчанию и не должно быть отключено. (На правильном языке, ускоренная перемотка вперед - это тип слияния, но это не «истинное слияние».)
Майкл,
4
это относительно политик проекта, в некоторых случаях полезно иметь / принудительно эти дополнительные «коммиты слияния», даже если это ff, потому что вам нужно отметить включение функции в основную ветку.
Самус_
7
...что. Ладно, я думаю, что git в значительной степени невосполним. Этот ответ, в частности , убедил меня попробовать Mercurial.
Брайан Гордон
24

Если вы хотите зафиксировать все изменения в одном коммите, как если бы вы набрали текст самостоятельно, --squash сделает то же самое

$ git merge --squash v1.0
$ git commit
Адриан Ли
источник
1
Это тот же эффект, что иgit merge v1.0 --no-commit --no-ff
jpierson
2
Нет, другой эффект. Сквош создает новый коммит с новым хешем. Он объединяет все коммиты в ветке в один коммит для слияния.
Кави Сигел
23

Я предпочитаю этот способ, поэтому мне не нужно запоминать какие-либо редкие параметры.

git merge branch_name

Затем он скажет, что ваша ветвь впереди " #" коммитов, теперь вы можете отключить эти коммиты и поместить их в рабочие изменения следующим образом:

git reset @~#

Например, если после слияния это 1 коммит вперед, используйте:

git reset @~1

Примечание. В Windows требуются кавычки. (Как отметил Джош в комментариях) например:

git reset "@~1"
гранула
источник
4
На окнах нужны цитаты:git reset "@~1"
Джош
1

Когда есть только один коммит в ветке, я обычно делаю

git merge branch_name --ff
Ситху
источник