Скотт Чакон - Pro Git
- Название:Pro Git
- Автор:
- Жанр:
- Издательство:неизвестно
- Год:неизвестен
- ISBN:нет данных
- Рейтинг:
- Избранное:Добавить в избранное
-
Отзывы:
-
Ваша оценка:
Скотт Чакон - Pro Git краткое содержание
В книге рассматриваются следующие темы: основы Git;
ветвление в Git;
Git на сервере;
распределённый Git;
GitHub;
инструменты Git;
настройка Git;
Git и другие системы контроля версий.
Pro Git - читать онлайн бесплатно полную версию (весь текст целиком)
Интервал:
Закладка:
Removing hello.common.rb
Removing hello.ours.rb
Removing hello.theirs.rb
Использование checkout в конфликтах
Возможно, нас по каким-то причинам не устраивает необходимость выполнения слияния в текущий момент, или мы не можем хорошо исправить конфликт и нам необходимо больше информации.
Давайте немного изменим пример. Предположим, что у нас есть две долгоживущих ветки, каждая из которых имеет несколько коммитов, что при слиянии приводит к справедливому конфликту.
$git log --graph --oneline --decorate --all
* f1270f7 (HEAD, master) update README
* 9af9d3b add a README
* 694971d update phrase to hola world
| * e3eb223 (mundo) add more tests
| * 7cff591 add testing script
| * c3ffff1 changed text to hello mundo
|/
* b7dcc89 initial hello world code
У нас есть три уникальных коммита, которые присутствуют только в ветке master и три других, которые присутствуют в ветке mundo. Если мы попытаемся слить ветку mundo, то получим конфликт.
$git merge mundo
Auto-merging hello.rb
CONFLICT (content): Merge conflict in hello.rb
Automatic merge failed; fix conflicts and then commit the result.
Мы хотели бы увидеть в чем состоит данный конфликт. Если мы откроем конфликтующий файл, то увидим нечто подобное:
#! /usr/bin/env ruby
defhello
<<<<<<< HEAD
puts 'hola world'
=======
puts 'hello mundo'
>>>>>>> mundo
end
hello()
В обеих сливаемых ветках в этот файл было добавлено содержимое, но в некоторых коммитах изменялись одни и те же строки, что и привело к конфликту.
Давайте рассмотрим несколько находящихся в вашем распоряжении инструментов, которые позволяют определить как возник этот конфликт. Возможно, не понятно как именно вы должны исправить конфликт и вам требуется больше информации.
Полезным в данном случае инструментом является команда git checkout с опцией ‘--conflict’. Она заново выкачает файл и заменит маркеры конфликта. Это может быть полезно, если вы хотите восстановить маркеры конфликта и попробовать разрешить его снова.
В качестве значения опции --conflict вы можете указывать diff3 или merge (последнее значение используется по умолчанию). Если вы укажете diff3, Git будет использовать немного другую версию маркеров конфликта – помимо “нашей” и “их” версий файлов будет также отображена “базовая” версия, и таким образом вы получите больше информации.
$git checkout --conflict=diff3 hello.rb
После того, как вы выполните эту команду, файл будет выглядеть так:
#! /usr/bin/env ruby
defhello
<<<<<<< ours
puts 'hola world'
||||||| base
puts 'hello world'
=======
puts 'hello mundo'
>>>>>>> theirs
end
hello()
Если вам нравится такой формат вывода, то вы можете использовать его по умолчанию для будущих конфликтов слияния, установив параметру merge.conflictstyle значение diff3.
$git config --global merge.conflictstyle diff3
Команде git checkout также можно передать опции --ours и --theirs, которые позволяют действительно быстро выбрать одну из версий файлов, не выполняя слияния совсем.
Это может быть действительно полезным при возникновении конфликтов в бинарных файлах (в этом случае вы можете просто выбрать одну из версий), или при необходимости слить из другой ветки только некоторые файлы (в этом случае вы можете выполнить слияние, а затем перед коммитом переключить нужные файлы на требуемые версии).
История при слиянии
Другой полезный инструмент при разрешении конфликтов слияния – это команда git log. Она поможет вам получить информацию о том, что могло привести к возникновению конфликтов. Временами может быть очень полезным просмотреть историю, чтобы понять почему в двух ветках разработки изменялась одна и та же область кода.
Для получения полного списка всех уникальных коммитов, которые были сделаны в любой из сливаемых веток, мы можем использовать синтаксис “трех точек”, который мы изучили в Три точки.
$git log --oneline --left-right HEAD...MERGE_HEAD
< f1270f7 update README
< 9af9d3b add a README
< 694971d update phrase to hola world
>e3eb223 add more tests
>7cff591 add testing script
>c3ffff1 changed text to hello mundo
Это список всех шести коммитов, включенных в слияния, с указанием также ветки разработки, в которой находится каждый из коммитов.
Мы также можем сократить его, попросив предоставить нам более специализированную информацию. Если мы добавим опцию --merge к команде git log, то она покажет нам только те коммиты, в которых изменялся конфликтующий в данный момент файл.
$git log --oneline --left-right --merge
< 694971d update phrase to hola world
>c3ffff1 changed text to hello mundo
Если вы выполните эту команду с опцией -p, то получите только список изменений файла, на котором возник конфликт. Это может быть действительнополезным для быстрого получения информации, которая необходима, чтобы понять почему что-либо конфликтует и как наиболее правильно это разрешить.
Комбинированный формат изменений
Так как Git добавляет в индекс все успешные результаты слияния, то при вызове git diff в состоянии конфликта слияния будет отображено только то, что сейчас конфликтует. Это может быть полезно, так как вы сможете увидеть какие еще конфликты нужно разрешить.
Если вы выполните git diff сразу после конфликта слияния, то получите информацию в довольно своеобразном формате.
$git diff
diff --cc hello.rb
index 0399cd5,59727f0..0000000
--- a/hello.rb
+++ b/hello.rb
@@@ -1,7 -1,7 +1,11 @@@
#! /usr/bin/env ruby
def hello
++<<<<<<< HEAD
+ puts 'hola world'
++=======
+ puts 'hello mundo'
++>>>>>>> mundo
end
hello()
Такой формат называется “комбинированным” (“Combined Diff”), для каждого различия в нем содержится два раздела с информацией. В первом разделе отображены различия строки (добавлена она или удалена) между “вашей” веткой и содержимым вашей рабочей директории, а во втором разделе содержится тоже самое, но между “их” веткой и рабочей директорией.
Таким образом, в данном примере вы можете увидеть строки <<<<<<< и >>>>>>> в файле в вашей рабочей директории, хотя они отсутствовали в сливаемых ветках. Это вполне оправдано, потому что, добавляя их, инструмент слияния предоставляет вам дополнительную информацию, но предполагается, что мы удалим их.
Если мы разрешим конфликт и снова выполним команду git diff, то получим ту же информацию, но в немного более полезном представлении.
$vim hello.rb
$git diff
diff --cc hello.rb
index 0399cd5,59727f0..0000000
--- a/hello.rb
+++ b/hello.rb
@@@ -1,7 -1,7 +1,7 @@@
#! /usr/bin/env ruby
def hello
- puts 'hola world'
- puts 'hello mundo'
++ puts 'hola mundo'
end
hello()
В этом выводе указано, что строка “hola world” при слиянии присутствовала в “нашей” ветке, но отсутствовала в рабочей директории, строка “hello mundo” была в “их” ветке, но не в рабочей директории, и, наконец, “hola mundo” не была ни в одной из сливаемых веток, но сейчас присутствует в рабочей директории. Это бывает полезно просмотреть перед коммитом разрешения конфликта.
Читать дальшеИнтервал:
Закладка: