web-dev-qa-db-fra.com

Combinaison de plusieurs commits avant de pousser dans Git

J'ai un groupe de commits sur mon référentiel local qui sont thématiquement similaires. J'aimerais les combiner en un seul commit avant de les pousser vers une télécommande. Comment fait-on ça? Je pense que rebase fait cela, mais je ne peux pas donner de sens à la documentation.

365
muudscope

Ce que vous voulez faire est appelé "écraser" dans git. Vous avez beaucoup d'options (trop?), Mais si vous souhaitez simplement fusionner tous vos commits non envoyés en un seul, procédez comme suit:

git rebase -i Origin/master

Ceci fera apparaître votre éditeur de texte (-i est pour "interactif") avec un fichier qui ressemble à ceci:

pick 16b5fcc Code in, tests not passing
pick c964dea Getting closer
pick 06cf8ee Something changed
pick 396b4a3 Tests pass
pick 9be7fdb Better comments
pick 7dba9cb All done

Remplacez tous les pick par squash (ou s) à l’exception du premier:

pick 16b5fcc Code in, tests not passing
squash c964dea Getting closer
squash 06cf8ee Something changed
squash 396b4a3 Tests pass
squash 9be7fdb Better comments
squash 7dba9cb All done

Enregistrez votre fichier et quittez votre éditeur. Ensuite, un autre éditeur de texte s'ouvrira pour vous permettre de combiner les messages de validation de tous les validations en un seul message de validation.

Voila! Googling "git squashing" vous donnera des explications sur toutes les autres options disponibles.

554
Leopd

Si vous avez beaucoup de commits et que vous voulez seulement écraser les derniers X commits, recherchez l'ID de validation du commit à partir duquel vous souhaitez commencer à écraser et faire

git rebase -i <that_commit_id>

Procédez ensuite comme décrit dans la réponse de leopd en remplaçant toutes les picks par squashes, à l'exception du premier.

Exemple :

871adf OK, feature Z is fully implemented      --- newer commit --┐
0c3317 Whoops, not yet...                                         |
87871a I'm ready!                                                 |
643d0e Code cleanup                                               |-- Join these into one
afb581 Fix this and that                                          |
4e9baa Cool implementation                                        |
d94e78 Prepare the workbench for feature Z     -------------------┘
6394dc Feature Y                               --- older commit

Vous pouvez soit faire ceci (écrire le nombre de commits):

git rebase --interactive HEAD~[7]

Ou ceci (écrivez le hash du dernier commit que vous ne voulez pas voulez écraser):

git rebase --interactive 6394dc
70
Noich

Il y a pas mal de réponses de travail ici, mais j'ai trouvé cela le plus facile. Cette commande ouvrira un éditeur dans lequel vous pouvez simplement remplacer pick par squash afin de les supprimer/les fusionner en un seul.

git rebase -i HEAD~4

4 est le nombre de commits que vous souhaitez écraser en un. Ceci est expliqué ici aussi.

32
vikas027

Vous pouvez le faire avec git rebase -i, en transmettant la révision que vous souhaitez utiliser comme "racine":

git rebase -i Origin/master

ouvrira une fenêtre d'éditeur montrant tous les commits que vous avez effectués après le dernier commit dans Origin/master. Vous pouvez rejeter les validations, regrouper les validations dans une validation unique ou modifier les validations précédentes.

Quelques ressources peuvent probablement expliquer cela mieux et en donner d'autres exemples:

http://book.git-scm.com/4_interactive_rebasing.html

et

http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html

sont les deux premières bonnes pages que j'ai pu trouver.

25
Justin Weiss

Je suis venu avec

#!/bin/sh

message=`git log --format=%B Origin..HEAD | sort | uniq | grep -v '^$'`
git reset --soft Origin
git commit -m "$message"

Combine, trie, unifie et supprime les lignes vides du message de validation. J'utilise ceci pour les modifications locales d'un wiki github (en utilisant gollum)

11
ruediste

Et ma manière de squashing multiple Push est (vous avez peut-être poussé vers votre propre branche de nombreux commits et maintenant vous souhaitez faire une demande de tir et vous ne voulez pas les encombrer de nombreux commits que vous avez déjà poussé). La façon dont je le fais (aucune autre option plus simple, pour autant que je sache, est).

  1. Créez une nouvelle branche pour squash (branche de la branche d'origine vers laquelle vous souhaitez extraire la demande).
  2. Poussez la branche nouvellement créée.
  3. Fusionner la branche avec les commits (déjà poussés) vers la nouvelle branche.
  4. Rebaser la nouvelle branche et la courge.
  5. Poussez nouvelle branche.
  6. Créez une nouvelle demande d'extraction pour une nouvelle branche qui a maintenant un seul commit.

Exemple:

git checkout from_branch_you_wish_to_pull_request_to
git checkout -b new_branch_will_have_single_squashed_commit
git Push -u new_branch_will_have_single_squashed_commit
git merge older_branch_with_all_those_multiple_commits
git rebase -i (here you squash)
git Push Origin new_branch_will_have_single_squashed_commit

Vous pouvez maintenant extraire la demande dans from_branch_you_wish_to_pull_request_to

6
Tomer Ben David

Vous pouvez écraser (rejoindre) les commits avec un Rebase interactif . Il y a une jolie vidéo YouTube de Nice qui montre comment faire cela en ligne de commande ou avec SmartGit :

Si vous êtes déjà un utilisateur SmartGit, vous pouvez sélectionner tous vos commits sortants (en maintenant la touche Ctrl enfoncée) et ouvrir le menu contextuel (clic droit) pour écraser vos commits.

C'est très confortable

enter image description here

Il existe également un très bon tutoriel de Atlassian qui montre comment cela fonctionne:

6
Benny Neugebauer

Vous voudrez probablement utiliser Interactive Rebasing , qui est décrit en détail dans ce lien.

Vous pouvez trouver d'autres bonnes ressources si vous recherchez "git rebase interactive".

2
Greg Hewgill