-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrebase.Rmd
210 lines (140 loc) · 7.65 KB
/
rebase.Rmd
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
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
---
title: "Git rebase"
output:
html_document:
toc: true
toc_float: true
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE, cache = TRUE)
library(tidyverse)
```
# Rebase : réécrire l'histoire
La commande `git rebase` permet de réécrire l'histoire des commits, par exemple pour la rendre plus lisible.
Pour éviter les soucis de compatibilité on évite de réécrire une histoire publique. On ne fait des rebase que sur des branches qui ne sont pas liées aux autres.
# Un exemple d'utilisation de rebase : le merge
Classiquement quand on merge une branche test dans master on a un historique de commit comme dans la figure suivante
<img src="resources/figs/git8.svg" width="800" height = "250" alt = "simple branche"></img>
Si cette situation se reproduit de nombreuses fois sur de nombreuses branches le graphe des commits devient vite illisible. Pour faciliter la vision de l'historique du projet on peut modifier cet arbre.
<img src="resources/figs/git8_rebase.svg" width="800" height = "250" alt = "simple branche"></img>
# En pratique
Pour réussir facilement cette tâche, il suffit se positionner sur la branche test et on va faire comme si on avait commencé à développer test à partir de la dernière version de master
```{r rebase1, eval = FALSE}
git switch test
git rebase master
```
A l'issue de cette opération, test est une succession de changements initiés depuis la dernière version de master. En fussionnant master et test, on va juste faire avancer master de quelques commits on n'aura as de commit de merge.
```{r rebase2, eval = FALSE}
git switch master
git merge test
```
<img src="resources/figs/git8_rebase_merge.svg" width="800" height = "250" alt = "simple branche"></img>
# Pour aller plus loin
Le rebase permet de réécrire toute l'histoire des commits. Si l'on souhaite modifier les 5 derniers commits. Par exemple dans la branche rebase voici l'historique des 5 derniers commits.
```{r log, eval=FALSE, echo = TRUE}
metienne@RMATHMPE20:~/git/finistR2022$ git log -n 5 --oneline
423f7a1 (HEAD -> rebase) Add git8 rebase merge illustration
3ebd174 Add git8 rebase illustration
a535bf1 Add git8 merge bifucation illustration
d3ae968 git rebase fast forward
2a0b55e (origin/master, master) Add build directory to .gitignore
```
Il m'a fallu 3 commits pour ajouter les images, je n'ai pas envie de garder cet historique inutile, je voudrais un seul commit qui inclut toutes les images. je peux utiliser rebase pour faire ceci. La commande suivante, demande rentrer dans un mode de rebase automatique à partir pour les 5 derniers commits.
```{r rebase_i, eval = FALSE}
git rebase --interactive HEAD~5
```
On a alors accès aux derniers commits ouvert dans un éditeur de texte (attention ils sont dans l'ordre inverse, le plus récent en bas). Pour réécrire l'histoire il suffit de modifier le mot clé pick par une des propositions ci dessous.
```{r rebase_inter_res, echo = TRUE, eval = FALSE}
pick 2a0b55e Add build directory to .gitignore
pick d3ae968 git rebase fast forward
pick a535bf1 Add git8 merge bifucation illustration
pick 3ebd174 Add git8 rebase illustration
pick 423f7a1 Add git8 rebase merge illustration
# Rebase cefde40..423f7a1 onto 3ebd174 (5 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
[ Read 31 lines ]
^G Get Help ^O Write Out ^W Where Is ^K Cut Text ^J Justify ^C Cur Pos
^X Exit ^R Read File ^\ Replace ^U Paste Text^T To Spell ^_ Go To Line
```
Pour ne faire qu'un seul commit de mes 3 ajouts de fichier, je vais utiliser ` squash`
```{r rebase_inter_res2, echo = TRUE, eval = FALSE}
pick 2a0b55e Add build directory to .gitignore
pick d3ae968 git rebase fast forward
pick a535bf1 Add git8 merge bifucation illustration
s 3ebd174 Add git8 rebase illustration
f 423f7a1 Add git8 rebase merge illustration
# Rebase cefde40..423f7a1 onto 3ebd174 (5 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
# f, fixup <commit> = like "squash", but discard this commit's log message
# x, exec <command> = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop <commit> = remove commit
# l, label <label> = label current HEAD with a name
# t, reset <label> = reset HEAD to a label
# m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]
[ Read 31 lines ]
^G Get Help ^O Write Out ^W Where Is ^K Cut Text ^J Justify ^C Cur Pos
^X Exit ^R Read File ^\ Replace ^U Paste Text^T To Spell ^_ Go To Line
```
Ensuite, on peut modifier les messages de commit
```{r messages_commit, eval = FALSE, echo = TRUE}
# This is a combination of 3 commits.
# This is the 1st commit message:
Add git8 merge bifucation illustration
# This is the commit message #2:
Add git8 rebase illustration
# The commit message #3 will be skipped:
# Add git8 rebase merge illustration
# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit.
#
# Date: Tue Aug 23 11:32:14 2022 +0200
#
# interactive rebase in progress; onto cefde40
```
Si on sauve ce fichier et qu'on quitte, on a réécrit l'histoire
```{r log_history_res, eval = FALSE, echo = TRUE}
commit 5d107f70b48a6344e8bd8c07eb0e4683b572b924 (HEAD -> rebase)
Author: Marie-Pierre Etienne <[email protected]>
Date: Tue Aug 23 11:54:53 2022 +0200
Git rebase interactive mode redaction
commit 339f67470bbc5aee4fe737eb049a61c4212a405b
Author: Marie-Pierre Etienne <[email protected]>
Date: Tue Aug 23 11:32:14 2022 +0200
Add git8 merge bifucation illustration
Add git8 rebase illustration
commit d3ae968e4961f636c55a67e4d630574798154f3c
Author: Marie-Pierre Etienne <[email protected]>
Date: Tue Aug 23 11:27:54 2022 +0200
git rebase fast forward
commit 2a0b55e1ebba204c94126d51b72bacd1f8f0e0d0 (origin/master, master)
Author: Marie-Pierre Etienne <[email protected]>
Date: Tue Aug 23 09:34:53 2022 +0200
Add build directory to .gitignore
commit cefde40f7516ff8877bca4a6cebc910a14dd7d15
Author: Marie-Pierre Etienne <[email protected]>
Date: Tue Aug 23 09:34:12 2022 +0200
Remove build directory automatically created on the gh-pages branch
```
# Important
Bien sur en réécrivant l'histoire on modifie le passé. Comme dans retour vers le futur, modifier le passé va affecter toutes les personnes concernées par ce passé. On doit donc etre très prudent avec cette approche. **On ne rebase jamais master !!!!** On ne peut réécrire l'histoire que pour des branches simples qui n'ont pas d'enfant.
# pour visualiser ce qui se passe
Un outil pratique (merci Cédric pour comprendre, visualiser tester les différentes commandes git )
[https://learngitbranching.js.org/?locale=fr_FR&NODEMO=](https://learngitbranching.js.org/?locale=fr_FR&NODEMO=)