web-dev-qa-db-fra.com

Erreur Git: RPC a échoué; résultat = 22, code HTTP = 404

J'utilise SourceTree sur OSX et j'utilise Git pour pousser vers Visual Studio Online. J'obtiens l'erreur suivante:

POST git-receive-pack (490857233 octets)
erreur: RPC a échoué; résultat = 22, code HTTP = 404
fatal: l'extrémité distante a raccroché de façon inattendue
Tout est à jour
Complété avec des erreurs, voir ci-dessus

J'ai déjà essayé ce qui suit:

git config --global http.postBuffer 524288000
22
guinzu

Je viens de rencontrer une erreur très similaire (pour laquelle cette réponse est le meilleur résultat Google) - la solution était dans un commentaire de @Liviu Chircu

La solution était de mettre le .git à la fin de l'url

git clone http://myURL/projectname
Cloning into 'projectname'...
error: RPC failed; result=22, HTTP code = 404
fatal: The remote end hung up unexpectedly

Pourtant:

git clone http://myURL/projectname.git

réussi.

Ce qui est étrange, c'est que l'URL d'origine sans .git a réussi sur deux machines Linux et un bureau Windows, mais a échoué sur une troisième machine Linux. Comprenant .git le fait fonctionner sur toutes les machines.

43
user2711915

Votre référentiel peut être trop volumineux, essayez de télécharger des morceaux, comme utiliser GIT pour revenir en arrière à mi-chemin dans l'historique ou ainsi dans une nouvelle branche, poussez cela, puis poussez les derniers commits.

Probablement une meilleure solution de contournement, mais c'est ce que j'ai pu faire pour résoudre rapidement mon problème

J'ai pu pousser 108,61 Mio, mais pas 144,64 Mio

J'espère que cela t'aides.

2
Oxymoron

Mise à jour de juin 2016: Selon cette page :

L'authentification SSH auprès des dépôts Team Services Git est actuellement en aperçu privé

Je vous recommande de passer à l'authentification SSH si vous le pouvez, car cela devrait éviter complètement ce problème. (Notez que vous pouvez utiliser HTTPS et SSH en tandem, même sur la même machine .)

Si cela n'a pas encore été activé pour vous, ou si vous ne pouvez pas autrement basculer vers SSH, continuez à lire.


Message d'origine:

Comme @Oxymoron l'a mentionné, le problème est que votre référentiel est trop grand, ou plus précisément, vous essayez de trop pousser à la fois.

Quelle? Ça n'a pas de sens! Ce n'est pas ce que le HTTP 404 le code est pour!

Cela n'a pas de sens pour moi non plus. * regarde dans la direction générale de Microsoft *

Vous avez probablement déjà rencontré cela et obtenu une erreur comme celle-ci:

Unable to rewind rpc post data - try increasing http.postBuffer

Et c'est probablement ce qui vous a amené à faire le git config commande que vous avez mentionnée.

Maintenant, dans le but de publier une réponse distincte: je voudrais développer la façon dont vous pouvez résoudre ce problème. Vous essaierez toujours de pousser un plus petit nombre de commits à la fois, mais ce n'est pas toujours aussi simple qu'il y paraît. Voici le processus:

  1. Déterminez le nombre de validations de Push à la fois. Je recommanderais normalement une recherche binaire pour déterminer combien vous pouvez pousser, mais cela peut être difficile en raison du temps d'attente entre les poussées. De plus, de nombreux repos ont un premier commit très volumineux, ou certains commits après sont très volumineux. Si vous connaissez de tels commits, essayez de les pousser par eux-mêmes. Si votre dépôt est suffisamment petit, il peut être plus simple de simplement pousser un commit à la fois. Sinon, essayez de pousser les validations 20-30, en diminuant le nombre si vous rencontrez des problèmes.

  2. En supposant que vous avez une branche, master, créez une nouvelle branche au même endroit, par exemple master-temp.

  3. Réinitialisez master sur le dernier commit du premier groupe que vous souhaitez pousser. Par exemple. git reset --hard master-temp~100.

  4. Poussez ce commit (git Push).

  5. Fait une --ff fusionner au dernier commit du groupe suivant. (git merge --ff-only master-temp~90)

  6. Répétez les étapes 4 et 5 jusqu'à ce que toutes les validations soient poussées.

