Nettoyer une fourche et la redémarrer depuis l'amont

396

J'ai bifurqué un dépôt, puis j'ai fait quelques changements et il semble que j'ai tout gâché.

Je souhaite le recommencer à zéro, en utilisant le courant amont / maître comme base pour mon travail.
Dois-je rebaser mon référentiel ou le supprimer du tout?

tampe125
la source
4
Réponses très complexes à une question simple. Supprimez simplement tout et clonez à nouveau le référentiel.
Yaza
1
@Yaza, non, cela pourrait vous causer encore plus de problèmes dans certains scénarios.
Shimmy Weitzhandler
@shimmy, pas si vous voulez recommencer à zéro comme le demandait OP.
Yaza

Réponses:

796

La solution la plus simple serait (en utilisant ' upstream' comme nom distant référençant le repo original fourchu):

git remote add upstream /url/to/original/repo
git fetch upstream
git checkout master
git reset --hard upstream/master  
git push origin master --force 

(Similaire à cette page GitHub, section "Que dois-je faire si je suis dans une mauvaise situation?" )

Sachez que vous pouvez perdre les modifications effectuées sur la masterbranche (à la fois localement, à cause de reset --hard, et sur le côté distant, à cause de lapush --force ).

Une alternative serait, si vous souhaitez conserver vos validations master, de rejouer ces validations en plus du courant upstream/master.
Remplacez la pièce de réinitialisation par a git rebase upstream/master. Vous devrez alors encore forcer la poussée.
Voir aussi " Que dois-je faire si je suis dans une mauvaise situation? "


Une solution plus complète, sauvegardant votre travail actuel (juste au cas où) est détaillée dans " Nettoyer la branche principale de git et déplacer certains commit vers une nouvelle branche ".

Voir aussi " Extraire les nouvelles mises à jour du référentiel GitHub d'origine dans le référentiel GitHub bifurqué " pour illustrer ce qu'est " upstream".

en amont


Remarque: les dépôts GitHub récents protègent la masterbranche contre push --force.
Vous devrez donc d'abord retirer la protection master(voir l'image ci-dessous), puis la re-protéger après avoir poussé de force ).

entrez la description de l'image ici


Remarque: sur GitHub en particulier, il existe maintenant (février 2019) un raccourci pour supprimer les dépôts fourchus pour les demandes d'extraction qui ont été fusionnées en amont.

VonC
la source
4
salut, cela a très bien fonctionné! btw la bonne syntaxe de réinitialisation estgit reset --hard upstream/master
tampe125
1
@ tampe125 Excellent. J'ai corrigé la syntaxe de git resetdans la réponse.
VonC
fatal: 'upstream' ne semble pas être un dépôt git
Benubird
@Benubird qui est le nom de la télécommande référençant le dépôt d'origine (celui que vous avez forké): voir le graphique et les git remotecommandes " " dans stackoverflow.com/a/3903835/6309 .
VonC
D'accord, mais il n'est pas clair à partir de votre question comment configurer cela, car par défaut 'en amont' n'est pas défini dans la ligne de commande car j'ai bifurqué via github.
Benubird
31

J'adore la réponse de VonC. En voici une version simple pour les débutants.

Il y a une télécommande git appelée origindont je suis sûr que vous êtes tous au courant. Fondamentalement, vous pouvez ajouter autant de télécommandes à un dépôt git que vous le souhaitez. Donc, ce que nous pouvons faire, c'est introduire une nouvelle télécommande qui est le dépôt d'origine et non la fourche. J'aime l'appeleroriginal

Ajoutons des dépôts originaux à notre fourche en tant que télécommande.

git remote add original https://git-repo/original/original.git

Maintenant, récupérons le dépôt d'origine pour nous assurer que nous avons le dernier code

git fetch original

Comme l'a suggéré VonC, assurez-vous que nous sommes sur le maître.

git checkout master

Maintenant, pour mettre à jour notre fourche avec le dernier code du référentiel d'origine, tout ce que nous avons à faire est de réinitialiser durement notre branche principale conformément à la télécommande d'origine.

git reset --hard original/master

Et vous avez terminé :)

Ahmad Awais
la source
2
J'entre fatal: ambiguous argument 'original/master': unknown revision or path not in the working tree.dans la dernière étape. Aucun conseil?
TomNorway
Il semble que cela ne vous laisse que du stock sur la branche distante d'origine. Je suppose qu'il manque une étape pour réinitialiser VOTRE fourche sur la bonne télécommande?
Ray Suelzer
1
originalest mieux que upstream(que les documents Github utilisent), tout comme origin/master"en amont" de local master. Réduit l'ambiguïté. Je me demande si c'est pour ça que vous l'utilisez?
vaughan
1
C'est exactement pourquoi je l'utilise!
Ahmad Awais
2
J'ai suivi ces instructions et maintenant git status dit: On branch master Votre branche et 'origin / master' ont divergé, et ont respectivement 52 et 5 validations différentes. (utilisez "git pull" pour fusionner la branche distante dans la vôtre) - mais je veux supprimer mes 5 commits. Quelle est la prochaine étape?
user3562927
6

