Comment vérifier si un commit Git est l'ancêtre d'un autre

GitGitBeginner
Pratiquer maintenant

💡 Ce tutoriel est traduit par l'IA à partir de la version anglaise. Pour voir la version originale, vous pouvez cliquer ici

Introduction

Dans ce laboratoire, vous apprendrez à déterminer si un commit Git est l'ancêtre d'un autre. Comprendre les relations d'ascendance entre les commits est essentiel pour naviguer dans l'historique de votre projet et le comprendre.

Nous allons explorer la commande git merge-base --is-ancestor, un outil puissant à cet effet. De plus, nous utiliserons git log pour visualiser l'historique des commits et retracer l'ascendance, et tester la commande avec des commits non apparentés pour consolider votre compréhension. À la fin de ce laboratoire, vous serez en mesure d'identifier les relations d'ascendance dans votre dépôt Git.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL git(("Git")) -.-> git/SetupandConfigGroup(["Setup and Config"]) git(("Git")) -.-> git/BasicOperationsGroup(["Basic Operations"]) git(("Git")) -.-> git/BranchManagementGroup(["Branch Management"]) git/SetupandConfigGroup -.-> git/init("Initialize Repo") git/BasicOperationsGroup -.-> git/add("Stage Files") git/BasicOperationsGroup -.-> git/commit("Create Commit") git/BranchManagementGroup -.-> git/branch("Handle Branches") git/BranchManagementGroup -.-> git/checkout("Switch Branches") git/BranchManagementGroup -.-> git/log("Show Commits") subgraph Lab Skills git/init -.-> lab-560057{{"Comment vérifier si un commit Git est l'ancêtre d'un autre"}} git/add -.-> lab-560057{{"Comment vérifier si un commit Git est l'ancêtre d'un autre"}} git/commit -.-> lab-560057{{"Comment vérifier si un commit Git est l'ancêtre d'un autre"}} git/branch -.-> lab-560057{{"Comment vérifier si un commit Git est l'ancêtre d'un autre"}} git/checkout -.-> lab-560057{{"Comment vérifier si un commit Git est l'ancêtre d'un autre"}} git/log -.-> lab-560057{{"Comment vérifier si un commit Git est l'ancêtre d'un autre"}} end

Utiliser git merge-base --is-ancestor

Dans cette étape, nous allons apprendre à utiliser la commande git merge-base --is-ancestor pour déterminer si un commit est l'ancêtre d'un autre. C'est un concept fondamental pour comprendre l'historique et les relations entre les différentes versions de votre projet dans Git.

Tout d'abord, créons un simple dépôt Git et effectuons quelques commits pour établir un historique. Accédez au répertoire de votre projet si vous n'y êtes pas déjà :

cd ~/project

Maintenant, créez un nouveau répertoire pour ce laboratoire et initialisez un dépôt Git à l'intérieur :

mkdir git-ancestor-lab
cd git-ancestor-lab
git init

Vous devriez voir une sortie similaire à celle-ci :

Initialized empty Git repository in /home/labex/project/git-ancestor-lab/.git/

Ensuite, créons notre premier fichier et validons-le :

echo "Initial content" > file1.txt
git add file1.txt
git commit -m "Add file1 with initial content"

Vous verrez une sortie confirmant le commit :

[master (root-commit) <commit-hash>] Add file1 with initial content
 1 file changed, 1 insertion(+)
 create mode 100644 file1.txt

Maintenant, effectuons un autre commit. Modifiez le fichier et validez les modifications :

echo "More content" >> file1.txt
git add file1.txt
git commit -m "Add more content to file1"

Vous verrez une sortie confirmant le deuxième commit :

[master <commit-hash>] Add more content to file1
 1 file changed, 1 insertion(+)

Nous avons maintenant un simple historique avec deux commits. Affichons le journal pour voir les hachages des commits :

git log --oneline

La sortie ressemblera à ceci (vos hachages de commit seront différents) :

<commit-hash-2> (HEAD -> master) Add more content to file1
<commit-hash-1> Add file1 with initial content

