Ssh – GIT pull times out

gitssh

I've recently set up a small turnkeylinux revision control VM (which has about 256MB RAM), and am attempting to clone one of the repositories I pushed up to it. It is very fast to push to (via ssh) but is extremely slow to pull from.

Here's what I get if I leave it till SSH times out:

$ git pull
andrewm@1.2.3.4's password:
remote: Counting objects: 403, done.
Read from remote host 1.2.3.4: The connection was aborted
fatal: The remote end hung up unexpectedly
fatal: early EOF

I attempted the clone like so:

> mkdir myProj
> cd myProj
> git init
> git remote add origin git+ssh://andrewm@1.2.3.4/srv/repos/git/myProj
> git pull

When I issue the pull command it reaches 50% almost instantly, and then halts. It slowly creeps forward a few more percent (one attempt reached 66%) and then eventually dies if left long enough.

This repo is tiny with only a handful of revisions so far. My main repo is much bigger and will also be unusable unless this issue is identified.

Any ideas what could be causing the sudden slowdown?

Update

I just confirmed that the VM is slow when connected using git:// protocol as well. It can't therefore be a problem with ssh. Updating the question title accordingly.

Best Answer

Are you able to clone locally on the VM using a file: protocol repository URL?

git clone file:///srv/repos/git/myProj /tmp/myProj-clone

The file: protocol forces local operations to use a protocol that is very close to the normal smart protocol used by git:/ssh:/smart-http: remote URLs. Specifically, it uses a pack-based protocol instead of taking advantage of the normal optimization for local operations (hardlinking/copying of repository objects).

You may not have enough memory for the server to generate the pack required for your pull operation. Doing a trial, local, file:-based clone/pull will exercise the pack generation capabilities of your VM without dragging in any kind of networking components to confuse the issue.

There are several configuration variables that control the generation of packs:

  • pack.window
  • pack.depth
  • pack.windowMemory
  • pack.deltaCacheSize
  • pack.deltaCacheLimit

You might be able to tune your repository to generate its packs in a less memory intensive fashion (the packing efficiency will likely suffer as a result though).

My guess is that 256MB (for OS and applications?) is just too small to expect (potentially) memory hungry applications (like Git's pack operations) to work quickly or even correctly.