web-dev-qa-db-fra.com

Pourquoi est-ce que je fusionne "branche de suivi à distance 'Origine / développement' en développement"?

Je suis le seul membre de mon organisation à s'engager avec le message suivant:

Fusionner la branche de suivi à distance 'Origine/Développer' dans Développer

Pas sûr de ce que je fais pour les causer, mais j'aimerais arrêter.

Quelle commande est-ce que je lance pour créer ce commit, et quelle est la commande appropriée que je devrais utiliser pour ne pas le produire?

112
Jordan Feldstein

git pull Est probablement en train de créer le commit. Si vous effectuez une validation locale, puis exécutez git pull Après que quelqu'un d'autre a poussé une validation dans le référentiel, Git télécharge la validation de l'autre développeur, puis la fusionne dans votre branche locale.

Comment éviter ces commits de fusion à l'avenir

Vous pouvez utiliser git pull --rebase Pour éviter que cela ne se produise à l'avenir, mais rebaser a ses risques et Je recommande d'éviter pull au total =.

Au lieu de cela, je vous encourage à suivre ce modèle d'utilisation:

# download the latest commits
git remote update -p

# update the local branch
git merge --ff-only @{u}

# if the above fails with a complaint that the local branch has
# diverged:
git rebase -p @{u}

Explication

  • git remote update -p Télécharge tous les commits des référentiels distants et met à jour les branches de suivi distantes (par exemple, Origin/master). Il ne touche PAS votre répertoire de travail, index ou branches locales.

    L'argument -p Supprime les branches en amont supprimées. Ainsi, si la branche foo est supprimée du référentiel Origin, git remote update -p Supprimera automatiquement votre référence Origin/foo.

  • git merge --ff-only @{u} Indique à Git de fusionner la branche en amont (l'argument @{u}) Dans votre branche locale, mais uniquement si votre branche locale peut être "transférée rapidement" à la branche en amont (en d'autres termes, si n'a pas divergé).

  • git rebase -p @{u} Déplace effectivement les commits que vous avez faits mais que vous n'avez pas encore placés au-dessus de la branche en amont, ce qui élimine la nécessité de créer des commits de fusion stupides que vous essayez d'éviter. Cela améliore la linéarité de l'historique du développement, ce qui facilite la révision.

    L'option -p Indique à Git de conserver les fusions. Cela empêche Git de linéariser les commits en cours de rebasement. Ceci est important si, par exemple, vous avez fusionné une branche de fonctionnalité dans master. Sans -p, Chaque validation de la branche de fonctionnalité serait dupliquée sur master dans le cadre de la linéarisation effectuée par git rebase. Cela rendrait l’historique du développement plus difficile à analyser et non plus facile.

    Attention : git rebase Ne fera peut-être pas ce que vous attendez, alors examinez les résultats avant de pousser. Par exemple:

    git log --graph --oneline --decorate --date-order --color --boundary @{u}..
    

Je préfère cette approche à git pull --rebase Pour les raisons suivantes:

  • Il vous permet de voir les commits entrants en amont avant de modifier votre historique pour les incorporer.
  • Il vous permet de passer l'option -p (--preserve-merges) À git rebase Au cas où vous auriez besoin de rebaser une fusion intentionnelle (par exemple, la fusion d'une branche de fonctionnalité déjà poussée en master).

Raccourci: git up Au lieu de git pull

Pour faciliter la tâche ci-dessus, je recommande de créer un alias appelé up:

git config --global alias.up '!git remote update -p; git merge --ff-only @{u}'

Maintenant, tout ce que vous avez à faire pour mettre votre succursale à jour est de lancer:

git up

au lieu de git pull. Si vous obtenez une erreur parce que votre branche locale a divergé de la branche en amont, vous êtes sur le point de rebaser.

Pourquoi pas git pull --rebase?

Exécuter git pull --rebase Équivaut à exécuter git fetch Suivi de git rebase. Cela tente d’avancer rapidement vers les nouveaux commits en amont, mais si cela n’est pas possible, vos commits locaux seront alors basés sur les nouveaux commits en amont. Ceci est généralement correct, mais soyez prudent:

  • Rebase est un sujet avancé et vous devez en comprendre les implications avant de le rebasonner.
  • git pull --rebase Ne vous donne pas l'occasion d'examiner les commits avant de les intégrer. En fonction de ce qui a changé en amont, il est tout à fait possible que rebase soit une mauvaise opération: un rebase --onto, merge, reset ou Push -f Pourrait être plus approprié que une plaine rebase.
  • Il n'est pas (actuellement) possible de passer --preserve-merges À l'opération de rebasement. Par conséquent, toute fusion intentionnelle d'une branche de fonctionnalité est linéarisée, ce qui permet de rejouer (et donc de dupliquer) tous les commits de la branche de fonctionnalité.

"Correction" d'un commit de fusion existant créé par git pull

Si vous n'avez pas encore poussé un commit de fusion créé par git pull, Vous pouvez rebaser le commit de fusion. En supposant que vous n'ayez effectué aucune fusion intentionnelle (par exemple, la fusion d'une branche de fonctionnalité déjà poussée dans votre branche actuelle), procédez comme suit:

git rebase @{u}

La commande ci-dessus indique à Git de sélectionner toutes les validations non fusionnées accessibles depuis HEAD (la validation actuelle), moins toutes les validations accessibles depuis @{u} (Qui est un raccourci pour "la branche en amont" , c.-à-d. Origin/master si HEAD est master), rejouez-les (cherry-pick) au-dessus de la branche en amont, puis déplacez la référence de la branche en cours pour pointer vers le résultat de rejouer les commits. Cela déplace effectivement les validations de non fusion sur la validation en amont la plus récente, ce qui élimine la fusion créée par git pull.

Si vous avez un commit de fusion intentionnel, vous ne voulez pas exécuter git rebase @{u} Car il rejouera tout de l'autre branche. Traiter cette affaire est beaucoup plus compliqué, c'est pourquoi il est bon d'utiliser git up Et d'éviter git pull Complètement. Vous devrez probablement utiliser reset pour annuler la fusion créée par pull puis faites git rebase -p @{u}. L'argument -p À git rebase N'a pas fonctionné de manière fiable pour moi. Vous devrez donc peut-être utiliser reset pour annuler la fusion intentionnelle, mettez à jour votre branche locale sur @{u}, Puis refait la fusion intentionnelle (ce qui est pénible s’il ya beaucoup de conflits de fusion velus).

184
Richard Hansen
git fetch
git rebase Origin/master

Ça devrait le faire. Ou si vous voulez continuer à utiliser pull

git pull --rebase

Vous pouvez également configurer cette branche dans votre configuration pour qu'elle se rebase automatiquement ou être ainsi configurée automatiquement pour toutes les autres branches de suivi que vous ferez. Ensuite, vous pouvez revenir à simplement utiliser

git pull

Plus à ce sujet dans la section "tirer avec rebase au lieu de fusionner" de cette page:

http://mislav.uniqpath.com/2010/07/git-tips/

17
Adam Dymitruk