Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does git run auto-packing on every push to our repo?

Tags:

git

The last few days, each and every push to our git repository has caused auto-packing on the server.

The output on the client when this happens:

~pdr git:master ❯❯❯ git push origin master
Counting objects: 44, done.
Delta compression using up to 8 threads.
Compressing objects: 100% (26/26), done.
Writing objects: 100% (27/27), 4.67 KiB, done.
Total 27 (delta 14), reused 0 (delta 0)
Auto packing the repository for optimum performance.

The packing happens on the server, and ps shows these git commands at work:

git      23252  0.0  0.0  68520   552 ?        S    15:21   0:00 sshd: git@notty  
git      23253  0.0  0.0   9660   540 ?        Ss   15:21   0:00 git shell -c git-receive-pack 'repositories/pdr.git'
git      23254  0.0  0.0  16644  2136 ?        S    15:21   0:00 git receive-pack repositories/pdr.git
git      23258  0.0  0.0   9660   624 ?        S    15:21   0:00 git gc --auto --quiet
git      23261  0.0  0.0   9660   504 ?        S    15:21   0:00 git repack -d -l -q -A
git      23262  0.0  0.0   4104   376 ?        S    15:21   0:00 /bin/sh /usr/lib/git-core/git-repack -d -l -q -A
git      23275  267 92.2 9569724 3742468 ?     Sl   15:21  23:07 git pack-objects --keep-true-parents --honor-pack-keep --non-empty --all --reflog --unpack-unreachable --local -q --delta-base-offset /home/git/repositories/pdr.git/objects/.tmp-23262-pack

I have run a manual "git gc" followed by a "git fsck" on the server. No error messages, but on the next push it started auto-packing again.

This is on a server running Ubuntu Server 10.04 LTS with Git 1.7.0.4.

like image 984
anr78 Avatar asked Jul 29 '13 13:07

anr78


People also ask

Why does Git take so long to repack objects?

It's more efficient to store objects in packs, but it takes time to pack (compress) objects, so Git initially creates loose objects, then packs them in batches now and then, via automatic invocation of git gc --auto. If you let Git finish repacking, this won't happen again for a while.

How do I push changes to a production Git repository?

You can use the same server you’ve set up as your development machine. On your production machine, you will be setting up another web server, a bare git repository that you will push changes to, and a git hook that will execute whenever a push is received. Complete the steps below as a normal user with sudo privileges.

What is a a pack in Git?

A pack is a delta-compressed single file, containing a large number of objects. It's more efficient to store objects in packs, but it takes time to pack (compress) objects, so Git initially creates loose objects, then packs them in batches now and then, via automatic invocation of git gc --auto.

Why is my Git push being denied?

You might’ve noticed that it’s actually a loop – that’s because a git push may contain more than one commit, and as such we’d like to run the tests for all the commits to be sure which one broke things (if any). Returning a non-zero exit code from the shell script will cause the push to be denied.


1 Answers

Git decides whether to auto gc based on two criteria:

  1. Are there too many packs? (Literally, are there more than 50 files with .idx in .git/objects/pack?)
  2. Are there too many loose objects? (Literally, are there more than 27 files in .git/objects/17?)

If for some reason Git is not able to merge the pack files or remove the loose objects in that directory, it will think it needs to auto-gc again next time.

I would check the contents of the two directories cited above to see if the (default) criteria are met and see if the criteria change after the re-packing.

Some reasons for failure to complete the process might be:

  • some sort of permissions problem
  • unreachable objects that are ignored by Git's garbage collection or not pruned by default due to their youth
  • insufficient disk space to complete the gc (the repack)
  • insufficient memory to complete the gc (the repack)
  • objects too large to fit in a specified pack size (see git config pack.packSizeLimit which defaults to unlimited but may be overridden by the user)

You should also ensure of course that the gc related tunable parameters haven't been set unreasonably by looking at:

git config -l | grep gc

For some other details, see the Git SCM book on Git Internals.

like image 64
Emil Sit Avatar answered Oct 16 '22 20:10

Emil Sit