542 votes

Fusionner (avec squash) tous les changements d'une autre branche en un seul commit

Dans Git, existe-t-il un moyen de fusionner toutes les modifications d'une branche dans une autre, mais de les écraser dans un seul commit en même temps ?

Je travaille souvent sur une nouvelle fonctionnalité dans une branche séparée et je fais régulièrement des commits/push - principalement pour la sauvegarde ou pour transférer ce sur quoi je travaille sur une autre machine. La plupart du temps, ces commits disent "Feature xxx WIP" ou quelque chose de redondant.

Une fois que ce travail est terminé et que je veux fusionner la branche WIP dans master, j'aimerais me débarrasser de tous ces commits intermédiaires, et n'avoir qu'un seul commit propre.

Existe-t-il un moyen simple de procéder ?

Sinon, pourquoi pas une commande qui écraserait tous les commits sur une branche depuis le moment où elle a été branchée ?

4voto

Stephen Crosby Points 704

J'ai créé mon propre alias git pour faire exactement cela. Je l'appelle git freebase ! Il prendra votre branche de fonctionnalité désordonnée et non basable existante et la recréera pour qu'elle devienne une nouvelle branche avec le même nom avec ses commits écrasés en un seul commit et rebasé sur la branche que vous avez spécifiée (master par défaut). A la toute fin, cela vous permettra d'utiliser le message de commit que vous souhaitez pour votre nouvelle branche "freebased".

Installez-le en plaçant l'alias suivant dans votre .gitconfig :

[alias]
  freebase = "!f() { \
    TOPIC="$(git branch | grep '\\*' | cut -d ' ' -f2)"; \
    NEWBASE="${1:-master}"; \
    PREVSHA1="$(git rev-parse HEAD)"; \
    echo "Freebaseing $TOPIC onto $NEWBASE, previous sha1 was $PREVSHA1"; \
    echo "---"; \
    git reset --hard "$NEWBASE"; \
    git merge --squash "$PREVSHA1"; \
    git commit; \
  }; f"

Utilisez-le à partir de votre branche de fonctionnalités en exécutant : git freebase <new-base>

Je ne l'ai testé que quelques fois, alors lisez-le d'abord et assurez-vous que vous voulez l'exécuter. Comme petite mesure de sécurité, il imprime le sha1 de départ afin que vous puissiez restaurer votre ancienne branche si quelque chose se passe mal.

Je le maintiendrai dans mon repo dotfiles sur github : https://github.com/stevecrozz/dotfiles/blob/master/.gitconfig

0voto

GSK Points 1322

Vous disposez d'une branche principale et d'une branche de fonctionnalités. Vous avez beaucoup de commits sur la branche des fonctionnalités. Vous ne voulez pas que tous les commits de la branche fonctionnalité apparaissent dans l'historique des commits du master. Suivez les étapes suivantes

  1. Créez une nouvelle branche à partir du dernier code maître et vous serez dans cette branche.
git checkout -b latest_MCode
  1. Maintenant, fusionnez votre branche de fonctionnalités avec la branche latest_Mcode
git merge --squash feature
  1. Faire un commit sans le paramètre -m

git commit # sans -m

Un éditeur devrait être une fenêtre contextuelle avec tous les journaux de validation et les fichiers modifiés à partir de la branche de fonctionnalité. Vous pouvez voir tous les commits de la branche fonctionnalité ici. Si vous le souhaitez, vous pouvez tout effacer, et n'écrire qu'une seule ligne du message de validation que vous souhaitez afficher après la fusion dans master. Appuyez sur i puis écrivez votre message et appuyez sur Esc->:wq->Enter pour sauvegarder et quitter l'éditeur. 4. Fusionnez votre branche nouvellement créée dans master

git checkout master
git merge latest_Mcode
git push

Vous avez terminé ! La réponse originale se trouve à l'adresse suivante GithubLink

-1voto

Arjun Mullick Points 1

git merge --squash <feature branch> La commande "git commit" vous indique tous les messages de commit de la branche des fonctionnalités avec votre choix de les conserver.

Pour moins d'engagement, fusionner .

git merge do x fois --git reset HEAD^ --soft then git commit .

Risque - les fichiers supprimés peuvent réapparaître .

-6voto

NamshubWriter Points 7238

Vous pouvez le faire avec la commande "rebase". Appelons les branches "main" et "feature" :

git checkout feature
git rebase main

La commande rebase rejouera tous les commits sur "feature" en un seul commit avec un parent égal à "main".

Vous pourriez vouloir exécuter git merge main avant git rebase main si "main" a changé depuis la création de "feature" (ou depuis la dernière fusion). De cette façon, vous avez toujours votre historique complet au cas où vous auriez un conflit de fusion.

Après le rebasement, vous pouvez fusionner votre branche avec la branche principale, ce qui devrait entraîner une fusion rapide :

git checkout main
git merge feature

Voir le rebase page de Comprendre Git de manière conceptuelle pour une bonne vue d'ensemble

0 votes

Cela n'a pas fonctionné pour moi. J'ai créé un simple repo de test, avec une branche WIP et j'ai essayé ce qui précède et j'ai obtenu des conflits de fusion (même si je n'avais pas fait de changements sur master).

0 votes

Si la fonctionnalité a été créée à partir de main (git checkout -b feature main) et que vous avez effectué une fusion récente à partir de main, vous ne devriez pas avoir de conflits lors de la refonte.

0 votes

OK, j'ai réessayé. Il n'y a pas eu de conflits cette fois-ci, mais l'historique n'a pas été écrasé.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X