Application
Vous avez travaillé sur 4 fonctionnalités en parallèle et voulez mettre un peu d'ordre dans tout cela. Pour l'instant vous avez :
Créé un readme (premier commit)
Créé des fichiers a.txt, b.txt, c.txt et d.txt (commits 2-5)
Ajouté les fonctionnalités a et b dans les fichiers a.txt et b.txt (commits 6-7)
Après test vous avez trouvé des bugs dans a.ext et b.txt et les avez corrigés (commits 8-9)
L'arborescence de votre projet est présenté ci-contre, pour obtenir ce projet, copiez-collez les instructions ci-dessous après vous être assuré d'avoir tout compris.

git init rebase_exercice_1
cd rebase_exercice_1/
touch a.txt
touch b.txt
touch c.txt
touch d.txt
touch readme.txt
git add readme.txt
git commit -m "Commit initial"
git add a.txt
git commit -m "ajout a.txt"
git add b.txt
git commit -m "ajout b.txt"
git add c.txt
git commit -m "ajout c.txt"
git add d.txt
git commit -m "ajout d.txt"
echo "fonctionnalité A buggée" >> a.txt
git commit -am "Ajout fonctionnalité a dans a.txt"
echo "fonctionnalité B buggée" >> b.txt
git commit -am "Ajout fonctionnalité b dans b.txt"
echo "correction fonctionnalité a" > a.txt
git commit -am "débug fonctionnalité a dans a.txt"
echo "correction fonctionnalité b" > b.txt
git commit -am "débug fonctionnalité b dans b.txt"
Question
On souhaite mettre côte à côte les deux derniers commits sur A et les deux derniers sur B comme présenté sur l'illustration. Procédez à cet échange

Indice
git rebase -i HEAD~4
Solution
Vous ne pouvez pas copier/coller la réponse car les SHA sont différents d'un dépôt à l'autre, mais la solution est d'éditer l'ordre des lignes pour que les deux commits concernant a soient avant puis les deux commits concernant b
pick 3e248a4 Ajout fonctionnalité a dans a.txt
pick 8ba988e débug fonctionnalité a dans a.txt
pick 9290d9b Ajout fonctionnalité b dans b.txt
pick c81ab15 débug fonctionnalité b dans b.txt
Vous devriez obtenir le résultat suivant avec un git log --oneline --reverse
3b3252f Commit initial
ff96cbb ajout a.txt
2af0e23 ajout b.txt
348a1ee ajout c.txt
d781684 ajout d.txt
3e248a4 Ajout fonctionnalité a dans a.txt
0e282ab débug fonctionnalité a dans a.txt
6454f4a Ajout fonctionnalité b dans b.txt
2d23f67 (HEAD -> master) débug fonctionnalité b dans b.txt
Question
Il n'est en définitive pas très intéressant pour vos collaborateurs de voir les bugs que vous avez introduit dans vos tests intermédiaires, il est donc judicieux de fusionner l'ajout de fonctionnalités et leur debug. Procédez à la fusion des commits deux à deux en ne maintenant pas les textes des commits A3 et B3

Indice
Le message du commit corrigeant les bugs n'est plus pertinent, utilisez le mot clé approprié
Solution
Vous souhaitez une fois de plus modifier les 4 derniers commits, mais cette fois-ci, vous souhaites fusionner des commits entre eux. Il faut donc utiliser la même commande que précédemment
git rebase -i HEAD~4
Ici, il ne faut plus pick mais bien utiliser fixup
pick 3e248a4 Ajout fonctionnalité a dans a.txt
fixup 9290d9b Ajout fonctionnalité b dans b.txt
pick 8ba988e débug fonctionnalité a dans a.txt
fixup c81ab15 débug fonctionnalité b dans b.txt
Question
Enfin, effectuez un dernier rebase respectant les contraintes ci-après.
on veut ne garder que 3 commits en dehors du commit initial pour plus de clarté :
Un pour toutes les modifications sur a.txt
Un pour toutes les modifications sur b.txt
Un pour toutes les modifications sur c.txt
On ne veut garder aucune modification concernant d
Le commit 1 aura pour message : "Ajout fonctionnalité a dans nouveau fichier a.txt"
Le commit 2 aura pour message : "Ajout fonctionnalité b dans nouveau fichier b.txt"
Le commit 3 aura pour message : "Création du fichier c.txt pour fonctionnalité c à implémenter"

Indice
Pour toucher à toute l'arborescence de commits sauf le premier, allez chercher l'identifiant de celui-ci en utilisant git log.
Si vous voulez avoir accès à tout l'historique, vous pouvez utiliser la commande suivante, mais attention à ne pas toucher au premier commit dans l'opération ! !
git rebase -i --root
Indice
Pour avoir accès au commit message lors d'une fusion de messages, on utilise squash
Indice
Pour pouvoir éditer le commit message avant de le commit, on utilise edit. Le rebase va marquer une pause une fois qu'il aura traité la ligne et vous pourrez alors modifier le commit message avec
git commit --amend
Une fois les modifications effectuées, on peut reprendre le rebase avec
git rebase --continue
Solution
Il faut réordonner les commits dans l'ordre dans lequel les appliquer en indiquant le bon mot clé à chaque fois :
"pick 3b3252f commit initial" permet de commiter le commit inital sur la racine
"pick ff96cbb ajout a.txt" recommite l'ajout du texte
"squash d94ffd5 Ajout fonctionnalité a dans a.txt" ajoute les modifications du commit d94ffd5 dans le commit précédent et vous permet de rééditer le message
"edit 348a1ee ajout c.txt" va commiter 348a1ee en vous permettant de réécrire le message de commit
"drop d781684 ajout d.txt" va supprimer le commit d781684
pick 3b3252f Commit initial
pick ff96cbb ajout a.txt
squash d94ffd5 Ajout fonctionnalité a dans a.txt
pick 2af0e23 ajout b.txt
squash d9c0c67 Ajout fonctionnalité b dans b.txt
edit 348a1ee ajout c.txt
drop d781684 ajout d.txt
Question
Supprimez votre dépôt et recréez le avec les instructions du début de cet exercice. Refaites toutes les modifications en utilisant une seule fois la commande
git rebase -i --root
Solution
pick 1d2846f Commit initial
pick 965c783 ajout a.txt
s e5d05f9 Ajout fonctionnalité a dans a.txt
f bbedd45 débug fonctionnalité a dans a.txt
pick a12e44b ajout b.txt
s 62ba4ff Ajout fonctionnalité b dans b.txt
f 5e4f411 débug fonctionnalité b dans b.txt
e 49d3279 ajout c.txt
d e6cbadf ajout d.txt
Solution
Vous devriez avoir l'historique suivant
1f249b6 (HEAD -> master) Création du fichier c.txt pour fonctionnalité c à implémenter
afe5f2f Ajout fonctionnalité b dans nouveau fichier b.txt
23dde8b Ajout fonctionnalité a dans nouveau fichier a.txt
1d2846f Commit initial