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?

rwolst
la source
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.

Sascha Wolf
la source
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
Dorian
la source
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
    
René Hamburger
la source
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.
Akhter-uz-zaman
la source
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É .

Chayapol
la source