Dans cette sortie, <commit-hash-1> est le hachage du premier commit, et <commit-hash-2> est le hachage du deuxième commit. Le deuxième commit est un descendant direct du premier commit. Cela signifie que le premier commit est l'ancêtre du deuxième commit.

La commande git merge-base --is-ancestor <ancestor-commit> <descendant-commit> vérifie si le premier commit est l'ancêtre du deuxième commit. Si c'est le cas, la commande se termine avec un statut de 0 (succès). Sinon, elle se termine avec un statut de 1 (échec).

Testons cela. Remplacez <commit-hash-1> et <commit-hash-2> par les hachages réels de votre sortie git log --oneline.

git merge-base --is-ancestor <commit-hash-1> <commit-hash-2>
echo $?

La commande echo $? affiche le statut de sortie de la commande précédente. Étant donné que <commit-hash-1> est l'ancêtre de <commit-hash-2>, la commande git merge-base devrait réussir, et la sortie de echo $? devrait être 0.

Comprendre l'ascendance est crucial pour de nombreuses opérations Git, telles que la fusion (merge) et le rebasage (rebase), car cela aide Git à déterminer l'historique commun entre différentes branches ou commits.

Exécuter git log pour retracer l'ascendance

Dans cette étape, nous allons utiliser la commande git log pour visualiser l'historique des commits et comprendre plus clairement le concept d'ascendance. La commande git log est un outil puissant pour explorer l'historique de votre dépôt.

Accédez au répertoire de votre dépôt si vous n'y êtes pas déjà :

cd ~/project/git-ancestor-lab

Nous avons déjà deux commits dans notre dépôt. Affichons le journal à nouveau, cette fois-ci en utilisant le format par défaut :

git log

La sortie affichera les détails de chaque commit, y compris le hachage du commit, l'auteur, la date et le message de commit. Les commits sont listés dans l'ordre chronologique inverse (le plus récent en premier).

commit <commit-hash-2> (HEAD -> master)
Author: Jane Doe <[email protected]>
Date:   <Date and Time>

    Add more content to file1

commit <commit-hash-1>
Author: Jane Doe <[email protected]>
Date:   <Date and Time>

    Add file1 with initial content

Dans cette sortie, vous pouvez voir que le deuxième commit (<commit-hash-2>) pointe vers le premier commit (<commit-hash-1>). C'est ainsi que Git suit l'historique. Chaque commit (sauf le premier) a un commit parent, et cette relation parent-enfant définit l'ascendance.

La commande git log parcourt essentiellement en arrière cette chaîne de parents, en partant du commit actuel (indiqué par HEAD -> master).

Ajoutons un autre commit pour allonger légèrement l'historique :

echo "Final content" >> file1.txt
git add file1.txt
git commit -m "Add final content to file1"

Maintenant, exécutez git log --oneline à nouveau pour voir l'historique mis à jour :

git log --oneline

La sortie affichera trois commits :

<commit-hash-3> (HEAD -> master) Add final content to file1
<commit-hash-2> Add more content to file1
<commit-hash-1> Add file1 with initial content

Ici, <commit-hash-3> est le commit le plus récent, <commit-hash-2> est son parent, et <commit-hash-1> est le parent de <commit-hash-2>. Cela signifie que <commit-hash-1> est l'ancêtre de <commit-hash-2> et de <commit-hash-3>. De même, <commit-hash-2> est l'ancêtre de <commit-hash-3>.

Nous pouvons utiliser git merge-base --is-ancestor pour vérifier ces relations. Remplacez les espaces réservés par les hachages de commit réels.

git merge-base --is-ancestor <commit-hash-1> <commit-hash-3>
echo $?

Cela devrait afficher 0 car le premier commit est l'ancêtre du troisième commit.

git merge-base --is-ancestor <commit-hash-2> <commit-hash-3>
echo $?

Cela devrait également afficher 0 car le deuxième commit est l'ancêtre du troisième commit.

L'utilisation de git log vous aide à visualiser le graphe des commits et à comprendre les relations parent-enfant, qui sont directement liées au concept d'ascendance vérifié par git merge-base --is-ancestor.

