forked from aplb/git-notes
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrebase-mechanics.txt
More file actions
112 lines (75 loc) · 6.74 KB
/
rebase-mechanics.txt
File metadata and controls
112 lines (75 loc) · 6.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
МЕХАНИКА REBASE.
Итак, рассмотрим следующую историю.
(Коммиты сгенерированы рандомно).
--------------------------------------------------------------------------------
┏ 2702bed (49 minutes ago) aplb A random change of 18513 to master1.txt
┣ cd27e19 (49 minutes ago) aplb A random change of 23068 to master2.txt
┣━┓
┃ ┣ 43948ca (49 minutes ago) aplb A random change of 24595 to master3.txt
┃ ┗━[master]──54d123d (49 minutes ago) aplb A random change of 8798 to master4.txt
┣ 6359ac6 (19 seconds ago) aplb A random change of 27285 to feat1.txt
┣ 93c7b2a (19 seconds ago) aplb A random change of 865 to feat2.txt
┗━[HEAD]──[feat]──3fcbe57 (19 seconds ago) aplb A random change of 20774 to feat3.txt
--------------------------------------------------------------------------------
От ветки master в определенный момент пошла линия разработки feat, в ней были сделаны 3 коммита.
Чтобы поддерживать историю линейной, стоит задача: поместить эти коммиты на верхушку master, при этом
коммиты 1 и 2 можно уплотнить в один.
С этим поможет справиться
>> git rebase -i master
--------------------------------------------------------------------------------
pick 6359ac6 A random change of 27285 to feat1.txt
pick 93c7b2a A random change of 865 to feat2.txt
pick 3fcbe57 A random change of 20774 to feat3.txt
--------------------------------------------------------------------------------
На второй строке редактора 'pick 93c7b2a' заменяем pick на squash (или s), чтобы уплотнить коммит 93c7b2a с его предшественником 6359ac6 в один.
Смотрим историю.
--------------------------------------------------------------------------------
┏ 2702bed (60 minutes ago) aplb A random change of 18513 to master1.txt
┣ cd27e19 (60 minutes ago) aplb A random change of 23068 to master2.txt
┣ 43948ca (60 minutes ago) aplb A random change of 24595 to master3.txt
┣━[master]──54d123d (60 minutes ago) aplb A random change of 8798 to master4.txt
┣ bbc18a3 (11 minutes ago) aplb This is a combination of 2 commits 1 and 2
┗━[HEAD]──[feat]──3ab9ecc (11 minutes ago) aplb A random change of 20774 to feat3.txt
--------------------------------------------------------------------------------
Получилось. История изменений линейна, из двух коммитов сплющен один. Можно безболезненно выполнить
fast-forward merge на master-е. Стоит все же напомнить, что перемещенные коммиты не являются теми же самыми. У них другой sha1-hash. Родителем нашего squashed-коммита bbc18a3 выступает коммит 54d123d, на который указывает ветка master.
Это было вступление. А теперь вернемся к изначальному состоянию истории и попробуем выполнить то же самое
с помощью более простых команд.
Чтобы повторить 'git rebase -i master', для начала перейдем на ветку master.
>> git checkout master
Надо понимать, что разницей между двумя коммитами является дельта. Выполняя rebase, Git вычисляет дельту между
коммитами (ветки feat) и последовательно применяет их (дельты) на ветке, на которую выполняется перемещение
(в данном случае master).
Также я создам специально для rebase ветку
>> git checkout -b tmp-rebase master
>> git diff cd27e19 6359ac6 | git apply
1) Для начала определим разницу при переходе из cd27e19 в коммит 6359ac6, затем по цепочке команд применим дельту к
working tree, что позволяет не использовать временный файл.
Команда `git-status` показывает, что в дереве проекта появились изменения. С помощью `git-add` и `git commit`
создадим новый коммит.
И хотя, показывая `git rebase -i`, я делал squash для 1 и 2 коммитов ветки feat, в текущем примере я выполню squash
для 2 и 3.
Далее можно последовательно получать diff между коммитами, применяя его
>> git diff 6359ac6 93c7b2a
и
>> git diff 93c7b2a 3fcbe57
Но поскольку это простой учебный пример, можно получить и применить два diff-а сразу.
>> git diff 6359ac6 3fcbe57 | git apply
`git-status` снова покажет, что в дереве проекта появились новые файлы, которые можно добавить в индекс и
зафиксировать.
Вот и практически и всё. Некоторую информацию о полученных изменениях можно извлечь из вывода
>> git log -p -2
В завершение я переименую временную ветку в feat, тем самым удалив старую.
>> git branch -M feat
История изменений теперь выглядит так:
--------------------------------------------------------------------------------
┏ 2702bed (4 hours ago) aplb A random change of 18513 to master1.txt
┣ cd27e19 (4 hours ago) aplb A random change of 23068 to master2.txt
┣ 43948ca (4 hours ago) aplb A random change of 24595 to master3.txt
┣━[master]──54d123d (4 hours ago) aplb A random change of 8798 to master4.txt
┣ 68bba50 (13 minutes ago) aplb Rebased commit-1
┗━[HEAD]──[feat]──38bcc9d (3 minutes ago) aplb Rebased commits 2 and 3
--------------------------------------------------------------------------------
что похоже на результат, полученный в вводной части. Нет ничего легче перемотки fast-forward.
Несмотря на то, что такие действия не стоит повторять ежедневно, пример демонстрирует определенную схему работы
rebase-a без погружения во все внутренние нюансы.