Remote rejeté (mise à jour superficielle non autorisée) après la modification de l'URL distante Git


164

J'ai un projet sous contrôle de version Git que j'ai travaillé à la fois sur un serveur et sur mon ordinateur local. À l'origine, j'avais défini l'origine distante comme mon ordinateur local, mais je voudrais maintenant changer cela en BitBucket.

Sur le serveur j'ai utilisé la commande

git remote set-url origin bitbucket_address

Mais maintenant, quand j'essaye de pousser mon projet, j'obtiens l'erreur

 ! [remote rejected] master -> master (shallow update not allowed)

Qu'est-ce qui cause ce problème et comment le résoudre?


3
Comment avez-vous cloné votre version locale? git clone --depth?
— Sascha Wolf

C'était il y a quelque temps et je ne m'en souviens plus. Existe-t-il un moyen de le savoir?
— rwolst

2
Il devrait y avoir un fichier nommé shallowdans votre .gitdossier.
— Sascha Wolf

Oui, je peux voir un shallowfichier.
— rwolst

Voir stackoverflow.com/a/50996201 pour une solution qui supprime (ou réécrit) simplement l'historique manquant
— caw

Réponses:


329

Comme il semble que vous avez utilisé git clone --depth <number>pour cloner votre version locale. Il en résulte un clone peu profond . Une limitation d'un tel clone est que vous ne pouvez pas le pousser dans un nouveau référentiel.

Vous avez maintenant deux options:

  1. si vous ne vous souciez pas de votre histoire actuelle ou manquante, jetez un œil à cette question
  2. si vous souhaitez conserver votre historique complet, continuez à lire:

Alors, tu veux garder ton histoire, hein? Cela signifie que vous devez libérer votre référentiel. Pour ce faire, vous devrez à nouveau ajouter votre ancienne télécommande.

git remote add old <path-to-old-remote>

Ensuite, nous git fetchrécupérons l'historique restant de l'ancienne télécommande (comme suggéré dans cette réponse ).

git fetch --unshallow old

Et maintenant, vous devriez être en mesure de pousser dans votre nouveau référentiel distant.


Remarque : après avoir annulé votre clone, vous pouvez évidemment supprimer à nouveau l'ancienne télécommande.


45
Et si j'ai cloné un projet de démarrage et que je ne veux pas / n'ai pas besoin de tout l'historique? y a-t-il un moyen de l'éviter?
— itamar

9
@itamar Cela semble être un bon exemple pour une nouvelle question parfaitement valable. Vous pouvez créer un lien vers cette question pour référence.
— Sascha Wolf

14
Posée comme nouvelle question stackoverflow.com/questions/29748197/…
— itamar

2
Notez que cela git fetch --unshallowpeut prendre une refspec pour ne débloquer qu'une certaine branche plutôt que l'ensemble du dépôt. Ex:git fetch --unshallow origin refs/heads/mydeepbranch:refs/remotes/origin/mydeepbranch
— clacke

5
Si vous poussez vers un repo qui est un peu en retard sur le repo à partir duquel vous avez cloné, sans créer un tout nouveau repo, il suffit que votre référence locale soit suffisamment profonde pour contenir la référence distante. Donc, si vous aviez origin/master20 commits avant votre oldrepo/masterlorsque vous clone --depth 1l' avez édité, et que vous avez effectué 17 commits locaux depuis, il vous suffit de le faire git fetch --depth 37 origin refs/heads/master:refs/remotes/origin/master(excuses pour toute erreur ponctuelle), et vous pouvez le faire git push oldrepo mastersans incident (peut nécessiter git 1.9.0 ou plus récent).
— clacke

28

Dans le cas où votre repo est origin, et le repo d'origine est upstream:

git fetch --unshallow upstream

cela fonctionne pour moi, et assez facile alors la réponse la plus votée.
— Maosheng Wang

11

Une autre option si vous voulez garder le dépôt tel quel avec les nouveaux commits que vous avez ajoutés depuis le commit initial superficiel est la suivante: Modifiez ce commit avec un rebase interactif .

  • Démarrez un rebase interactif comprenant le premier commit (racine) avec

    git rebase --interactive --root
    
  • Remplacez le pick(s) commit (s) initial (s) par editet enregistrez et fermez le fichier.

    Si vous avez cloné le dépôt avec une profondeur supérieure à 1, vous devrez peut-être faire de même pour tous ces commits. Ou, alternativement, exécutez fixuppour tous ceux-ci pendant le rebase interactif.

  • Convertissez ce commit en un commit régulier et peu clair avec

    git commit --amend --no-edit
    

    Cela modifiera également l'ID de validation et vous ajoutera en tant que co-auteur de cette validation initiale.

  • N'oubliez pas de terminer votre rebase

    git rebase --continue
    

Je vous remercie! Cela a fonctionné comme un charme, lorsque le référentiel d'origine a été supprimé et que vous n'en avez qu'une copie superficielle.
— Vitalii Dmitriev

9

Si vous voulez pousser le nouveau repo tel quel, vous pouvez essayer ceci:

  • Supprimez d'abord le old git folderde votre dépôt actuel,sudo rm -rf .git
  • Puis initialisez à nouveau le git git init
  • Ajoutez ensuite le nouveau référentiel distant git remote add your-new-repo
  • Puis poussez-le.

J'ai trouvé que c'était une meilleure solution, car elle ne nécessite pas une poussée vers l'ancienne. Parfois, cela peut arriver avec des passe-partout.
— rnpd le

C'est essentiellement la réponse à la question connexe que vous pouvez trouver ici .
— Sascha Wolf

@NachPD Je ne suis pas sûr de ce que vous voulez dire, quand vous dites que l'autre solution nécessite "une poussée vers l'ancienne". Voulez-vous dire une recherche au lieu d'une poussée? Parce qu'il ne nécessite pas de poussée.
— Sascha Wolf

0

Si la récupération de --unshallow ne fonctionne pas. Il doit y avoir des problèmes avec votre succursale. Corrigez-le avec la commande suivante avant de le pousser.

git filter-branch -- --all

Faites cela uniquement avec --unshallow ne fonctionne pas car il y a un problème de SÉCURITÉ .

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.