Leçon 21 · Histoire et intégration
Fusionner ou rebaser : choisissez avec un graphique
Exécutez une fusion et un rebase à partir de deux copies identiques de la même divergence, comparez les deux graphiques, les parents et les arborescences de fichiers, et apprenez la règle qui les départage : qui d'autre a déjà vos commits.
- Niveau: Intermédiaire
- 11 minutes de lecture
- 6 minutes de vidéo
- Mis à jour
- Avant cette leçon: Fusionner des branches avec un historique divergent, Comprendre les fusions rapides, Rebaser un travail inédit sur une nouvelle base
Progression enregistrée dans ce navigateur.
La lecture charge la vidéo depuis YouTube (mode de confidentialité amélioré).
Ce que vous apprendrez
- Commencez la fusion et le rebase à partir de copies identiques afin que la comparaison soit équitable.
- Lisez les deux parents d'un commit de fusion et le nouveau parent unique d'un commit rebasé.
- Expliquez pourquoi deux copies peuvent se terminer par les mêmes fichiers tout en ayant des historiques différents.
- Choisissez avec une seule règle : réécrivez uniquement les commits que personne d’autre n’a.
Avant de commencer
Vous avez besoin de deux copies distinctes de la divergence de la leçon 20, nommées gittree-merge et gittree-rebase. Dans chaque copie, la branche feature/signup-form contient un de vos commits (appelez-le S), la branche updated-main contient un commit différent (appelez-le N), toutes deux démarrées à partir du même commit M et rescue/signup-before-rebase pointe sur S. La branche thématique est extraite et l'arborescence de travail est propre. Ne faites pas la deuxième copie à partir du résultat de la première.
Tout ici est local et sur le forfait gratuit (GitTree vous demande de vous connecter) : pas de compte d'hébergement, pas de fournisseur, pas d'Internet. Chaque identité est fictive (exemple.com) et vous ne devriez jamais exécuter cette leçon dans le cadre d'un projet réel.
Apportez les modifications dans GitTree ou avec les commandes Git natives, pas les deux dans la même copie. La lecture du résultat par la suite est toujours sûre. Les étiquettes de menu proviennent des propres chaînes de GitTree 2.0 ; les commandes natives ont été exécutées avec Git 2.43 dans des copies jetables. Les étapes GitTree n'ont pas été exécutées sur macOS, Windows ou Linux ; les raccourcis de l'application utilisent Command sur macOS où cette page écrit Ctrl.
Effets de concept et d'état
Une comparaison n'est juste que lorsque les deux copies partent des mêmes références et des mêmes fichiers. Si vous fusionnez d'abord puis rebasez ce résultat, vous posez une question différente : la rediffusion a désormais une validation de fusion dans sa plage.
Merge conserve les deux secteurs d'activité. Il ajoute un nouveau commit, K, avec deux parents : S d'abord, puis N. S et N conservent leurs identifiants.
Rebase rejoue votre commit au-dessus de N. Le résultat, S′, a le même changement que S mais un nouveau parent, et l'ID d'un commit inclut son parent, donc S′ a un nouvel ID. L'ancien S ne survit que parce que la branche de sauvetage le pointe toujours.
Lorsqu'il n'y a aucun conflit, les deux copies se terminent par la même arborescence de fichiers. Des arbres égaux ne signifient pas une histoire égale : un graphique conserve un losange, l'autre une ligne droite et les ID de validation diffèrent.
La raison n’est pas une question de goût. Si d'autres personnes ont déjà vos commits, les rejouer brise leurs copies, alors fusionnez. Si les commits sont privés, un rebase est sûr et donne un historique linéaire si votre équipe en préfère un. Ni l’un ni l’autre n’améliore le code.
Dans chaque copie, seule la branche thématique bouge. Le serveur, updated-main et le principal d'origine ne sont pas touchés.
Préparer l’état exact du projet
Faites une divergence, puis copiez-la deux fois. Commencez à partir d’une copie ordinaire distincte du projet telle que la leçon 18 l’a laissé (la principale est le commit de fusion M). Laissez votre gittree-features d'origine intact et ne l'exécutez jamais lors d'une extraction de source. L'identité de la démo est GitTree Demo, demo@example.com, avec la signature désactivée dans ce référentiel uniquement.
Entrées de fichiers complètes
Enregistrez uniquement à la phase nommée ci-dessous. Ce sont des corps UTF-8/LF complets avec une nouvelle ligne finale ; ne collez jamais les clôtures Markdown. Les fichiers exécutables inchangés héritent de l'entrée nommée. Les versions dans des variantes distinctes ne doivent pas écraser l'original.
index.html — INSCRIPTION
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>GitTree Features — course demo</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<header class="site-header">
<a href="#main">GitTree Features</a>
</header>
<main id="main" tabindex="-1">
<section class="hero" aria-labelledby="hero-title">
<p class="eyebrow">GitTree Learn demo project</p>
<h1 id="hero-title">See your work clearly.</h1>
<p id="hero-copy">Choose one change, then check what Git saved.</p>
</section>
<section class="features" aria-labelledby="features-title">
<h2 id="features-title">Follow your work</h2>
<div class="cards">
<article class="feature-card">
<h3>History</h3>
<p>Read commits and branches together.</p>
</article>
<article class="feature-card">
<h3>Changes</h3>
<p>Review the exact content selected for a commit.</p>
</article>
<article class="feature-card">
<h3>Recovery</h3>
<p>Inspect the scope of a recovery point before using it.</p>
</article>
</div>
</section>
<section aria-labelledby="plans-title">
<h2 id="plans-title">Choose the workflow you need</h2>
<div class="cards">
<article class="feature-card">
<h3>Local Git</h3>
<p>Local Git workflows work without signing in.</p>
</article>
<article class="feature-card">
<h3>Connected workflows</h3>
<p>Provider integrations and Nour require Pro or an applicable trial.</p>
</article>
</div>
</section>
<section aria-labelledby="signup-title">
<h2 id="signup-title">Try the demo form</h2>
<form id="signup-form" novalidate>
<label for="demo-email">Demo email</label>
<input id="demo-email" name="email" type="email" autocomplete="off" aria-describedby="signup-hint">
<p id="signup-hint">Use a fictional example.com address. Nothing is sent.</p>
<button type="submit">Check the address locally</button>
<p id="signup-result" role="status"></p>
</form>
</section>
</main>
<footer><p>Built by a fictional team for GitTree Learn. Review one change at a time.</p></footer>
<script type="module" src="site.js"></script>
</body>
</html>docs/integration-note.md — DOC_MERGE
# Integration review
This note was written on main while signup work was private.Dans GitTree
Ouvrez la palette avec Commande+Maj+P (Ctrl+Maj+P sur Ubuntu), tapez le nom exact de la commande et choisissez-le. Les actions sur une branche nommée utilisent le menu contextuel de cette branche.
- Ouvrez gittree-merge. Choisissez ensuite New Tab et ouvrez gittree-rebase dans sa liste Recent. Chaque onglet porte le nom de son dossier, vous pouvez donc distinguer les deux.
- Dans l'onglet gittree-merge, laissez
feature/signup-formcoché. Cliquez avec le bouton droit surupdated-mainet choisissez Merge updated-main into feature/signup-form. - Sous Record it as, choisissez Always a merge commit, puis choisissez Merge une fois. Le nouveau commit a deux parents : S d'abord, puis N.
- Passez à l'onglet gittree-rebase. Il est toujours en S et N, exactement comme vous l'avez enregistré. N'utilisez pas la copie de fusion.
- Cliquez avec le bouton droit sur
updated-mainet choisissez Rebase feature/signup-form onto updated-main. Lisez Options for this rebase et laissez les deux options désactivées, puis choisissez Rebase feature/signup-form une fois. - Sélectionnez le commit rejoué. Son parent est N et son identifiant est nouveau. L'ancien S est toujours nommé par
rescue/signup-before-rebase. - Dans chaque onglet, ouvrez Show Files →
index.htmletdocs/integration-note.md. Il s'agit de la même page et de la même note dans les deux exemplaires. Revenez ensuite avec Back to Graph. - Comparez les deux graphiques, puis indiquez quelle règle décide du choix de cette branche avant de choisir un résultat. Conservez les deux copies telles quelles.
Pour chaque commit ordinaire du cours : Summary est le sujet indiqué, Description est vide et les options Amend Previous Commit, Skip Hooks, Add Signed-off-by, Different Author, Push After Commit et Allow Empty Commit restent désactivées. Cette leçon ne constitue pas un engagement ordinaire.
Dans la borne
Construisez la divergence dans une copie propre et distincte du résultat de la leçon 18 (le travail que vous avez effectué dans l'application, écrit sous forme de commandes natives) :
git switch --create feature/signup-formEnregistrez la page d'inscription complète sous index.html, puis :
git add -- index.html
git commit --quiet -m "feat: add the local signup demonstration"
git branch rescue/signup-before-rebase
BASE_SHA="$(git rev-parse HEAD~1)"
git switch --quiet --create updated-main "$BASE_SHA"Le updated-main, enregistrez la note DOC_MERGE complète sous docs/integration-note.md, puis :
git add -- docs/integration-note.md
git commit --quiet -m "docs: add the integration review"
git switch --quiet feature/signup-formBASE_SHA est le commit M à partir duquel les deux lignes se développent. Faites maintenant les deux copies indépendantes à partir de cet état exact (cd .. && cp -R gittree-features gittree-merge && cp -R gittree-features gittree-rebase). Dans la copie de fusion :
git merge --quiet --no-ff --no-edit updated-main
git rev-list --parents -n 1 HEAD
git rev-parse 'HEAD^{tree}'
git status --shortDans la copie de rebase intacte :
git rebase --quiet --no-autostash --no-update-refs --no-autosquash updated-main
git rev-list --parents -n 1 HEAD
git rev-parse 'HEAD^{tree}'
git status --shortgit rev-list --parents -n 1 HEAD imprime l'ID du commit suivi de ses parents : trois ID dans la copie de fusion, deux dans la copie de rebase. Les deux lignes HEAD^{tree} ont le même identifiant et git status --short n'imprime rien dans les deux. Les deux identifiants de commit HEAD sont différents. Vos identifiants seront différents de ceux des autres ; comparez les vôtres entre eux, pas avec cette page.
Si le sujet n'avait pas de validation propre et que updated-main était simplement en avance, git merge avancerait rapidement par défaut et ne créerait aucune validation de fusion. C'est une contribution différente et un résultat différent ; choisissez-le exprès, ne simulez jamais une fusion biparentale.
Résultat
Where you end: la copie de fusion a un nouveau commit K avec les parents S et N ; la copie de rebase a S' avec le parent N, et l'ancien S est conservé par la branche de sauvetage. Les arborescences de fichiers sont égales, les deux statuts sont propres et le principal d'origine, M et le serveur sont intacts.
Erreurs courantes
- En supposant qu'un graphique direct signifie que l'ancien identifiant de validation a survécu. Un rebase crée toujours de nouveaux commits.
- Démarrage du rebase à partir du résultat de la fusion. Il s'agit d'une expérience différente, et la rediffusion peut inclure la validation de fusion.
- Comparer les deux identifiants HEAD et s'attendre à ce qu'ils soient d'accord. Comparez plutôt les arbres.
- Répéter la fusion ou le rebase une fois qu'il est déjà terminé.
Si quelque chose ne va pas
Ne rejetez aucun des résultats pour les forcer à correspondre. Si les arbres diffèrent, comparez les références de départ, toute résolution de conflit et tout commit supplémentaire, puis recommencez à partir de la divergence enregistrée. Une branche de sauvetage conserve uniquement l'historique engagé ; il ne conserve pas les fichiers non validés.
Vérifiez votre compréhension
Répondez à chaque question, puis lisez pourquoi. Les questions marquées « Obligatoire » comptent pour terminer la leçon.
0 sur 6 corrects
Répondez correctement aux questions requises pour terminer la leçon.
Vérifié dans ce navigateur.
Pratique
Signalez les deux listes parent, les deux ID HEAD et les deux ID d'arborescence. Expliquez pourquoi des ID d'arbre égaux à côté de différents ID HEAD sont le résultat attendu. Prédisez ensuite, sans le faire, ce que fait une fusion par défaut lorsque le sujet n'a pas de validation propre.
Votre propre confirmation : le site ne peut pas voir votre ordinateur.
Pour terminer la leçon, répondez correctement aux questions demandées et confirmez l'exercice pratique.
Récapitulatif
- Même début, histoire différente.
- Des arbres égaux ne signifient pas une histoire égale.
- Fusionnez lorsque d’autres ont vos commits. Rebasez uniquement les fichiers privés.
En rapport
Termes du glossaire introduits
Rebase — إعادة تأسيس; rejouer — إعادة تطبيق; branche de sauvetage — فرع حفظ.
Transcription vidéo
La narration de la vidéo, repère par repère.
Afficher la transcription
- Fusionner ou rebaser ? Le même travail peut partir deux histoires différentes.
- Nous exécuterons les deux à partir du même départ pointer et comparer.
- Votre branche a un commit. La mise à jour la branche en a une autre.
- Les deux sont nés du même commit, donc ni l'un ni l'autre contient l'autre.
- Tout d'abord, préparez la divergence et faites deux exemplaires identiques.
- Un test équitable nécessite les mêmes références et fichiers dans les deux exemplaires.
- Voici le premier exemplaire. Nous fusionnerons dans celui-ci.
- Et c'est le deuxième exemplaire. Nous le gardons intact pour le rebase.
- Cliquez avec le bouton droit sur update-main et choisissez son Commande de fusion.
- Sous Enregistrer sous, choisissez Toujours une fusion commettre.
- Choisissez Fusionner une fois et attendez le vrai résultat.
- Le nouveau commit a deux parents : votre commit, puis update-main's.
- Maintenant le deuxième exemplaire. Il y a encore les deux commits originaux.
- Cliquez à nouveau avec le bouton droit sur update-main et choisissez Rebase cette fois.
- La boîte de dialogue nomme la branche et le cible. Laissez les deux options désactivées.
- Rebase une fois. Git rejoue votre commit sur haut de la page principale mise à jour.
- Le commit rejoué a un nouveau parent, donc il obtient un nouvel identifiant.
- L'ancien commit n'est pas perdu : le sauvetage la branche le pointe toujours.
- Comparez maintenant les fichiers. La page est la pareil dans les deux exemplaires.
- Il en va de même pour la note d’intégration. Mêmes fichiers, histoire différente.
- Regardez les deux graphiques : un diamant avec un commit de fusion et une ligne droite.
- Alors lequel devriez-vous utiliser ? Demande à qui d'autre a vos engagements.
- Si d'autres en ont, fusionnez. Un rebasement réécrire leur histoire.
- Si les commits sont privés, le rebase est sûr et donne une ligne droite.
- Ni l’un ni l’autre n’améliore votre code. La règle est une question de propriété.
- Maintenant, prouvez-le dans le terminal. Premièrement, le parents de chaque astuce.
- Trois identifiants pour la copie de fusion : le commit, et ses deux parents.
- Deux identifiants pour la copie de rebase : le commit, et c'est un parent.
- Puis les arborescences de fichiers : un identifiant, imprimé deux fois. Mêmes fichiers.
- Mais les deux identifiants de validation diffèrent. Égal des arbres, des histoires différentes.
- Modifiez l'entrée : supposons que votre branche ait aucun engagement propre.
- Une fusion par défaut effectuerait alors une avance rapide, sans validation de fusion.
- Ne rebasez jamais une branche que quelqu'un d'autre l'a déjà fait.
- Si les arbres diffèrent, comparez les arbres de départ les réfs en premier.
- Ne supprimez pas un résultat pour forcer les deux à correspondre.
- Pratique : signaler les parents, les pièces d'identité et les arbres à partir de vos propres copies.
- Ensuite, réorganisez, écrasez et reformulez votre engagements locaux.