Rebasage des branches distantes dans Git


135

J'utilise un référentiel Git intermédiaire pour mettre en miroir un référentiel SVN distant, à partir duquel les gens peuvent cloner et travailler. Le référentiel intermédiaire a sa branche principale rebasée tous les soirs à partir du SVN en amont, et nous travaillons sur des branches de fonctionnalités. Par exemple:

remote:
  master

local:
  master
  feature

Je peux repousser avec succès ma branche de fonctionnalités vers la télécommande et obtenir ce que j'attends:

remote:
  master
  feature

local:
  master
  feature

Je reconfigure ensuite la branche pour suivre la télécommande:

remote:
  master
  feature

local:
  master
  feature -> origin/feature

Et tout va bien. Ce que je voudrais faire à partir d'ici est de rebaser la branche de fonctionnalité vers la branche principale de la télécommande, mais je voudrais le faire à partir de ma machine locale. J'aimerais pouvoir faire:

git checkout master
git pull
git checkout feature
git rebase master
git push origin feature

Pour maintenir la branche de fonctionnalité distante à jour avec le maître distant. Cependant, cette méthode amène Git à se plaindre:

To <remote>
 ! [rejected]        feature -> feature (non-fast-forward)
error: failed to push some refs to '<remote>'
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes (e.g. 'git pull') before pushing again.  See the
'Note about fast-forwards' section of 'git push --help' for details.

git pullfait l'affaire mais provoque un commit de fusion que j'aimerais éviter. Je crains que le message indique feature -> featureplutôt que, feature -> origin/featuremais ce n'est peut-être qu'une présentation.

Suis-je en train de rater quelque chose ou de m'y prendre complètement de la mauvaise manière? Il n'est pas essentiel d'éviter de faire le rebase sur le serveur distant, mais cela rend la résolution des conflits de fusion à partir du rebase beaucoup plus difficile.


J'ai eu le même problème. Je voulais démarrer un modèle de rebase de branche ( comme celui-ci ). Ensuite, j'ai remarqué que j'avais fait une erreur: si vous voulez rebase (vous ne devriez pas pousser vos modifications sur la fonction distante avant de faire le rebase sur le maître) , vous confiez donc du code à votre fonction. Et maintenant, vous voulez le pousser vers votre fonction à distance. Avant de faire ceci: -Vous devriez aller chercher et tirer votre maître si vous en avez besoin. -Vous devez rebaser sur le maître s'il y a eu des changements sur le maître que vous n'avez pas dans votre fonction. Vous pouvez maintenant pousser la fonctionnalité et il n'y aura pas de problème.
Markus

Réponses:


185

Il s'agit de savoir si la fonctionnalité est utilisée par une personne ou si d'autres y travaillent.

Vous pouvez forcer la poussée après le rebase si ce n'est que vous:

git push origin feature -f

Cependant, si d'autres travaillent dessus, vous devez fusionner et ne pas rebaser hors de master.

git merge master
git push origin feature

Cela garantira que vous avez une histoire commune avec les personnes avec lesquelles vous collaborez.

À un autre niveau, vous ne devriez pas faire de back-merges. Ce que vous faites, c'est polluer l'historique de votre branche de fonctionnalité avec d'autres commits qui n'appartiennent pas à la fonctionnalité, ce qui rend le travail ultérieur avec cette branche plus difficile - rebasage ou non.

Ceci est mon article sur le sujet appelé branche par fonctionnalité .

J'espère que cela t'aides.


29
+1 pour if others are working on it, you should merge and not rebase off of master, rebase mieux être utilisé uniquement sur la branche privée.
Hendra Uzia

6
alternatif à la fonction d'origine git push -f vous pouvez également supprimer votre fonction à distance et la fonction push à nouveau
Markus

2
La fusion de master dans votre branche créera un commit de fusion et provoquera des conflits avec toute autre branche de fonctionnalité ouverte de master après que vos modifications soient poussées.
Steven

+1 pour git push origin feature -f. Dans certains contextes, il peut être nécessaire d'effectuer un rebase même avec des branches distantes. Le point crucial est de savoir ce que vous faites. Et nous devrions prendre en charge que vous supprimez peut-être des commits dans le dépôt distant.
enagra

33

Bien que vous ayez abordé ce sujet.

C'est une chose / un concept important dans git que beaucoup d'utilisateurs de git gagneraient à connaître. git rebase est un outil très puissant et vous permet d'écraser les commits ensemble, de supprimer les commits, etc. Mais comme avec tout outil puissant, vous devez essentiellement savoir ce que vous faites ou quelque chose pourrait vraiment mal tourner.

Lorsque vous travaillez localement et que vous dérangez vos succursales locales, vous pouvez faire ce que vous voulez tant que vous n'avez pas poussé les modifications vers le référentiel central. Cela signifie que vous pouvez réécrire votre propre histoire, mais pas celle des autres. En ne jouant qu'avec vos trucs locaux, rien n'aura d'impact sur les autres référentiels.

C'est pourquoi il est important de se rappeler qu'une fois que vous avez poussé les commits, vous ne devez pas les rebaser plus tard. La raison pour laquelle c'est important, c'est que d'autres personnes pourraient tirer dans vos commits et baser leur travail sur vos contributions à la base de code, et si vous décidez plus tard de déplacer ce contenu d'un endroit à un autre (rebasez-le) et de les pousser changements, alors d'autres personnes auront des problèmes et devront rebaser leur code. Imaginez maintenant que vous avez 1000 développeurs :) Cela ne fait que causer beaucoup de retouches inutiles.


Vote contre le mauvais langage: meta.stackexchange.com/questions/22232/…
Pouvoirs le

1
J'ai mis à jour ma langue.
ralphtheninja

5

Parce que vous avez rebasé featureau-dessus du nouveau master, votre local featuren'est plus une avance rapide origin/feature. Donc, je pense qu'il est parfaitement bien dans ce cas d'annuler la vérification d'avance rapide en faisant git push origin +feature. Vous pouvez également le spécifier dans votre configuration

git config remote.origin.push +refs/heads/feature:refs/heads/feature

Si d'autres personnes travaillent dessus origin/feature, elles seront dérangées par cette mise à jour forcée. Vous pouvez éviter cela en fusionnant le nouveau masterdans featureau lieu de le rebaser. Le résultat sera en effet une avance rapide.


1

Vous pouvez désactiver la vérification (si vous êtes vraiment sûr de savoir ce que vous faites) en utilisant l' --forceoption à git push.


15
Le problème est que je ne suis pas sûr de savoir vraiment ce que je fais :)
kfb

@r_: Veuillez lire ma réponse. Cela pourrait vous aider à comprendre ce que vous faites :)
ralphtheninja
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.