À titre d'exemple, considérons ce dépôt:

$ git log --oneline --decorate
* fffffff (HEAD -> master) Commit six
* eeeeeee Commit five
* ddddddd Commit four
* ccccccc Commit three
* bbbbbbb Commit two
* aaaaaaa Commit one

Voici ce que vous ferez, en supposant que vous souhaitiez pousser un commit à la fois:

$ git checkout -b master-temp master
$ git checkout master
$ git reset --hard aaaaaaa
$ git Push Origin master
$ git merge --ff-only bbbbbbb
$ git Push Origin master
$ git merge --ff-only ccccccc
$ git Push Origin master
$ git merge --ff-only ddddddd
$ git Push Origin master
$ git merge --ff-only eeeeeee
$ git Push Origin master
$ git merge --ff-only fffffff
$ git Push Origin master

Idéalement, cela fonctionne bien et vous avez terminé. Mais que se passe-t-il si un commit donné ne peut pas être poussé, même si c'est le seul commit que vous poussiez? Tout d'abord, essayez de pousser une ou deux fois de plus; il semble y avoir une certaine incohérence dans le temps qu'il faut pour échouer le Push.

S'il ne pousse toujours pas, il est temps de réécrire l'histoire.

Mais je ne veux pas réécrire mon histoire! Mon journal Git est agréable et propre, car j'ai passé beaucoup de temps à apprendre à écrire de bons messages de commit , et j'ai toujours garder mes commits atomiques .

Ne vous inquiétez pas, vous aurez toujours votre historique d'origine lorsque vous aurez terminé.

Retour à l'exemple de référentiel (mis à jour):

* fffffff (HEAD -> master) Tiny commit five
* eeeeeee Tiny commit four
* ddddddd Tiny commit three
* ccccccc Tiny commit two
* bbbbbbb Tiny commit one
* aaaaaaa This commit is massive

(Le commit massif peut être n'importe où, ou il peut y en avoir plusieurs.)

L'idée générale est que vous effectuez un rebase interactif (git rebase -i) à diviser le commit massif en quelques plus petits .

$ git checkout -b master-temp master
$ git rebase -i --root

Noter la --root n'est nécessaire que si vous devez fractionner le tout premier commit. Sinon, par exemple git rebase -i bbbbbbb.

Modifiez le commit que vous souhaitez séparer de pick en edit.

$ git reset HEAD^
$ git add somefiles
$ git commit
$ git Push Origin master-temp
$ git add someotherfiles
$ git commit
$ git Push Origin master-temp
$ git rebase --continue
$ git Push Origin master-temp

Maintenant, c'est là que le magit la magie opère:

$ git checkout master
switched to branch 'master'
$ git Push Origin master
POST git-receive-packed (chunked)
remote: Analyzing objects... (1212/1212) (2518523 ms)
remote: Storing packfile... done (48186 ms)
remote: Storing index... done (228 ms)
Pushing to https://example.visualstudio.com/SomeCollection/SomeTeam/_git/MyRepo
To https://example.visualstudio.com/SomeCollection/SomeTeam/_git/MyRepo
 * [new branch]    master -> master
updating local tracking ref 'refs/remotes/Origin/master'

La dernière commande réussira, car Git est assez intelligent pour réutiliser les éléments que vous avez déjà poussés, même s'ils sont dans un commit différent. (Notez que le Analyzing objects l'étape est celle qui prend le plus de temps. C'est Git qui calcule combien il peut réutiliser et combien il doit télécharger.) Si vous souhaitez en savoir plus sur son fonctionnement, consultez la section Packfiles des documents Git Internals , peut-être après avoir brossé Git Objects .

Ai-je mentionné que Git est génial?

2
Scott Weldon