-
1. DĂ©marrage rapide
-
2. Les bases de Git
-
3. Les branches avec Git
-
4. Git sur le serveur
- 4.1 Protocoles
- 4.2 Installation de Git sur un serveur
- 4.3 Génération des clés publiques SSH
- 4.4 Mise en place du serveur
- 4.5 DĂ©mon (Daemon) Git
- 4.6 HTTP intelligent
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 Git hébergé
- 4.10 Résumé
-
5. Git distribué
-
6. GitHub
-
7. Utilitaires Git
- 7.1 SĂ©lection des versions
- 7.2 Indexation interactive
- 7.3 Remisage et nettoyage
- 7.4 Signer votre travail
- 7.5 Recherche
- 7.6 RĂ©Ă©crire lâhistorique
- 7.7 Reset démystifié
- 7.8 Fusion avancée
- 7.9 Rerere
- 7.10 DĂ©boguer avec Git
- 7.11 Sous-modules
- 7.12 Empaquetage (bundling)
- 7.13 Replace
- 7.14 Stockage des identifiants
- 7.15 Résumé
-
8. Personnalisation de Git
- 8.1 Configuration de Git
- 8.2 Attributs Git
- 8.3 Crochets Git
- 8.4 Exemple de politique gérée par Git
- 8.5 Résumé
-
9. Git et les autres systĂšmes
- 9.1 Git comme client
- 9.2 Migration vers Git
- 9.3 Résumé
-
10. Les tripes de Git
- 10.1 Plomberie et porcelaine
- 10.2 Les objets de Git
- 10.3 Références Git
- 10.4 Fichiers groupés
- 10.5 La refspec
- 10.6 Les protocoles de transfert
- 10.7 Maintenance et récupération de données
- 10.8 Les variables dâenvironnement
- 10.9 Résumé
-
A1. Annexe A: Git dans dâautres environnements
- A1.1 Interfaces graphiques
- A1.2 Git dans Visual Studio
- A1.3 Git dans Visual Studio Code
- A1.4 Git dans IntelliJ / PyCharm / WebStorm / PhpStorm / RubyMine
- A1.5 Git dans Sublime Text
- A1.6 Git dans Bash
- A1.7 Git dans Zsh
- A1.8 Git dans PowerShell
- A1.9 Résumé
-
A2. Annexe B: Embarquer Git dans vos applications
- A2.1 Git en ligne de commande
- A2.2 Libgit2
- A2.3 JGit
- A2.4 go-git
- A2.5 Dulwich
-
A3. Commandes Git
- A3.1 Installation et configuration
- A3.2 Obtention et création des projets
- A3.3 Capture dâinstantanĂ© basique
- A3.4 Création de branches et fusion
- A3.5 Partage et mise Ă jour de projets
- A3.6 Inspection et comparaison
- A3.7 DĂ©bogage
- A3.8 Patchs
- A3.9 Courriel
- A3.10 SystĂšmes externes
- A3.11 Administration
- A3.12 Commandes de plomberie
7.13 Utilitaires Git - Replace
Replace
Git manipule des objets immuables mais il fournit un moyen de faire comme sâil pouvait remplacer des objets de sa base de donnĂ©es par dâautres objets.
La commande replace
vous permet de spĂ©cifier un objet dans Git et de lui indiquer : « chaque fois que tu vois ceci, fais comme si câĂ©tait cette autre chose ».
Ceci sert principalement Ă remplacer un commit par un autre dans votre historique.
Par exemple, supposons que vous avez un énorme historique de code et que vous souhaitez scinder votre dépÎt en un historique court pour les nouveaux développeurs et un plus important et long pour ceux intéressés par des statistiques.
Vous pouvez gĂ©nĂ©rer un historique depuis lâautre avec replace
en remplaçant le commit le plus ancien du nouvel historique par le dernier commit de lâhistorique ancien.
Câest sympa parce que cela signifie que vous nâavez pas besoin de rĂ©Ă©crire tous les commits du nouvel historique, comme vous devriez le faire pour les joindre tous les deux (Ă cause de lâeffet de lien des SHA-1).
Voyons ce que ça donne.
Prenons un dépÎt existant, découpons-le en deux dépÎts, un récent et un historique, puis nous verrons comment les recombiner sans modifier les valeurs SHA-1 du dépÎt récent, grùce à replace
.
Nous allons utiliser un dépÎt simple avec cinq commit simples :
$ git log --oneline
ef989d8 fifth commit
c6e1e95 fourth commit
9c68fdc third commit
945704c second commit
c1822cf first commit
Nous souhaitons couper ceci en deux lignes dâhistoriques. Une ligne ira de first commit Ă fourth commit et sera la ligne historique. La seconde ligne ira de fourth commit Ă fifth commit et sera ligne rĂ©cente.
Bien, la crĂ©ation de la ligne historique est simple, nous nâavons quâĂ crĂ©er une branche dans lâhistorique et la pousser vers la branche master
dâun nouveau dĂ©pĂŽt distant.
$ git branch history c6e1e95
$ git log --oneline --decorate
ef989d8 (HEAD, master) fifth commit
c6e1e95 (history) fourth commit
9c68fdc third commit
945704c second commit
c1822cf first commit
Maintenant, nous pouvons pousser la nouvelle branche history
vers la branche master
du nouveau dépÎt :
$ git remote add project-history https://github.com/schacon/project-history
$ git push project-history history:master
DĂ©compte des objets : 12, fait.
Delta compression using up to 2 threads.
Compression des objets : 100% (4/4), fait.
Ăcriture des objets : 100% (12/12), 907 bytes, fait.
Total 12 (delta 0), reused 0 (delta 0)
DĂ©paquetage des objets : 100% (12/12), fait.
To git@github.com:schacon/project-history.git
* [nouvelle branche] history -> master
Bien, notre projet historique est publiĂ©. Maintenant, la partie la plus compliquĂ©e consiste Ă tronquer lâhistorique rĂ©cent pour le raccourcir. Nous avons besoin dâun recouvrement pour pouvoir remplacer un commit dans un historique par un Ă©quivalent dans lâautre, donc nous allons tronquer lâhistorique Ă fourth commit et fifth commit, pour que fourth commit soit en recouvrement.
$ git log --oneline --decorate
ef989d8 (HEAD, master) fifth commit
c6e1e95 (history) fourth commit
9c68fdc third commit
945704c second commit
c1822cf first commit
Il peut ĂȘtre utile de crĂ©er un commit de base qui contient les instructions sur la maniĂšre dâĂ©tendre lâhistorique, de sorte que les autres dĂ©veloppeurs puissent savoir comment sây prendre sâils butent sur le premier commit et ont besoin de plus dâhistoire. Donc, ce que nous allons faire, câest crĂ©er un objet commit initial comme base avec les instructions, puis rebaser les commits restants (quatre et cinq) dessus.
Nous avons besoin de choisir un point de découpe, qui pour nous est third commit, soit le SHA-1 9c68fdc
.
Donc, notre commit de base sera créé sur cet arbre.
Nous pouvons créer notre commit de base en utilisant la commande commit-tree
, qui accepte juste un arbre et nous fournit un SHA-1 dâun objet commit orphelin tout nouveau.
$ echo 'get history from blah blah blah' | git commit-tree 9c68fdc^{tree}
622e88e9cbfbacfb75b5279245b9fb38dfea10cf
Note
|
La commande |
OK, donc maintenant avec un commit de base, nous pouvons rebaser le reste de notre historique dessus avec la commande git rebase --onto
.
Lâargument --onto
sera lâempreinte SHA-1 que nous venons tout juste de rĂ©cupĂ©rer avec la commande commit-tree
et le point de rebasage sera third commit
(le parent du premier commit que nous souhaitons garder, 9c68fdc
).
$ git rebase --onto 622e88 9c68fdc
First, rewinding head to replay your work on top of it...
Applying: fourth commit
Applying: fifth commit
Bien, nous avons donc rĂ©Ă©crit lâhistorique rĂ©cent Ă la suite du commit de base qui contient les instructions pour reconstruire lâhistorique complet. Nous pouvons pousser ce nouvel historique vers un nouveau projet et quand des personnes clonent ce dĂ©pĂŽt, elles ne voient que les deux commits les plus rĂ©cents et un commit avec des instructions.
Inversons les rĂŽles et plaçons-nous dans la position dâune personne qui clone le projet pour la premiĂšre fois et souhaite obtenir lâhistorique complet. Pour obtenir les donnĂ©es dâhistorique aprĂšs avoir clonĂ© ce dĂ©pĂŽt tronquĂ©, on doit ajouter un second dĂ©pĂŽt distant pointant vers le dĂ©pĂŽt historique et tout rĂ©cupĂ©rer  :
$ git clone https://github.com/schacon/project
$ cd project
$ git log --oneline master
e146b5f fifth commit
81a708d fourth commit
622e88e get history from blah blah blah
$ git remote add project-history https://github.com/schacon/project-history
$ git fetch project-history
From https://github.com/schacon/project-history
* [nouvelle branche] master -> project-history/master
à présent, le collaborateur aurait les commits récents dans la branche master
et les commits historiques dans la branche project-history/master
.
$ git log --oneline master
e146b5f fifth commit
81a708d fourth commit
622e88e get history from blah blah blah
$ git log --oneline project-history/master
c6e1e95 fourth commit
9c68fdc third commit
945704c second commit
c1822cf first commit
Pour combiner ces deux branches, vous pouvez simplement lancer git replace
avec le commit que vous souhaitez remplacer suivi du commit qui remplacera.
Donc nous voulons remplacer fourth commit
dans la branche master
par fourth commit
de la branche project-history/master
 :