Tester des commits non-ancêtres

Dans les étapes précédentes, nous avons utilisé git merge-base --is-ancestor pour confirmer que les commits antérieurs étaient les ancêtres des commits ultérieurs sur la même branche. Maintenant, explorons ce qui se passe lorsque nous testons des commits qui ne sont pas les ancêtres les uns des autres.

Accédez au répertoire de votre dépôt :

cd ~/project/git-ancestor-lab

Actuellement, nous avons une seule branche (master) avec trois commits. Pour tester les relations de non-ascendance, nous devons créer une nouvelle branche et effectuer un commit sur cette branche. Cela créera un historique divergent.

Tout d'abord, créons une nouvelle branche appelée feature :

git branch feature

Cette commande crée un nouveau pointeur de branche appelé feature qui pointe vers le même commit que master (notre dernier commit, <commit-hash-3>).

Maintenant, changeons de branche pour la branche feature :

git checkout feature

Vous devriez voir une sortie indiquant que vous avez changé de branche :

Switched to branch 'feature'

Nous sommes maintenant sur la branche feature. Effectuons un nouveau commit sur cette branche. Créez un nouveau fichier :

echo "Feature content" > file2.txt
git add file2.txt
git commit -m "Add file2 on feature branch"

Vous verrez une sortie confirmant le commit sur la branche feature :

[feature <commit-hash-4>] Add file2 on feature branch
 1 file changed, 1 insertion(+)
 create mode 100644 file2.txt

Maintenant, examinons l'historique en utilisant git log --oneline --all --graph. Le flag --all affiche les commits de toutes les branches, et --graph trace une représentation textuelle de l'historique des commits.

git log --oneline --all --graph

La sortie montrera un historique avec des branches. Elle pourrait ressembler à ceci (les hachages de commit varieront) :

* <commit-hash-4> (HEAD -> feature) Add file2 on feature branch
* <commit-hash-3> (master) Add final content to file1
* <commit-hash-2> Add more content to file1
* <commit-hash-1> Add file1 with initial content

Dans ce graphe, <commit-hash-4> est le dernier commit sur la branche feature, et <commit-hash-3> est le dernier commit sur la branche master. Ces deux commits ne sont pas les ancêtres l'un de l'autre. Ils ont un ancêtre commun, qui est <commit-hash-3> (le commit où la branche feature a été créée).

Utilisons git merge-base --is-ancestor pour tester la relation entre <commit-hash-4> et <commit-hash-3>. Remplacez les espaces réservés par les hachages de commit réels.

git merge-base --is-ancestor <commit-hash-4> <commit-hash-3>
echo $?

Cette commande vérifie si <commit-hash-4> est l'ancêtre de <commit-hash-3>. D'après notre graphe, ce n'est pas le cas. Par conséquent, la commande devrait se terminer avec un statut de 1.

Maintenant, testons l'inverse : <commit-hash-3> est-il l'ancêtre de <commit-hash-4> ?

git merge-base --is-ancestor <commit-hash-3> <commit-hash-4>
echo $?

Cette commande vérifie si <commit-hash-3> est l'ancêtre de <commit-hash-4>. En regardant le graphe, le parent de <commit-hash-4> est <commit-hash-3>. Donc, <commit-hash-3> est l'ancêtre de <commit-hash-4>. La commande devrait se terminer avec un statut de 0.

Cela démontre comment git merge-base --is-ancestor peut être utilisé pour vérifier de manière programmée la relation entre n'importe deux commits de l'historique de votre dépôt, même sur différentes branches.

Résumé

Dans ce laboratoire (lab), nous avons appris à utiliser la commande git merge-base --is-ancestor pour vérifier si un commit Git est l'ancêtre d'un autre. Nous avons commencé par créer un simple dépôt Git et effectué quelques commits pour établir un historique. Nous avons ensuite utilisé git log --oneline pour afficher l'historique des commits et identifier les hachages de commit. Cette étape de base est cruciale pour comprendre les relations entre différentes versions d'un projet dans Git.