Git
Junior
Quiz-Git-Junior
Git-Merge
Git-Rebase
Resolution-Conflits
Entretien-Git-Junior
Qcm-Git-Avance
Git-Stash
Git-Remote
Git-Tag
Git-Cherry-Pick
Git-Reset
📝
Entretien Git Junior — Merge, Rebase et Conflits
Évaluez votre maîtrise Git avec 20 questions niveau junior : merge, rebase, stash, résolution de conflits, tags et remotes. Préparez vos entretiens techniques.
Banque de révision : les 60 questions corrigées
Voici l'intégralité des 60 questions de « Entretien Git Junior — Merge, Rebase et Conflits », chacune avec sa bonne réponse et son explication. Le quiz interactif ci-dessus en tire une sélection aléatoire à chaque tentative — utilisez cette liste complète pour réviser.
Explication :
git merge combine deux branches en créant un commit de fusion qui possède deux parents, ce qui préserve l'historique réel. git rebase réécrit l'historique en rejouant les commits de la branche courante un par un au sommet d'une nouvelle base. Le résultat de merge est non destructif, celui de rebase produit un historique linéaire mais modifie les SHA des commits.
Merge = on garde la trace, rebase = on remet au propre.
Explication :
La règle d'or du rebase est de ne jamais réécrire l'historique d'une branche partagée. Comme
git rebase change les SHA des commits, les collègues qui ont déjà récupéré l'ancienne version se retrouveront avec un historique divergent. On rebase donc librement ses branches locales et privées, mais on utilise merge sur les branches publiques comme main.
Rebase en privé, merge en public.
Explication :
git rebase main rejoue les commits de la branche courante au-dessus du dernier commit de main. C'est la manière classique de mettre à jour une branche de fonctionnalité avec les évolutions récentes de la branche principale. On exécute souvent d'abord git checkout ma-branche puis git rebase main pour obtenir un historique propre avant l'ouverture d'une Pull Request.
D'abord se placer sur sa branche, ensuite rebaser sur main.
Explication :
Quand Git ne peut pas fusionner automatiquement, il insère des marqueurs de conflit dans le fichier.
ferme la zone avec la version entrante. Vous devez éditer le fichier pour garder le bon contenu et supprimer entièrement les trois marqueurs.
Garde le bon code, efface les sept chevrons.
Explication :
Une fois les marqueurs supprimés et le contenu corrigé, on exécute
git add fichier pour marquer le conflit comme résolu. L'ajout à l'index signale à Git que la version retenue est validée. Ensuite, lors d'un merge on poursuit avec git commit, et lors d'un rebase avec git rebase --continue.
Conflit résolu = git add du fichier concerné.
Explication :
git merge --abort interrompt une fusion conflictuelle et restaure l'état du dépôt avant le début du merge. C'est très utile lorsqu'on réalise que la fusion est trop complexe ou qu'on s'est trompé de branche. L'arbre de travail et l'index reviennent proprement à la situation initiale.
Trop de conflits ? --abort remet tout comme avant.
Explication :
Lors d'un rebase, Git rejoue les commits un par un. En cas de conflit, on corrige les fichiers, on fait
git add, puis git rebase --continue pour passer au commit suivant. On peut aussi utiliser git rebase --skip pour ignorer un commit ou git rebase --abort pour tout annuler.
Rebase bloqué : add puis --continue.
Explication :
git stash met de côté les modifications non commitées de l'arbre de travail et de l'index, puis restaure un répertoire propre. C'est pratique pour changer rapidement de branche ou récupérer un correctif urgent sans créer un commit incomplet. Les modifications sont stockées dans une pile que l'on peut réappliquer plus tard.
Stash = un tiroir temporaire pour ton travail en cours.
Explication :
git stash pop réapplique les modifications stockées puis retire l'entrée de la pile. git stash apply réapplique les modifications mais conserve l'entrée, ce qui permet de la réutiliser ailleurs. On préfère apply quand on veut garder une copie de sécurité du stash.
pop = applique et jette, apply = applique et garde.
Explication :
git stash push -m "correctif" crée une entrée de stash avec un message personnalisé, ce qui facilite son identification dans la liste. La forme git stash save existait dans les anciennes versions mais elle est désormais dépréciée au profit de git stash push.
git stash push -m pour nommer tes tiroirs.
Explication :
git stash list affiche la pile des stashs sous la forme stash@{0}, stash@{1}, etc. Chaque entrée indique la branche d'origine et le message éventuel. On peut ensuite cibler un stash précis, par exemple git stash apply stash@{2}.
stash list pour retrouver tous tes tiroirs ouverts.
Explication :
git stash drop stash@{0} supprime une entrée précise de la pile sans en réappliquer le contenu. Pour vider l'intégralité de la pile en une fois, on utilise git stash clear, mais cette opération est irréversible et doit être employée avec prudence.
drop = un tiroir, clear = tous les tiroirs.
Explication :
git cherry-pick prend un commit existant et applique ses modifications comme un nouveau commit sur la branche courante. C'est idéal pour récupérer un correctif isolé d'une autre branche sans tout fusionner. Le nouveau commit possède un SHA différent puisqu'il a un parent différent.
Cherry-pick = piocher un seul commit à la fois.
Explication :
Un tag léger (
git tag v1.0) est un simple pointeur nommé vers un commit, sans métadonnées. Un tag annoté (git tag -a v1.0 -m "version 1.0") est un véritable objet Git stockant l'auteur, la date et un message, et il peut être signé. Pour les versions officielles, on privilégie toujours les tags annotés.
Releases officielles = tag annoté avec -a.
Explication :
Par défaut,
git push n'envoie pas les tags. Il faut explicitement faire git push origin v1.0 pour un tag précis, ou git push origin --tags pour envoyer tous les tags locaux. Cette étape est souvent oubliée après la création d'un tag de version.
Un tag créé reste local tant qu'on ne le pousse pas.
Explication :
git reset --soft HEAD~1 déplace le pointeur HEAD un commit en arrière mais conserve les modifications dans l'index (zone de staging). Le commit est défait, mais le travail reste prêt à être recommité. C'est parfait pour refaire un commit avec un meilleur message ou regrouper plusieurs commits.
--soft : le commit saute, le travail reste indexé.
Explication :
git reset --mixed est le mode par défaut. Il déplace HEAD et réinitialise l'index, mais laisse les modifications dans le répertoire de travail en tant que changements non indexés. --soft conserve l'index, tandis que --hard détruit aussi les changements du répertoire de travail.
--mixed : commit et index sautent, le code reste sur le disque.
Explication :
git reset --hard agit sur les trois zones : HEAD, l'index et le répertoire de travail. Toute modification non commitée est perdue sans possibilité de récupération simple. On l'utilise avec prudence, généralement pour revenir à un état propre connu. En cas d'erreur, git reflog peut parfois aider à retrouver un commit perdu.
--hard efface tout : sauvegarde avant de l'utiliser.
Explication :
git revert crée un nouveau commit qui inverse les modifications d'un commit antérieur, sans réécrire l'historique. git reset déplace le pointeur de branche, ce qui réécrit l'historique. Sur une branche partagée, on utilise revert car il est sûr ; reset est réservé aux branches privées.
Historique partagé = revert, jamais reset.
Explication :
git log --oneline affiche chaque commit sur une seule ligne avec un SHA abrégé et le titre du message. C'est l'option la plus utilisée pour avoir une vue d'ensemble rapide. On la combine souvent avec --graph et --all pour visualiser la structure des branches.
--oneline pour une vue d'ensemble lisible.
Explication :
git log --graph trace un graphe ASCII illustrant les branchements et les fusions de l'historique. Combinée à --oneline --all, elle donne une commande très pratique : git log --oneline --graph --all qui permet de comprendre visuellement la structure du dépôt.
--graph --oneline --all : le trio gagnant.
Explication :
git log --author="Alice" filtre l'historique pour n'afficher que les commits dont l'auteur correspond au motif fourni. Le motif est interprété comme une expression régulière, donc --author="Ali" trouverait aussi Alice. On combine souvent ce filtre avec --since et --until pour cibler une période.
--author accepte une regex, pas un nom exact.
Explication :
git log -p (ou --patch) affiche, pour chaque commit, le diff complet des modifications introduites. C'est très utile pour réviser le code historique. L'option --stat donne une version plus légère avec uniquement le nombre de lignes modifiées par fichier.
-p pour voir le code, --stat pour voir les chiffres.
Explication :
git diff --staged (ou son alias --cached) montre les différences entre l'index et le dernier commit, donc ce qui sera inclus au prochain git commit. À l'inverse, git diff sans option compare le répertoire de travail à l'index, c'est-à-dire les modifications non encore indexées.
git diff = pas encore add ; git diff --staged = déjà add.
Explication :
git diff branche1 branche2 affiche les différences entre les sommets des deux branches indiquées. On peut aussi comparer deux commits en passant leurs SHA, par exemple git diff abc123 def456. La notation à trois points branche1...branche2 compare quant à elle par rapport à leur ancêtre commun.
git diff A B compare directement deux références.
Explication :
git remote add origin enregistre un dépôt distant sous le nom origin, le nom conventionnel pour le dépôt principal. On peut ensuite vérifier la configuration avec git remote -v qui affiche les URL de récupération (fetch) et d'envoi (push).
remote add pour relier ton dépôt local au serveur.
Explication :
git remote rename ancien nouveau change le nom d'un dépôt distant, par exemple git remote rename origin upstream. Pour supprimer un distant, on utilise git remote remove nom (ou son ancien alias rm). Ces commandes ne touchent pas au dépôt distant lui-même, seulement à sa référence locale.
remote rename, remote remove : gestion des distants.
Explication :
L'option
-u (ou --set-upstream) crée la relation de suivi entre la branche locale et la branche distante. Après cela, un simple git push ou git pull sans argument suffit, car Git connaît la branche associée. On l'utilise typiquement la première fois qu'on pousse une nouvelle branche.
Premier push d'une branche : ajoute -u une seule fois.
Explication :
Une branche de suivi est une branche locale liée à une branche distante (son upstream). Cette association permet à Git de savoir où pousser et d'où récupérer, et d'indiquer si la branche locale est en avance ou en retard. La commande
git branch -vv affiche les relations de suivi configurées.
Tracking branch = locale qui sait dialoguer avec sa distante.
Explication :
git pull équivaut à git fetch suivi de git merge, ce qui peut créer un commit de fusion. git pull --rebase fait un git fetch suivi d'un git rebase, rejouant vos commits locaux au-dessus des nouveautés distantes. Le résultat est un historique linéaire, sans commit de fusion superflu.
--rebase pour un historique propre lors d'un pull.
Explication :
Une fusion fast-forward se produit quand la branche cible n'a pas divergé : Git peut simplement faire avancer le pointeur jusqu'au dernier commit de la branche fusionnée, sans créer de commit de fusion. L'historique reste linéaire. Si les branches ont divergé, Git effectue une vraie fusion à trois voies.
Fast-forward = le pointeur glisse, aucun merge commit.
Explication :
git merge --no-ff impose la création d'un commit de fusion explicite, même lorsqu'un fast-forward serait possible. Cela conserve une trace visible de l'intégration d'une branche de fonctionnalité dans l'historique. Beaucoup d'équipes l'utilisent pour que chaque feature reste clairement identifiable.
--no-ff garde une trace visible de chaque feature.
Explication :
En detached HEAD, HEAD pointe directement sur un commit précis plutôt que sur une branche. Cela arrive en faisant
git checkout ou en se plaçant sur un tag. Les commits créés dans cet état ne sont rattachés à aucune branche et risquent d'être perdus s'ils ne sont pas sauvegardés.
Detached HEAD : tu es sur un commit, pas sur une branche.
Explication :
Pour conserver des commits faits en detached HEAD, on crée une branche qui les rattache :
git switch -c nouvelle-branche (ou git branch nom). Si on quittait l'état detached sans cette précaution en revenant directement sur une autre branche, les commits orphelins deviendraient inaccessibles.
Du travail en detached HEAD ? Crée vite une branche.
Explication :
git branch -d nom est une suppression sécurisée : Git refuse de supprimer une branche dont les commits ne sont pas encore fusionnés ailleurs, pour éviter une perte de travail. git branch -D nom est la version majuscule qui force la suppression sans vérification.
-d protège, -D force : majuscule = danger.
Explication :
git fetch récupère les nouveautés du dépôt distant et met à jour les références distantes (origin/main, etc.) sans modifier votre branche de travail. git pull ajoute une étape : il enchaîne le fetch avec un merge (ou un rebase). fetch est donc plus sûr pour inspecter avant d'intégrer.
fetch = je regarde, pull = je récupère et j'intègre.
Explication :
Dans un
.gitignore, le préfixe ! est une négation : il réinclut un fichier qui aurait été exclu par un motif précédent. Par exemple *.log
!important.log ignore tous les fichiers .log sauf important.log. L'ordre des règles est important : la négation doit venir après le motif d'exclusion.
Le ! réinclut une exception après une règle d'exclusion.
Explication :
Pour ignorer un dossier complet, on écrit son nom suivi d'une barre oblique :
build/. La barre finale indique explicitement qu'il s'agit d'un répertoire. On peut aussi utiliser des jokers, par exemple **/temp/ pour ignorer tout dossier temp à n'importe quelle profondeur.
Un slash final dans .gitignore = on cible un dossier.
Explication :
git blame fichier.txt annote chaque ligne du fichier avec le SHA du commit, l'auteur et la date de la dernière modification. C'est un outil précieux pour comprendre l'origine d'une ligne de code, identifier qui contacter ou retrouver le contexte d'un changement, sans intention d'accuser malgré son nom.
git blame répond à : qui a écrit cette ligne et pourquoi ?
Explication :
git clean -n est un mode simulation (dry-run) : il affiche les fichiers non suivis qui seraient supprimés, sans rien effacer. Pour réellement supprimer, on utilise git clean -f, et -d pour inclure les dossiers. On exécute toujours -n avant -f par précaution.
Toujours git clean -n avant git clean -f.
Explication :
git clean -fd supprime les fichiers non suivis (-f pour forcer) ainsi que les dossiers non suivis (-d). Cette commande ne touche ni aux fichiers suivis, ni aux fichiers ignorés (sauf avec -x). C'est utile pour nettoyer un répertoire de travail encombré de fichiers générés.
-f pour les fichiers, -d pour les dossiers non suivis.
Explication :
HEAD~3 désigne le commit situé trois générations en arrière en suivant le premier parent à chaque étape. Ainsi HEAD~1 est le commit précédent. Cette notation est très pratique pour des opérations comme git reset HEAD~2 ou git rebase -i HEAD~5.
HEAD~n : remonte n commits en arrière.
Explication :
Le symbole
^ sélectionne un parent d'un commit. Sur un commit de fusion, qui possède plusieurs parents, HEAD^1 est le premier parent (la branche sur laquelle on était) et HEAD^2 le deuxième (la branche fusionnée). Sur un commit ordinaire, HEAD^ équivaut à HEAD~1.
^ choisit quel parent, ~ remonte la lignée.
Explication :
git commit --amend permet de modifier le dernier commit : on peut corriger son message ou ajouter des fichiers oubliés (préalablement indexés). Attention, cette opération réécrit l'historique car le SHA change ; il ne faut donc pas l'utiliser sur un commit déjà poussé et partagé.
--amend : pour rectifier le dernier commit, pas un plus ancien.
Explication :
git restore --staged fichier désindexe un fichier : il le retire de la zone de staging tout en conservant ses modifications dans le répertoire de travail. C'est l'équivalent moderne et plus explicite de git reset HEAD fichier. Le fichier modifié reste donc présent, simplement non préparé pour le prochain commit.
restore --staged annule un git add sans rien perdre.
Explication :
git switch -c nouvelle-fonctionnalite crée une branche puis bascule dessus en une seule commande. C'est l'équivalent moderne de git checkout -b. La commande git switch a été introduite pour clarifier le rôle de git checkout, qui était surchargé de fonctions différentes.
switch -c = créer et basculer en une fois.
Explication :
Une Pull Request (ou Merge Request sur GitLab) propose d'intégrer une branche dans une autre. Elle ouvre un espace de relecture de code où les coéquipiers commentent, demandent des modifications et lancent les tests automatiques. La fusion n'a lieu qu'une fois la PR approuvée, ce qui améliore la qualité et le partage de connaissance.
La PR = un sas de relecture avant d'entrer dans main.
Explication :
git config --global écrit dans le fichier ~/.gitconfig et s'applique à tous les dépôts de l'utilisateur. git config --local écrit dans .git/config et ne concerne que le dépôt courant. La configuration locale est prioritaire sur la globale, ce qui permet de surcharger un réglage projet par projet.
Local écrase global : du plus précis au plus général.
Explication :
Le
rebase est idéal pour mettre à jour une branche de fonctionnalité privée avec les évolutions de main, en obtenant un historique propre et linéaire avant l'ouverture d'une PR. Le merge reste préférable pour intégrer une branche dans une branche partagée, car il ne réécrit pas l'historique.
Rebase pour nettoyer sa branche, merge pour intégrer.
Explication :
La notation à deux points
git log main..feature affiche les commits présents dans feature mais absents de main. C'est très pratique pour visualiser ce qu'une branche apporte avant de la fusionner. Inverser l'ordre, feature..main, montrerait ce que main a en plus.
A..B = ce que B contient en plus de A.
Explication :
Comme pour un rebase, un
git cherry-pick peut générer un conflit. On édite alors les fichiers, on fait git add, puis git cherry-pick --continue pour finaliser le commit. On peut aussi annuler avec git cherry-pick --abort pour revenir à l'état initial.
Cherry-pick en conflit : add puis --continue, comme le rebase.
Explication :
git log --stat ajoute, sous chaque commit, un résumé des fichiers modifiés avec le nombre de lignes ajoutées et supprimées. C'est un bon compromis entre --oneline, trop concis, et -p, qui affiche le diff complet. On obtient ainsi une vue d'ensemble de l'ampleur de chaque changement.
--stat : combien de lignes touchées, sans tout le diff.
Explication :
git remote -v (verbose) liste les dépôts distants avec leurs URL de fetch et de push. C'est la commande de référence pour vérifier vers quel serveur on pousse et d'où l'on récupère. Sans le -v, git remote n'affiche que les noms des distants.
remote -v pour voir où pointent vraiment tes distants.
Explication :
Sur une branche partagée, on annule un commit fautif avec
git revert . Cette commande crée un nouveau commit inverse qui défait les modifications, sans toucher à l'historique existant. Les collègues peuvent alors récupérer la correction par un simple git pull, sans conflit de divergence.
Commit poussé à corriger ? revert, jamais reset.
Explication :
git tag -a v2.0 -m "Version 2.0" crée un tag annoté, c'est-à-dire un objet Git complet contenant l'auteur, la date et le message. Sans l'option -a, git tag v2.0 créerait un simple tag léger. Pour les versions destinées à être publiées, le tag annoté est recommandé.
-a + -m : le duo pour un tag annoté propre.
Explication :
git diff HEAD~1 HEAD compare l'avant-dernier commit (HEAD~1) au dernier commit (HEAD), affichant ainsi exactement les modifications apportées par le dernier commit. Cette technique permet de revoir le contenu d'un commit précis en comparant deux références de l'historique.
diff entre deux refs = ce qui change de l'une à l'autre.
Explication :
git push --force remplace l'historique distant par le vôtre. Sur une branche partagée, cela peut écraser des commits poussés par d'autres et provoquer des pertes de travail difficiles à récupérer. Quand un push forcé est nécessaire après un rebase, on préfère --force-with-lease, qui refuse d'écraser si le distant a été mis à jour entre-temps.
Push forcé indispensable ? Préfère --force-with-lease.
Explication :
git stash clear vide entièrement la pile de stashs. Cette opération est irréversible : tous les travaux mis de côté sont supprimés d'un coup. Pour ne retirer qu'une entrée précise, on utilise plutôt git stash drop stash@{n}.
stash clear vide tout : assure-toi de ne plus en avoir besoin.
Explication :
git branch --merged affiche les branches dont les commits sont déjà intégrés dans la branche courante : elles peuvent généralement être supprimées sans risque avec git branch -d. À l'inverse, git branch --no-merged liste les branches contenant encore du travail non fusionné.
--merged repère les branches prêtes à être nettoyées.
Explication :
git rebase -i (interactif) ouvre un éditeur listant les commits concernés avec des actions possibles : pick pour garder, squash pour fusionner avec le précédent, reword pour changer le message, drop pour supprimer, ou réordonner les lignes. C'est l'outil idéal pour nettoyer son historique avant une Pull Request.
rebase -i : le couteau suisse pour ranger ses commits.