$ git replace 81a708d c6e1e95
Maintenant, quand on regarde lâhistorique de la branche master
, il apparaßt comme ceci :
$ git log --oneline master
e146b5f fifth commit
81a708d fourth commit
9c68fdc third commit
945704c second commit
c1822cf first commit
Sympa, non ? Sans devoir changer tous les SHA-1 en amont, nous avons pu remplacer un commit dans notre historique avec un autre entiÚrement différent et tous les outils normaux (bisect
, blame
, etc) fonctionnent de maniĂšre transparente.
Ce qui est intĂ©ressant, câest que fourth commit
a toujours un SHA-1 de 81a708d
, mĂȘme sâil utilise en fait les donnĂ©es du commit c6e1e95
par lequel nous lâavons remplacĂ©.
MĂȘme si vous lancez une commande comme cat-file
, il montrera les données remplacées :
$ git cat-file -p 81a708d
tree 7bc544cf438903b65ca9104a1e30345eee6c083d
parent 9c68fdceee073230f19ebb8b5e7fc71b479c0252
author Scott Chacon <schacon@gmail.com> 1268712581 -0700
committer Scott Chacon <schacon@gmail.com> 1268712581 -0700
fourth commit
Souvenez-vous que le parent réel de 81a708d
Ă©tait notre commit de base (622e88e
) et non 9c68fdce
comme indiqué ici.
Une autre chose intéressante est que les données sont conservées dans nos références :
$ git for-each-ref
e146b5f14e79d4935160c0e83fb9ebe526b8da0d commit refs/heads/master
c6e1e95051d41771a649f3145423f8809d1a74d4 commit refs/remotes/history/master
e146b5f14e79d4935160c0e83fb9ebe526b8da0d commit refs/remotes/origin/HEAD
e146b5f14e79d4935160c0e83fb9ebe526b8da0d commit refs/remotes/origin/master
c6e1e95051d41771a649f3145423f8809d1a74d4 commit refs/replace/81a708dd0e167a3f691541c7a6463343bc457040
Ceci signifie quâil est facile de partager notre remplacement avec dâautres personnes, puisque nous pouvons pousser ceci sur notre serveur et dâautres personnes pourront le tĂ©lĂ©charger. Ce nâest pas trĂšs utile dans le cas de la reconstruction dâhistorique que nous venons de voir (puisque tout le monde tĂ©lĂ©chargerait quand mĂȘme les deux historiques, pourquoi alors les sĂ©parer ?), mais cela peut ĂȘtre utile dans dâautres circonstances.