Je veux pousser mes fichiers locaux, et les avoir sur un repo distant, sans avoir à gérer les conflits de fusion. Je veux juste que ma version locale soit prioritaire sur la version distante.
Comment puis-je faire cela avec Git ?
Je veux pousser mes fichiers locaux, et les avoir sur un repo distant, sans avoir à gérer les conflits de fusion. Je veux juste que ma version locale soit prioritaire sur la version distante.
Comment puis-je faire cela avec Git ?
Vous devriez être en mesure de forcer votre révision locale vers le dépôt distant en utilisant
git push -f <remote> <branch>
(par exemple git push -f origin master
). Abandon <remote>
et <branch>
poussera de force toutes les branches locales qui ont défini --set-upstream
.
Attention, si d'autres personnes partagent ce dépôt, leur historique de révision entrera en conflit avec le nouveau dépôt. Et s'ils ont des commits locaux après le point de changement, ils deviendront invalides.
Mise à jour : J'ai pensé ajouter une note complémentaire. Si vous créez des modifications qui seront revues par d'autres, il n'est pas rare de créer une branche avec ces modifications et de la rebaser périodiquement pour la maintenir à jour avec la branche de développement principale. Informez simplement les autres développeurs que cela se produira périodiquement afin qu'ils sachent à quoi s'attendre.
Mise à jour 2 : En raison du nombre croissant de téléspectateurs, j'aimerais ajouter quelques informations supplémentaires sur ce qu'il faut faire quand votre upstream
subit une poussée de force.
Disons que j'ai cloné votre repo et que j'ai ajouté quelques commits comme ceci :
D----E topic
/
A----B----C development
Mais plus tard, le development
La branche est frappée par un rebase
ce qui m'amènera à recevoir une erreur comme celle-ci lorsque je lancerai le programme git pull
:
Unpacking objects: 100% (3/3), done.
From <repo-location>
\* branch development -> FETCH\_HEAD
Auto-merging <files>
CONFLICT (content): Merge conflict in <locations>
Automatic merge failed; fix conflicts and then commit the result.
Ici, je pourrais régler les conflits et commit
mais cela me laisserait avec un historique de livraison vraiment moche :
C----D----E----F topic
/ /
A----B--------------C' development
Cela peut sembler séduisant d'utiliser git pull --force
mais faites attention car cela vous laissera avec des commits bloqués :
D----E topic
A----B----C' development
Donc probablement la meilleure option est de faire un git pull --rebase
. Cela m'obligera à résoudre tous les conflits comme précédemment, mais pour chaque étape, au lieu de valider, j'utiliserai la méthode suivante git rebase --continue
. Au final, l'historique des livraisons sera bien meilleur :
D'---E' topic
/
A----B----C' development
Puisque c'est la réponse choisie, je vais commenter ici. L'utilisation de la force n'est pas un problème lorsque l'on travaille seul. Par exemple, mon hôte en nuage démarre avec son propre git. Si je travaille localement et que je construis un projet, et que je veux le mettre sur mon hôte cloud (OpenShift), j'ai deux projets git séparés. Mon projet local et mon projet OpenShift. J'obtiens mon local comme je l'entends, mais je veux maintenant le prévisualiser sur mon OpenShift. Vous poussez alors sur OpenShift pour la première fois, en utilisant -f
drapeau. Essentiellement en mettant votre git local sur OpenShift.
Vous pouvez également faire git push -f
tant que la branche distante vers laquelle vous voulez pousser est la plus récente.
"will force push all local branches" - Pourquoi pousserait-il autre chose que la branche active ?
Ce que vous voulez faire, c'est de pousser votre branche locale, afin d'écraser la branche distante.
Si vous souhaitez une explication plus détaillée de chacune des commandes suivantes, consultez ma section détaillée ci-dessous. En fait, vous avez 4 options différentes pour forcer la mise à jour avec Git :
git push <remote> <branch> -f
git push origin master -f # Example
git push <remote> -f
git push origin -f # Example
git push -f
git push <remote> <branch> --force-with-lease
Si vous souhaitez une explication plus détaillée de chaque commande, consultez la section des réponses longues ci-dessous.
Attention : Force pushing va écraser la branche distante avec l'état de la branche que vous êtes en train de pousser. Assurez-vous que c'est bien ce que vous voulez faire avant de l'utiliser, sinon vous risquez d'écraser des commits que vous souhaitez conserver.
Vous pouvez spécifier complètement des branches spécifiques et une télécommande. Le site -f
est la version abrégée de --force
git push <remote> <branch> --force
git push <remote> <branch> -f
Lorsque la branche à pousser est omise, Git la détermine en fonction de vos paramètres de configuration. Dans les versions de Git postérieures à 2.0, un nouveau repo aura des paramètres par défaut pour pousser la branche actuellement extraite :
git push <remote> --force
alors qu'avant la version 2.0, les nouveaux dépôts auront des paramètres par défaut pour pousser plusieurs branches locales. Les paramètres en question sont les suivants remote.<remote>.push
et push.default
(voir ci-dessous).
Lorsque le distant et la branche sont omis, le comportement de seulement git push --force
est déterminé par votre push.default
Paramètres de configuration de Git :
git push --force
A partir de Git 2.0, le paramètre par défaut, simple
En fait, il suffit de pousser votre branche actuelle vers sa contrepartie distante en amont. Le distant est déterminé par le paramètre branch.<remote>.remote
et, par défaut, le repo d'origine.
Avant la version 2.0 de Git, le paramètre par défaut, matching
En gros, il s'agit de pousser toutes vos branches locales vers les branches portant le même nom sur le serveur distant (qui est par défaut origin).
Vous pouvez lire la suite push.default
les paramètres en lisant git help config
ou une version en ligne de la page de manuel git-config(1) .
--force-with-lease
Le forçage avec un "bail" permet au forçage d'échouer s'il y a de nouveaux commits sur la branche distante que vous n'attendiez pas (techniquement, si vous ne les avez pas encore récupérés dans votre branche de suivi distante), ce qui est utile si vous ne voulez pas accidentellement écraser les commits de quelqu'un d'autre que vous ne connaissez même pas encore, et que vous voulez juste écraser les vôtres :
git push <remote> <branch> --force-with-lease
Vous pouvez obtenir plus de détails sur la façon d'utiliser --force-with-lease
en lisant l'un des documents suivants :
Vous avez raison, mais cela ne devrait être utilisé que dans les cas suivants exceptionnel situations.
@ScottBerrevoets " Je préfère pousser ce que j'ai et le laisser écraser à distance plutôt que d'intégrer. " J'ai donné au PO exactement ce qu'il a demandé.
Je sais, mais le PO n'est peut-être pas conscient des conséquences de cette action. Vous avez techniquement répondu à la question, mais je pense qu'un avertissement pour ne pas faire ça n'est pas déplacé.
Une autre option est de :
master
sur origin/master
master
en conservant toujours les commits de la branche dédiée (c'est-à-dire en créant de nouvelles révisions au-dessus de la branche dédiée). master
qui sera le miroir de votre branche dédiée).git merge --strategy=theirs
.De cette façon, vous pouvez pousser le maître à distance sans avoir à forcer quoi que ce soit.
@alexkovelsky Tout push forcé réécrirait l'historique, forçant les autres utilisateurs du repo à réinitialiser leur propre repo local pour correspondre aux commits nouvellement poussés. Cette approche ne crée que de nouveaux commits et ne nécessite pas de push forcé.
Je vous suggère d'ajouter un titre à votre réponse : "Vous ne voulez pas forcer le passage" :)
Git push -f est un peu destructeur car il réinitialise toutes les modifications à distance qui avaient été faites par n'importe quel autre membre de l'équipe. Une option plus sûre est {git push --force-with-lease}.
Ce que fait {--force-with-lease} est de refuser de mettre à jour une branche à moins qu'elle ne soit dans l'état que nous attendons ; c'est-à-dire que personne n'a mis à jour la branche en amont. En pratique, cela fonctionne en vérifiant que la référence en amont est ce que nous attendons, parce que les références sont des hachages, et encodent implicitement la chaîne des parents dans leur valeur. Vous pouvez indiquer à {--force-with-lease} exactement ce qu'il faut vérifier, mais par défaut, il vérifiera la référence distante actuelle. Ce que cela signifie en pratique, c'est que lorsque Alice met à jour sa branche et la pousse vers le référentiel distant, la tête de référence de la branche sera mise à jour. Maintenant, à moins que Bob ne fasse un pull depuis le dépôt distant, sa référence locale vers le dépôt distant ne sera pas à jour. Lorsqu'il va pousser en utilisant {--force-with-lease}, git va vérifier la référence locale par rapport au nouveau dépôt distant et refuser de forcer la poussée. {--force-with-lease} ne vous permet effectivement de forcer le push que si personne d'autre n'a poussé de changements vers le distant dans l'intervalle. C'est {--force} avec la ceinture de sécurité.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.
171 votes
Est-ce que
git push origin --force
ne fonctionne pas pour vous ?3 votes
Duplicata possible de Remplacer le dépôt git distant par mon dépôt
0 votes
Il n'est pas clair si vous voulez seulement remplacer les fichiers .git, ou la copie de travail associée. Si c'est le dépôt git, git push est la réponse. Si vous voulez mettre à jour la copie de travail distante, vous devez utiliser un hook post-receive.
0 votes
@Mike ça marche pour moi pour une raison quelconque... je me demande ce qui s'est passé avec le PO.
1 votes
Une cause probable, la force push ne fonctionne pas est, qu'elle peut avoir été explicitement désactivée sur le repo distant (pour s'assurer que rien ne soit perdu à cause de contributeurs idiots et/ou malveillants) : utiliser
config receive.denyNonFastforwards
pour le découvrir.0 votes
J'ai essayé
git push origin some_branch --force
mais il renvoie toujours le message Everything is up-to-date. Mais..,git push origin your_branch:some_branch --force
et c'est ce qui me manquait. J'espère que cela vous aidera !0 votes
Mon premier 1000ème vote.