Suite à @VonC excellente réponse. La politique de votre entreprise GitHub peut ne pas autoriser la «poussée forcée» sur le maître.

remote: error: GH003: Sorry, force-pushing to master is not allowed.

Si vous obtenez un message d'erreur comme celui-ci, veuillez suivre les étapes suivantes.

Pour réinitialiser efficacement votre fork, vous devez suivre ces étapes:

git checkout master
git reset --hard upstream/master
git checkout -b tmp_master
git push origin

Ouvrez votre fork sur GitHub, dans "Paramètres -> Branches -> Branche par défaut", choisissez 'new_master' comme nouvelle branche par défaut. Vous pouvez maintenant forcer le push sur la branche 'master':

git checkout master
git push --force origin

Ensuite, vous devez définir "master" comme branche par défaut dans les paramètres GitHub. Pour supprimer 'tmp_master':

git push origin --delete tmp_master
git branch -D tmp_master

D'autres réponses avertissant de la perte de votre changement s'appliquent toujours, faites attention.

Hugodby
la source
4

Comment le faire à 100% via l' interface graphique de Sourcetree

(Tout le monde n'aime pas faire les choses via l'interface de ligne de commande git)

Une fois que cela a été configuré, vous n'avez qu'à effectuer les étapes 7 à 13 à partir de là.

Récupérer> retirer la branche principale> réinitialiser à leur maître> Transférer les modifications au serveur

Pas

  1. Dans la barre d'outils du menu en haut de l'écran: "Référentiel"> "Paramètres du référentiel"

"Référentiel" mis en évidence dans la barre de menu supérieure

  1. "Ajouter"

Bouton "Ajouter" en bas de la boîte de dialogue

  1. Revenez à GitHub et copiez l'URL du clone.

Bouton "Cloner ou télécharger" sur le site Web de Github suivi de l'URL git

  1. Collez l'URL dans le champ "URL / Chemin" puis donnez-lui un nom qui a du sens. Je l'ai appelé "maître". Ne cochez pas la case "Remote remote" . Vous ne pourrez pas accéder directement à ce référentiel.

Champs "Nom distant" et "URL / Chemin d'accès" mis en évidence dans la boîte de dialogue "Détails distants"

  1. Appuyez sur "OK" et vous devriez le voir apparaître dans votre liste de référentiels maintenant.

référentiel "maître" ajouté à la liste des référentiels dans la boîte de dialogue "Paramètres du référentiel"

  1. Appuyez à nouveau sur "OK" et vous devriez le voir apparaître dans votre liste de "télécommandes".

référentiel "maître" mis en évidence dans la liste des télécommandes dans la barre latérale

  1. Cliquez sur le bouton "Récupérer" (en haut à gauche de la zone d'en-tête de l'arborescence source)

Bouton "Récupérer" dans la zone d'en-tête

  1. Assurez-vous que la case "Récupérer de toutes les télécommandes" est cochée et appuyez sur "ok"

Case à cocher "Extraire de toutes les télécommandes" mise en évidence dans la boîte de dialogue "Extraire"

  1. Double-cliquez sur votre branche "maître" pour la vérifier si elle n'est pas déjà extraite.

  2. Trouvez le commit que vous souhaitez réinitialiser, si vous avez appelé le référentiel "master", vous voudrez probablement trouver le commit avec la balise "master / master" dessus.

Exemple de commit avec une balise "master / master" dessus

  1. Faites un clic droit sur le commit> "Réinitialiser la branche actuelle sur ce commit".

  2. Dans la boîte de dialogue, définissez le champ "Mode d'utilisation:" sur "Ignorer toutes les modifications de la copie de travail", puis appuyez sur "OK" (assurez-vous de placer d'abord les modifications que vous ne souhaitez pas perdre dans une branche distincte).

Champ "Mode d'utilisation" mis en surbrillance dans la boîte de dialogue "Réinitialiser pour valider".  Il est défini sur "annuler toutes les modifications de copie de travail"

  1. Cliquez sur le bouton "Push" (en haut à gauche de la zone d'en-tête de l'arborescence Source) pour télécharger les modifications dans votre copie du dépôt.

Bouton "Push" dans la zone d'en-tête

Tu es fini!

Daniel Tonon
la source