OK, je pensais que c'était un simple scénario git, qu'est-ce qui me manque?
J'ai une master
succursale et une feature
succursale. Je fais un peu de travail master
, d'autres feature
, puis d'autres encore master
. Je me retrouve avec quelque chose comme ça (l'ordre lexicographique implique l'ordre des commits):
A--B--C------F--G (master)
\
D--E (feature)
Je n'ai aucun problème à git push origin master
maintenir la télécommande à master
jour, ni à git push origin feature
(lorsqu'elle est activée feature
) de maintenir une sauvegarde à distance pour mon feature
travail. Jusqu'à présent, nous sommes bons.
Mais maintenant, je veux rebaser feature
au-dessus des F--G
commits sur master, donc moi git checkout feature
et git rebase master
. Encore bon. Maintenant nous avons:
A--B--C------F--G (master)
\
D'--E' (feature)
Problème: au moment où je veux sauvegarder le nouveau feature
ramifié avec branchement git push origin feature
, le push est rejeté car l'arborescence a changé en raison du rebasage. Cela ne peut être résolu qu'avec git push --force origin feature
.
Je déteste utiliser --force
sans être sûr d'en avoir besoin. Alors, en ai-je besoin? Le rebasage implique- t-il nécessairement que le prochain push
soit --force
complet?
Cette branche de fonctionnalité n'est partagée avec aucun autre développeur, donc je n'ai aucun problème de facto avec la poussée de force, je ne vais pas perdre de données, la question est plus conceptuelle.
git pull feature-branch
, ce pull va générer un nouveau commit de fusion (en fusionnant les versions distantes et locales de la branche de fonctionnalité). Donc, soit vous obtenez une fusion inutile après le rebasage, soit vous poussez avec--force
.push --force
n'est donc pas un problème) pour garder l'historique des validations linéaire sans aucune validation de fusion.--force-with-lease
comme l'a suggéré @hardev est une excellente optionAu lieu d'utiliser -f ou --force, les développeurs devraient utiliser
Pourquoi? Parce qu'il vérifie les changements de la branche distante, ce qui est absolument une bonne idée. Imaginons que James et Lisa travaillent sur la même branche de fonctionnalité et Lisa a poussé un commit. James rebase maintenant sa branche locale et est rejeté lorsqu'il essaie de pousser. Bien sûr, James pense que cela est dû à un rebase et utilise --force et réécrirait toutes les modifications de Lisa. Si James avait utilisé --force-with-lease, il aurait reçu un avertissement indiquant que quelqu'un d'autre avait commis des commits. Je ne vois pas pourquoi quelqu'un utiliserait --force au lieu de --force-with-lease en poussant après un rebase.
la source
git push --force-with-lease
m'a sauvé un tas.--force-with-lease
répond au souci de l'utilisation--force
J'utiliserais plutôt "checkout -b" et c'est plus facile à comprendre.
lorsque vous supprimez, vous empêchez d'insérer une branche existante contenant un ID SHA différent. Je supprime uniquement la branche distante dans ce cas.
la source
push --force
, donc c'est seulement un moyen de contourner un git repo empêchant--force
. En tant que tel, je ne pense pas que ce soit jamais une bonne idée - soit le repo le permetpush --force
, soit pour une bonne raison, il le désactive. La réponse de Nabi est plus appropriée si elle--force
est désactivée sur le référentiel distant, car elle n'a pas le risque de perdre les commits d'autres développeurs ou de causer des problèmes.Une solution à cela est de faire ce que le script de fusion de rebasage de msysGit fait - après le rebase, fusionnez dans l'ancienne tête de
feature
avec-s ours
. Vous vous retrouvez avec le graphe de validation:... et votre poussée
feature
sera une avance rapide.En d'autres termes, vous pouvez faire:
(Non testé, mais je pense que c'est vrai ...)
la source
git rebase
(au lieu de fusionnermaster
dans votre branche de fonctionnalité) est de rendre l'historique des validations linéaires propres. Avec votre approche, l'histoire devient encore pire. Et comme le rebasage crée de nouveaux commits sans aucune référence à leurs versions précédentes, je ne suis même pas sûr que le résultat de cette fusion sera adéquat.merge -s ours
est qu'elle ajoute artificiellement une référence parent à la version précédente. Bien sûr, l'histoire ne semble pas propre, mais le questionneur semble être particulièrement dérangé par le fait de forcer la poussée de lafeature
branche, et cela contourne cela. Si vous voulez rebaser, c'est plus ou moins l'un ou l'autre. :) Plus généralement, je pense qu'il est intéressant que le projet msysgit fasse cela ....ours
stratégie, mais je pensais qu'elle ne s'applique qu'aux situations de conflit en les résolvant automatiquement en utilisant des changements dans notre branche. Il s'est avéré que cela fonctionne différemment. Et travailler de cette façon est très utile si vous avez besoin d'une version rebasée (par exemple, pour que le responsable du référentiel l'applique proprementmaster
) mais que vous voulez éviter de forcer la poussée (si beaucoup d'autres ppl utilisent votre branche de fonctionnalité pour une raison quelconque).Il se peut ou non qu'il n'y ait qu'un seul développeur sur cette branche, qui est maintenant (après le rebase) non aligné avec l'origine / la fonctionnalité.
En tant que tel, je suggère d'utiliser la séquence suivante:
Ouais, nouvelle branche, cela devrait résoudre cela sans --force, ce qui, je pense, est généralement un gros inconvénient.
la source
Ma façon d'éviter la poussée de force est de créer une nouvelle branche et de continuer le travail sur cette nouvelle branche et après une certaine stabilité, de supprimer l'ancienne branche qui a été rebasée:
la source
D'autres ont répondu à votre question. Si vous rebasez une branche, vous devrez forcer à pousser cette branche.
Rebase et un référentiel partagé ne s'entendent généralement pas. C'est réécrire l'histoire. Si d'autres utilisent cette branche ou se sont branchés à partir de cette branche, le rebasage sera assez désagréable.
En général, le rebase fonctionne bien pour la gestion des succursales locales. La gestion des succursales à distance fonctionne mieux avec les fusions explicites (--no-ff).
Nous évitons également de fusionner master dans une branche de fonctionnalité. Au lieu de cela, nous rebase à master mais avec un nouveau nom de branche (par exemple en ajoutant un suffixe de version). Cela évite le problème du rebasage dans le référentiel partagé.
la source
Quel est le problème avec un
git merge master
sur lafeature
branche? Cela préservera le travail que vous aviez, tout en le gardant séparé de la branche principale.Edit: Ah désolé, je n'ai pas lu votre énoncé de problème. Vous aurez besoin de force pendant que vous exécutez a
rebase
. Toutes les commandes qui modifient l'historique auront besoin de l'--force
argument. Il s'agit d'une sécurité intégrée pour vous empêcher de perdre du travail (l'ancienD
etE
serait perdu).Vous avez donc effectué un
git rebase
qui a fait ressembler l'arbre (bien qu'il soit partiellement masquéD
etE
ne se trouve plus dans une branche nommée):Ainsi, lorsque vous essayez de pousser votre nouvelle
feature
branche (avecD'
etE'
en elle), vous perdrezD
etE
.la source
Pour moi, suivre les étapes faciles fonctionne:
Après avoir fait tout ce qui précède, nous pouvons également supprimer la branche myFeature en suivant la commande:
la source
Ce qui suit fonctionne pour moi:
git push -f origin branch_name
et il ne supprime aucun de mon code.
Mais, si vous voulez éviter cela, vous pouvez procéder comme suit:
vous pouvez ensuite sélectionner tous vos commits dans la nouvelle branche.
git cherry-pick COMMIT ID
puis appuyez sur votre nouvelle branche.la source
-f
est un alias pour--force
, ce que la question tente d'éviter si possible.Comme l'OP comprend le problème, cherche juste une meilleure solution ...
Que diriez-vous de cela en tant que pratique?
Avoir une branche de développement de fonctionnalités réelle (où vous ne rebaserez jamais et ne forcez pas, afin que vos collègues développeurs de fonctionnalités ne vous détestent pas). Ici, récupérez régulièrement ces changements de main avec une fusion. Une histoire plus désordonnée , oui, mais la vie est facile et personne ne s'interrompt dans son travail.
Avoir une deuxième branche de développement de fonctionnalités, où un membre de l'équipe de fonctionnalités pousse régulièrement toutes les validations de fonctionnalités, voire rebasées, voire forcées. Donc, presque proprement basé sur un commit maître assez récent. Une fois la fonctionnalité terminée, poussez cette branche sur le maître.
Il existe peut-être déjà un nom de modèle pour cette méthode.
la source