Je souhaite envoyer mes fichiers locaux et les placer dans un dépôt distant sans avoir à gérer de conflits de fusion. Je veux juste que ma version locale ait la priorité sur la version distante.
Comment puis-je faire cela avec Git?
Vous devriez pouvoir forcer votre révision locale sur le dépôt distant en utilisant
git Push -f <remote> <branch>
(par exemple, git Push -f Origin master
). Si vous laissez <remote>
et <branch>
forcer Appuyez sur toutes les branches locales qui ont défini --set-upstream
.
Sachez simplement que si d'autres personnes partagent ce référentiel, leur historique de révision sera en conflit avec le nouveau. Et s’ils ont des commits locaux après le changement, ils ne seront plus valables.
Update : Je pensais ajouter une note de côté. Si vous créez des modifications que d'autres personnes examineront, il n'est pas rare de créer une branche avec ces modifications et de rebasonner périodiquement pour les tenir à jour avec la branche de développement principale. Faites simplement savoir aux autres développeurs que cela se produira périodiquement pour 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 lorsque votre upstream
fait l'expérience. une force Push.
Dites que j'ai cloné votre repo et que j'ai ajouté quelques commits comme ceci:
D ---- E thème / A----B----C développement
Mais plus tard, la branche development
est touchée par un rebase
, ce qui me fera recevoir une erreur comme lorsque je lance git pull
:
Déballer des objets: 100% (3/3), terminé. Depuis <repo-location> * Développement de branches -> FETCH_HEAD Fusion automatique <fichiers > CONFLICT (contenu): Conflit de fusion dans <emplacements> La fusion automatique a échoué; corrige les conflits puis valide le résultat.
Ici, je pourrais résoudre les conflits et commit
, mais cela me laisserait avec une histoire de commit vraiment moche:
C ---- D ---- E ---- F sujet // A----B---------- ---- C 'développement
Il peut sembler intéressant d’utiliser git pull --force
mais soyez prudent car cela vous laissera des commits échoués:
D ---- E sujet A ---- B ---- C 'développement
La meilleure option est donc probablement de faire un git pull --rebase
. Cela me demandera de résoudre les conflits comme avant, mais pour chaque étape, au lieu de commettre, je vais utiliser git rebase --continue
. En fin de compte, l’historique des commits sera bien mieux présenté:
D '--- E' sujet / A----B----C 'développement
Mise à jour 3: Vous pouvez également utiliser l'option --force-with-lease
comme force "plus sûre". Push, comme mentionné par Cupcake dans son réponse :
Le fait de forcer avec un "bail" autorise l'échec de la force de poussée s'il y a de nouveaux commits inattendus sur la télécommande (techniquement, si vous ne les avez pas encore récupérés dans votre branche de suivi à distance), ce qui est utile si vous ne voulez pas écraser accidentellement les commits de quelqu'un que vous ne saviez même pas encore et vous voulez juste écraser les vôtres:
git Push <remote> <branch> --force-with-lease
Vous pouvez en apprendre plus sur l'utilisation de
--force-with-lease
en lisant les informations suivantes:
Ce que vous voulez fondamentalement faire est de forcer Push votre branche locale, pour écraser celle distante.
Si vous souhaitez une explication plus détaillée de chacune des commandes suivantes, consultez ma section de détails ci-dessous. Vous avez essentiellement 4 options différentes pour pousser la force 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, reportez-vous à la section Réponses ci-dessous.
Avertissement: le forcer écrasera la branche distante par l'état de la branche que vous poussez. Assurez-vous que c'est bien ce que vous voulez vraiment faire avant de l'utiliser, sinon vous risquez d'écraser les commits que vous voulez réellement conserver.
Vous pouvez complètement spécifier des branches spécifiques et une télécommande. Le drapeau -f
est la version abrégée de --force
git Push <remote> <branch> --force
git Push <remote> <branch> -f
Lorsque la branche vers Push branche est omise, Git la déterminera en fonction de vos paramètres de configuration. Dans les versions de Git ultérieures à la version 2.0, un nouveau référentiel aura les 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 comportaient des paramètres par défaut permettant d'envoyer plusieurs branches locales. Les réglages en question sont les réglages remote.<remote>.Push
et Push.default
(voir ci-dessous).
Lorsque la télécommande et la branche sont omises, le comportement de git Push --force
uniquement est déterminé par vos paramètres Push.default
Git config:
git Push --force
À partir de Git 2.0, le paramètre par défaut, simple
, consiste simplement à pousser votre branche actuelle vers son contre-partie distante en amont. La télécommande est déterminée par le paramètre branch.<remote>.remote
de la branche et passe par défaut au référentiel d'origine.
Avant la version 2.0 de Git, le paramètre par défaut, matching
, consiste simplement à déplacer toutes vos branches locales vers des branches portant le même nom sur la télécommande (la valeur par défaut étant Origine).
Vous pouvez lire davantage de paramètres Push.default
en lisant git help config
ou version en ligne de la page de manuel git-config (1) .
--force-with-lease
Le fait de forcer avec un "bail" autorise l'échec de la force de poussée s'il y a de nouveaux commits inattendus sur la télécommande (techniquement, si vous ne les avez pas encore récupérés dans votre branche de suivi à distance), ce qui est utile si vous ne voulez pas écraser accidentellement les commits de quelqu'un que vous ne saviez même pas encore et vous voulez juste écraser les vôtres:
git Push <remote> <branch> --force-with-lease
Vous pouvez en apprendre plus sur l'utilisation de --force-with-lease
en lisant les informations suivantes:
Une autre option (pour éviter toute poussée forcée qui peut être problématique pour d'autres contributeurs) est de:
master
sur Origin/master
master
, en gardant toujours les commits de la branche dédiée (ce qui signifie créer de nouvelles révisions sur master
qui reflèteront votre branche dédiée).git merge --strategy=theirs
.De cette façon, vous pouvez pousser maître à distance sans rien forcer.
git Push -f est un peu destructeur car il réinitialise toutes les modifications à distance apportées par quelqu'un d'autre de l'équipe. Une option plus sûre est {git Push --force-with-lease}.
{--Force-with-lease} refuse de mettre à jour une branche, sauf si c'est l'état attendu. 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 correspond à ce que nous attendons, car les références sont des hachages et codent implicitement la chaîne de 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. En pratique, cela signifie que, lorsque Alice mettra à jour sa branche et la transmettra au référentiel distant, la tête de référence de la branche sera mise à jour. Désormais, à moins que Bob ne tire la télécommande, sa référence locale à la télécommande sera périmée. Lorsqu'il utilise Push avec {--force-with-lease}, git vérifie la référence locale par rapport à la nouvelle télécommande et refuse de forcer la Push. {--force-with-lease} ne vous permet effectivement de forcer-Push que si personne d'autre n'a transmis les modifications à la télécommande dans l'intervalle. C'est {--force} avec la ceinture de sécurité.
fonctionne pour moi git Push --set-upstream origin master