|
HEAD |
Индекс |
Рабочий Каталог |
Сохранность РК? |
На уровне коммитов (без указания путей) |
|
|
|
|
reset --soft [commit] |
REF |
NO |
NO |
YES |
reset [commit] |
REF |
YES |
NO |
YES |
reset --hard [commit] |
REF |
YES |
YES |
NO |
checkout [commit] |
HEAD |
YES |
YES |
YES |
На уровне файлов (с указанием путей) |
|
|
|
|
reset (commit) [file] |
NO |
YES |
NO |
YES |
checkout (commit) [file] |
NO |
YES |
YES |
NO |
Обычно выполнять слияния в Git довольно легко. Git упрощает повторные слияния с одной и той же веткой, таким образом, позволяя вам иметь очень долго живущую ветку, и вы можете сохранять ее всё это время в актуальном состоянии, часто разрешая маленькие конфликты, а не доводить дело до одного большого конфликта по завершению всех изменений.
Однако, иногда все же будут возникать сложные конфликты. В отличие от других систем управления версиями, Git не пытается быть слишком умным при разрешении конфликтов слияния. Философия Git заключается в том, чтобы быть умным, когда слияние разрешается однозначно, но если возникает конфликт, он не пытается сумничать и разрешить его автоматически. Поэтому, если вы слишком долго откладываете слияние двух быстрорастущих веток, вы можете столкнуться с некоторыми проблемами.
В этом разделе мы рассмотрим некоторые из возможных проблем и инструменты, которые предоставляет Git, чтобы помочь вам справиться с этими более сложными ситуациями. Мы также рассмотрим некоторые другие нестандартные типы слияний, которые вы можете выполнять, и вы узнаете как можно откатить уже выполненные слияния.
Мы рассказали некоторые основы разрешения конфликтов слияния в Основные конфликты слияния, для работы с более сложными конфликтами Git предоставляет несколько инструментов, которые помогут вам понять, что произошло и как лучше обойтись с конфликтом.
Во-первых, если есть возможность, перед слиянием, в котором может возникнуть конфликт, позаботьтесь о том, чтобы ваша рабочая директория была без локальных изменений. Если у вас есть несохраненные наработки, либо приберегите их, либо сохраните их во временной ветке. Таким образом, вы сможете легко отменить любыеизменения, которые сделаете в рабочей директории. Если при выполнении слияния вы не сохраните сделанные в рабочей директории изменения, то некоторые из описанных ниже приемов могут привести к утрате этих наработок.
Давайте рассмотрим очень простой пример. Допустим, у нас есть файл с исходниками на Ruby, выводящими на экран строку hello world .
#! /usr/bin/env ruby
defhello
puts 'hello world'
end
hello()
В нашем репозитории, мы создадим новую ветку по имени whitespace и выполним замену всех окончаний строк в стиле Unix на окончания строк в стиле DOS. Фактически, изменения будут внесены в каждую строку, но изменятся только пробельные символы. Затем мы заменим строку “hello world” на “hello mundo”.
$git checkout -b whitespace
Switched to a new branch 'whitespace'
$unix2dos hello.rb
unix2dos: converting file hello.rb to DOS format ...
$git commit -am 'converted hello.rb to DOS'
[whitespace 3270f76] converted hello.rb to DOS
1 file changed, 7 insertions(+), 7 deletions(-)
$vim hello.rb
$git diff -w
diff --git a/hello.rb b/hello.rb
index ac51efd..e85207e 100755
--- a/hello.rb
+++ b/hello.rb
@@ -1,7 +1,7 @@
#! /usr/bin/env ruby
def hello
- puts 'hello world'
+ puts 'hello mundo'^M
end
hello()
$git commit -am 'hello mundo change'
[whitespace 6d338d2] hello mundo change
1 file changed, 1 insertion(+), 1 deletion(-)
Теперь мы переключимся обратно на ветку master и добавим к функции некоторую документацию.
$git checkout master
Switched to branch 'master'
$vim hello.rb
$git diff
diff --git a/hello.rb b/hello.rb
index ac51efd..36c06c8 100755
--- a/hello.rb
+++ b/hello.rb
@@ -1,5 +1,6 @@
#! /usr/bin/env ruby
+# prints out a greeting
def hello
puts 'hello world'
end
$git commit -am 'document the function'
[master bec6336] document the function
1 file changed, 1 insertion(+)
Теперь мы попытаемся слить в текущую ветку ветку whitespace и в результате получим конфликты, так как изменились пробельные символы.
$git merge whitespace
Auto-merging hello.rb
CONFLICT (content): Merge conflict in hello.rb
Automatic merge failed; fix conflicts and then commit the result.
В данный момент у нас есть несколько вариантов дальнейших действий. Во-первых, давайте рассмотрим как выйти из этой ситуации. Если вы, возможно, не были готовы к конфликтам и на самом деле не хотите связываться с ними, вы можете просто отменить попытку слияния, используя команду git merge --abort.
Читать дальше