-
1. Начало
- 1.1 За Version Control системите
- 1.2 Кратка история на Git
- 1.3 Какво е Git
- 1.4 Конзолата на Git
- 1.5 Инсталиране на Git
- 1.6 Първоначална настройка на Git
- 1.7 Помощна информация в Git
- 1.8 Обобщение
-
2. Основи на Git
-
3. Клонове в Git
-
4. GitHub
-
5. Git инструменти
- 5.1 Избор на къмити
- 5.2 Интерактивно индексиране
- 5.3 Stashing и Cleaning
- 5.4 Подписване на вашата работа
- 5.5 Търсене
- 5.6 Манипулация на историята
- 5.7 Мистерията на командата Reset
- 5.8 Сливане за напреднали
- 5.9 Rerere
- 5.10 Дебъгване с Git
- 5.11 Подмодули
- 5.12 Пакети в Git (Bundling)
- 5.13 Заместване
- 5.14 Credential Storage система
- 5.15 Обобщение
-
6. Настройване на Git
- 6.1 Git конфигурации
- 6.2 Git атрибути
- 6.3 Git Hooks
- 6.4 Примерна Git-Enforced политика
- 6.5 Обобщение
-
7. Git и други системи
- 7.1 Git като клиент
- 7.2 Миграция към Git
- 7.3 Обобщение
-
8. Git на ниско ниво
- 8.1 Plumbing и Porcelain команди
- 8.2 Git обекти
- 8.3 Git референции
- 8.4 Packfiles
- 8.5 Refspec спецификации
- 8.6 Транспортни протоколи
- 8.7 Поддръжка и възстановяване на данни
- 8.8 Environment променливи
- 8.9 Обобщение
-
9. Приложение A: Git в други среди
-
10. Приложение B: Вграждане на Git в приложения
- 10.1 Git от команден ред
- 10.2 Libgit2
- 10.3 JGit
- 10.4 go-git
- 10.5 Dulwich
-
A1. Приложение C: Git команди
- A1.1 Настройки и конфигурация
- A1.2 Издърпване и създаване на проекти
- A1.3 Snapshotting
- A1.4 Клонове и сливане
- A1.5 Споделяне и обновяване на проекти
- A1.6 Инспекция и сравнение
- A1.7 Дебъгване
- A1.8 Patching
- A1.9 Email команди
- A1.10 Външни системи
- A1.11 Административни команди
- A1.12 Plumbing команди
5.9 Git инструменти - Rerere
Rerere
Функционалността на git rerere
е един вид скрита опция.
Името идва от фразата “reuse recorded resolution” и както името подсказва, позволява ви се да укажете на Git да запомня как сте разрешили даден конфликт така че следващия път, когато той възникне отново — да бъде автоматично разрешен.
Има няколко сценария, когато това може да ви е от помощ.
Един от примерите е упоменат в документацията и описва ситуация, в която искате да сте сигурни, че продължително съществуващ topic клон ще се слива чисто винаги, но не желаете да имате множество междинни сливащи къмити задръстващи историята ви.
С разрешен rerere
, можете да опитате случайно сливане, да разрешите конфликтите и след това да откажете сливането.
Ако правите това продължително, тогава финалното сливане би трябвало да е лесно, защото rerere
ще свърши корекциите вместо вас.
Същата тактика може да се използва, ако искате да пазите даден клон пребазиран и не желаете да се занимавате с едни и същи конфликти при пребазиране всеки път. Или, ако искате да вземете клон, който сте слели и в който сте разрешили много конфликти и след това пожелаете да го пребазирате — най-вероятно не искате да виждате всичките конфликти отново.
Друго приложение на rerere
е когато случайно сливате множество развиващи се клонове в едно за тестване както Git проекта прави например.
Ако тестовете не минават успешно, можете да превъртите назад сливанията и да ги повторите без участието на topic клона, който ги проваля без да трябва да решавате конфликтите отново.
За да активирате rerere
функционалността, просто изпълнете:
$ git config --global rerere.enabled true
Можете да я разрешите и за конкретно хранилище създавайки директорията .git/rr-cache
, но конфигурационната опция е по-чист начин и позволява глобална настройка.
Нека видим просто пример подобен на предишните.
Имаме файл hello.rb
със съдържание:
#! /usr/bin/env ruby
def hello
puts 'hello world'
end
В един от клоновете ни сменяме думата “hello” на “hola”, след това в друг клон променяме “world” на “mundo”, точно както преди.
Когато сливаме двата клона в едно, получаваме конфликт по съдържание:
$ git merge i18n-world
Auto-merging hello.rb
CONFLICT (content): Merge conflict in hello.rb
Recorded preimage for 'hello.rb'
Automatic merge failed; fix conflicts and then commit the result.
Забелязваме новия ред от изхода, Recorded preimage for FILE
.
Освен него, всичко си изглежда като при нормален конфликт.
На този етап rerere
може да ни каже няколко неща.
Нормално, можете да пуснете git status
за да видите какъв е конфликта:
$ git status
# On branch master
# Unmerged paths:
# (use "git reset HEAD <file>..." to unstage)
# (use "git add <file>..." to mark resolution)
#
# both modified: hello.rb
#
Обаче, командата git rerere
в допълнение ще ви уведоми, че е запомнила статуса преди сливането:
$ git rerere status
hello.rb
А git rerere diff
ще ви покаже текущия статус на корекцията на конфликта — с какво сте започнали корекцията и как сте я завършили.
$ git rerere diff
--- a/hello.rb
+++ b/hello.rb
@@ -1,11 +1,11 @@
#! /usr/bin/env ruby
def hello
-<<<<<<<
- puts 'hello mundo'
-=======
+<<<<<<< HEAD
puts 'hola world'
->>>>>>>
+=======
+ puts 'hello mundo'
+>>>>>>> i18n-world
end
Също така (и това няма връзка с rerere
), можете да използвате git ls-files -u
за да видите конфликтните файлове и техните версии — оригинална, лява и дясна:
$ git ls-files -u
100644 39804c942a9c1f2c03dc7c5ebcd7f3e3a6b97519 1 hello.rb
100644 a440db6e8d1fd76ad438a49025a9ad9ce746f581 2 hello.rb
100644 54336ba847c3758ab604876419607e9443848474 3 hello.rb
Сега можете да разрешите конфликта, така че редът да е puts 'hola mundo'
и да пуснете git rerere diff
отново, за да видите какво ще бъде запомнено от rerere:
$ git rerere diff
--- a/hello.rb
+++ b/hello.rb
@@ -1,11 +1,7 @@
#! /usr/bin/env ruby
def hello
-<<<<<<<
- puts 'hello mundo'
-=======
- puts 'hola world'
->>>>>>>
+ puts 'hola mundo'
end
Казано с други думи това означава, че когато Git намери конфликт във файла hello.rb
, при който има “hello mundo” от едната страна и “hola world” на другата, той ще го коригира автоматично използвайки “hola mundo”.
Сега можем да маркираме конфликта като разрешен и да къмитнем:
$ git add hello.rb
$ git commit
Recorded resolution for 'hello.rb'.
[master 68e16e5] Merge branch 'i18n'
Виждаме съобщението "Recorded resolution for FILE".
Сега, нека да отменим това сливане и да го пребазираме на върха на master
клона.
Можем да преместим клона назад с git reset
както видяхме в Мистерията на командата Reset.
$ git reset --hard HEAD^
HEAD is now at ad63f15 i18n the hello
Сега сливането ни е отменено. Следва да пребазираме topic клона.
$ git checkout i18n-world
Switched to branch 'i18n-world'
$ git rebase master
First, rewinding head to replay your work on top of it...
Applying: i18n one word
Using index info to reconstruct a base tree...
Falling back to patching base and 3-way merge...
Auto-merging hello.rb
CONFLICT (content): Merge conflict in hello.rb
Resolved 'hello.rb' using previous resolution.
Failed to merge in the changes.
Patch failed at 0001 i18n one word
Сега получихме същия конфликт, който очакваме, но обърнете внимание на реда Resolved FILE using previous resolution
в отпечатания изход.
Ако погледнем файла ще видим, че той вече е коригиран и не съдържа маркери за конфликт.
#! /usr/bin/env ruby
def hello
puts 'hola mundo'
end
Също, git diff
ще ни покаже как е направена автоматичната корекция:
$ git diff
diff --cc hello.rb
index a440db6,54336ba..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
Можете също да пресъздадете конфликтния статус на файла с git checkout
:
$ git checkout --conflict=merge hello.rb
$ cat hello.rb
#! /usr/bin/env ruby
def hello
<<<<<<< ours
puts 'hola world'
=======
puts 'hello mundo'
>>>>>>> theirs
end
Видяхме пример за това в Сливане за напреднали.
Засега обаче, нека да го коригираме отново като просто изпълним git rerere
повторно:
$ git rerere
Resolved 'hello.rb' using previous resolution.
$ cat hello.rb
#! /usr/bin/env ruby
def hello
puts 'hola mundo'
end
Сега сме повторили корекцията автоматично използвайки кешираната от rerere
информация за нея.
Сега можете да добавите файла и да продължите пребазирането, за да го завършите.
$ git add hello.rb
$ git rebase --continue
Applying: i18n one word
И така, ако правите много повтарящи се сливания или пък искате да държите topic клон в синхрон с промените на master
клона без много излишни сливания, или пък ако често пребазирате — можете да включите rerere
, за да си улесните работата.