web-dev-qa-db-fra.com

Combinaison de plusieurs commits en un avant de pousser

Cette question ne concerne pas seulement la manière d'accomplir cette tâche, mais aussi de savoir si cela est une bonne ou une mauvaise pratique avec Git.

Considérez que localement, je travaille le plus souvent sur la branche maître, mais j’ai créé une branche thématique que j’appellerai "topical_xFeature". Dans le processus de travail sur "topical_xFeature" et le passage alterné pour effectuer un autre travail sur la branche maître, il s’avère que j’ai effectué plus d’un commit sur la branche "topical_xFeature", mais entre chaque commit, je n'ai Pousser.

First, considéreriez-vous cette mauvaise pratique? Ne serait-il pas plus sage de s'en tenir à un commit par branche par push? Dans quels cas serait-il bon d'avoir plusieurs commits sur une branche avant qu'un Push soit effectué?

Second, comment dois-je accomplir au mieux pour amener les validations multiples sur la branche topical_xFeature dans la branche maître pour un push? Est-ce gênant de ne pas s’inquiéter à ce sujet et de ne faire que le Push où plusieurs commits sont poussés, ou est-ce moins agaçant de fusionner d’une manière ou d’une autre les commits en un puis de pousser? Encore une fois, comment faire cela?

119
Todd Hopkinson

Pour votre première question, non, il n'y a rien de mal à appliquer plusieurs commits à la fois. Plusieurs fois, vous voudrez peut-être diviser votre travail en quelques petits commits logiques, mais ne les pousser que lorsque vous aurez l’impression que toute la série est prête. Vous pouvez également effectuer plusieurs commits localement alors que vous êtes déconnecté et les envoyer tous une fois que vous êtes à nouveau connecté. Il n'y a aucune raison de vous limiter à un commit par Push.

De manière générale, j’estime qu’il est judicieux de laisser à chaque validation un changement unique, logique et cohérent, qui inclut tout ce dont il a besoin pour fonctionner (pour que votre code ne soit pas dans un état défaillant). Si vous avez deux commits, mais que cela provoquerait la rupture du code si vous appliquiez seulement le premier, il serait peut-être judicieux de supprimer le deuxième commit dans le premier. Mais si vous avez deux commits où chacun apporte un changement raisonnable, il est préférable de les appliquer séparément.

Si vous voulez écraser plusieurs commits ensemble, vous pouvez utiliser git rebase -i. Si vous êtes sur la branche topical_xFeature, vous courriez git rebase -i master. Cela ouvrira une fenêtre d’éditeur, avec un groupe de commits listés précédés de pick. Vous pouvez changer tout le premier sauf squash, ce qui indiquera à Git de garder toutes ces modifications, mais de les écraser dans le premier commit. Après cela, vérifiez master et fusionnez dans votre branche:

git checkout topical_xFeature
git rebase -i master
git checkout master
git merge topical_xFeature

Alternativement, si vous voulez juste tout écraser dans topical_xFeature dans master, vous pouvez simplement procéder comme suit:

git checkout master
git merge --squash topical_xFeature
git commit

Lequel vous choisissez est à vous. En règle générale, je ne m'inquiète pas de la présence de plusieurs commits plus petits, mais parfois vous ne voulez pas vous soucier des commits mineurs supplémentaires, vous devez donc les regrouper en un seul.

128
Brian Campbell

C’est de cette façon que j’ai l'habitude de combiner plusieurs validations en une seule validation avant d'envoyer le code.

Pour cela, je vous suggère d'utiliser le concept 'squash' fourni par GIT.

Suivez les étapes ci-dessous.

1) git rebase -i master (au lieu de master vous pouvez également utiliser un commit spécifique)

ouvrez l'éditeur interactif rebase, où il affichera tous vos commits. En gros, vous devez identifier les commits que vous souhaitez fusionner en un seul.

Imaginez que ce soient vos commits et montrés quelque chose comme ceci dans l'éditeur.

pick f7f3f6d changed my name a bit    
pick 310154e updated README formatting and added blame   
pick a5f4a0d added cat-file  

Il est important de noter que ces commits sont répertoriés dans l'ordre inverse de celui que vous voyez normalement à l'aide de la commande log. Cela signifie que le plus ancien commit sera affiché en premier.

2) remplacez 'pick' par 'squash' pour les derniers changements validés. quelque chose comme montré ci-dessous. Ce faisant, vos 2 derniers commits seront fusionnés avec le premier.

pick f7f3f6d changed my name a bit         
squash 310154e updated README formatting and added blame   
squash a5f4a0d added cat-file

Vous pouvez également utiliser la forme abrégée si vous avez beaucoup d'engagement à combiner:

p f7f3f6d changed my name a bit         
s 310154e updated README formatting and added blame   
s a5f4a0d added cat-file

pour l'édition, utilisez 'i', cela permettra à l'éditeur d'insérer. Gardez à l'esprit que la plupart des validations (les plus anciennes) ne peuvent pas être supprimées car il n'y a aucune validation précédente à combiner. Donc, il faut choisir ou 'p'. Utilisez 'Esc' pour quitter le mode insertion.

3) Maintenant, enregistrez l'éditeur avec la commande suivante. : wq

Lorsque vous sauvegardez cela, vous avez un seul commit qui introduit les modifications des trois précédents.

J'espère que ceci vous aidera.

62
Kondal Kolipaka

First : rien ne vous oblige à avoir qu'un seul commit par branche: un push est un mécanisme de publication vous permettant de publier un historique local (c'est-à-dire une collection). des commits) sur un repo distant.

Deuxième : un git merge --no-ff topical_xFeature enregistrerait sur le maître en tant que simple commettre votre travail de sujet, avant de pousser master.
(De cette façon, vous gardez topical_xFeature autour pour de futures évolutions, que vous pouvez enregistrer sur master sous la forme d’un nouveau commit à la prochaine fusion --no-ff.
Si vous vous débarrassez de topical_xFeature est le but, alors git merge --squash est la bonne option, comme indiqué en détail dans Brian Campbellréponse .)

11
VonC

Basculez vers la branche principale et assurez-vous d'être à jour.

git checkout master

git fetch cela peut être nécessaire (selon votre configuration git) de recevoir les mises à jour sur Origin/master

git pull

Fusionner la branche de fonctionnalité dans la branche principale.

git merge feature_branch

Réinitialisez la branche principale à l'état d'origine.

git reset Origin/master

Git considère maintenant toutes les modifications comme des modifications non mises en scène. Nous pouvons ajouter ces modifications en tant que commit. Ajouter . ajoutera également des fichiers non suivis.

git add --all

git commit

Réf.: https://makandracards.com/makandra/527-squash-several-git-commits-into-a-single-commit

8
shiva kumar

1) Choisissez d’abord quel commit vous voulez que tout vienne après.

git reflog
5976f2b HEAD@{0}: commit: Fix conflicts
80e85a1 HEAD@{1}: commit: Add feature
b860ddb HEAD@{2}: commit: Add something

2) Réinitialisez à la tête que vous avez sélectionnée (j'ai choisi HEAD @ {2})

git reset b860ddb --soft

3) statut git (juste pour être sûr)

4) Ajoutez votre nouveau commit

git commit -m "Add new commit"

Remarque: HEAD@{0} & HEAD@{1} Sont maintenant fusionnés dans 1 commit, ceci peut également être fait pour plusieurs commits.

git reflog devrait à nouveau afficher:

git reflog
5976f2b HEAD@{0}: commit: Add new commit
b860ddb HEAD@{1}: commit: Add something
3
Eddy Ekofo