$git status -sb
# # master
UU hello.rb
$git merge --abort
$git status -sb
# # master
Эта команда пытается откатить ваше состояние до того, что было до запуска слияния. Завершиться неудачно она может только в случаях если перед запуском слияния у вас были не припрятанные, не зафиксированные изменения в рабочей директории, во всех остальных случаях все будет хорошо.
Если по каким-то причинам вы обнаружили себя в ужасном состоянии и хотите просто начать все сначала, вы можете также выполнить git reset --hard HEAD (либо вместо HEAD указав то, куда вы хотите откатиться). Но помните, что это откатит все изменения в рабочей директории, поэтому удостоверьтесь, что никакие из них вам не нужны.
Игнорирование пробельных символов
В данном конкретном случае конфликты связаны с пробельными символами. Мы знаем это, так как это простой пример, но в реальных ситуациях это также легко определить при изучении конфликта, так как каждая строка в нем будет удалена и добавлена снова. По умолчанию Git считает все эти строки измененными и поэтому не может слить файлы.
Стратегии слияния, используемой по умолчанию, можно передать аргументы, и некоторые из них предназначены для соответствующей настройки игнорирования изменений пробельных символов. Если вы видите, что множество конфликтов слияния вызваны пробельными символами, то вы можете прервать слияние и запустить его снова, но на этот раз с опцией -Xignore-all-space или -Xignore-space-change. Первая опция игнорирует изменения в любом количествесуществующих пробельных символов, вторая игнорирует вообще все изменения пробельных символов.
$git merge -Xignore-all-space whitespace
Auto-merging hello.rb
Merge made by the 'recursive' strategy.
hello.rb | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
Поскольку в этом примере реальные изменения файлов не конфликтуют, то при игнорировании изменений пробельных символов все сольется хорошо.
Это значительно облегчает жизнь, если кто-то в вашей команде любит временами заменять все пробелы на табуляции или наоборот.
Хотя Git довольно хорошо обрабатывает пробельные символы, с другими типами изменений он не может справиться автоматически, но существуют другие варианты исправления. Например, представим, что Git не умеет обрабатывать изменения пробельных символов и нам нужно сделать это вручную.
То что нам действительно нужно – это перед выполнением самого слияния прогнать сливаемый файл через программу dos2unix. Как мы будем делать это?
Во-первых, мы перейдем в состояние конфликта слияния. Затем нам необходимо получить копии нашей версии файла, их версии файла (из ветки, которую мы сливаем) и общей версии (от которой ответвились первые две). Затем мы исправим либо их версию, либо нашу и повторим слияние только для этого файла.
Получить эти три версии файла, на самом деле, довольно легко. Git хранит все эти версии в индексе в разных “состояниях”, каждое из которых имеет ассоциированный с ним номер. Состояние 1 – это общий предок, состояние 2 – ваша версия и состояния 3 взято из MERGE_HEAD – версия, которую вы сливаете (“их” версия).
Вы можете извлечь копию каждой из этих версий конфликтующего файла с помощью команды git show и специального синтаксиса.
$git show :1:hello.rb > hello.common.rb
$git show :2:hello.rb > hello.ours.rb
$git show :3:hello.rb > hello.theirs.rb
Если вы хотите что-то более суровое, то можете также воспользоваться служебной командой ls-files -u для получения SHA-1 хешей для каждого из этих файлов.
$git ls-files -u
100755 ac51efdc3df4f4fd328d1a02ad05331d8e2c9111 1 hello.rb
100755 36c06c8752c78d2aff89571132f3bf7841a7b5c3 2 hello.rb
100755 e85207e04dfdd5eb0a1e9febbc67fd837c44a1cd 3 hello.rb
Выражение :1:hello.rb является просто сокращением для поиска такого SHA-1 хеша.
Теперь, когда в нашей рабочей директории присутствует содержимое всех трех состояний, мы можем вручную исправить их, чтобы устранить проблемы с пробельными символами и повторно выполнить слияние с помощью малоизвестной команды git merge-file, которая делает именно это.
$dos2unix hello.theirs.rb
dos2unix: converting file hello.theirs.rb to Unix format ...
$git merge-file -p \
hello.ours.rb hello.common.rb hello.theirs.rb > hello.rb
$git diff -w
diff --cc hello.rb
index 36c06c8,e85207e..0000000
--- a/hello.rb
+++ b/hello.rb
@@@ -1,8 -1,7 +1,8 @@@
#! /usr/bin/env ruby
+# prints out a greeting
def hello
- puts 'hello world'
+ puts 'hello mundo'
end
hello()
Теперь у нас есть корректно слитый файл. На самом деле, данный способ лучше, чем использование опции ignore-all-space, так как в его рамках вместо игнорирования изменений пробельных символов перед слиянием выполняется корректное исправление таких изменений. При слиянии с ignore-all-space мы в результате получим несколько строк с окончаниями в стиле DOS, то есть в одном файле смешаются разные стили окончания строк.
Читать дальше