Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does git run "git gc --auto" on every merge?

Tags:

git

Today, git started acting funny (well, funnier than usual) by insisting on running git gc after every single merge, even if they are back to back.

C:\Projects\my-current-project>git pull
remote: Counting objects: 31, done.
remote: Compressing objects: 100% (16/16), done.
remote: Total 16 (delta 11), reused 0 (delta 0)
Unpacking objects: 100% (16/16), done.
From git.company.com:git/
   e992ce8..6376211  mybranch/next -> origin/mybranch/next
Merge made by recursive.
Auto packing the repository for optimum performance. You may also run "git gc" manually. See "git help gc" for more information.
FIND: Parameter format not correct
Counting objects: 252732, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (59791/59791), done.
Writing objects: 100% (252732/252732), done.
Total 252732 (delta 190251), reused 252678 (delta 190222)
Removing duplicate objects: 100% (256/256), done.
 .../stylesheets/style.css                          |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

This is incredibly disruptive, and I fear that it means that my repository is corrupt somehow (this is the first time I've ever seen it automatically gc). Are my fears unfounded? If my repository is OK, how do I make the auto-packing stop?!

like image 375
Mike Caron Avatar asked Sep 12 '11 18:09

Mike Caron


2 Answers

EDIT

I think I spotted the problem.

You are probably running Cygwin/git or MsysGit on Windows. I noticed that because of the

FIND: Parameter format not correct

error message. The trouble is that somewhere your hook scripts (or git internally?!) is calling find, which does not find the UNIX (GNU) find utility but rather finds the Windows (MSDOS... sic) FIND.EXE.

You should be able to fix your system wide path. If that is not an option, explicitely specify the PATH environment variable inside your script (or before invoking them)


Old answer for information:

git gc --auto does not always result in any action taken; are you sure this is taking time every time, or did you just notice it is being called?

If it is being called every time, you might

  • check repository permissions (make sure it is fully writable to you!)
  • git fsck
  • git repack
  • git bundle --create mybundle.git --all and git clone mybundle.git to see whether somehow you can 'shake' the culprit
  • see whether you can upgrade to a later version
  • if all else fails, strace or debug the git-gc binary

Optionally, when you have shaken the culprit, you maybe able to analyze what is different between your 'cleaned' repo and the current one.

From the git-gc man-page:

With this option [--auto], git gc checks whether any housekeeping is required; if not, it exits without performing any work. Some git commands run git gc --auto after performing operations that could create many loose objects.

Housekeeping is required if there are too many loose objects or too many packs in the repository. If the number of loose objects exceeds the value of the gc.auto configuration variable, then all loose objects are combined into a single pack using git repack -d -l. Setting the value of gc.auto to 0 disables automatic packing of loose objects.

If the number of packs exceeds the value of gc.autopacklimit, then existing packs (except those marked with a .keep file) are consolidated into a single pack by using the -A option of git repack. Setting gc.autopacklimit to 0 disables automatic consolidation of packs.

like image 170
sehe Avatar answered Sep 22 '22 14:09

sehe


I'm adding this answer even though it doesn't answer the original poster's specific problem because every time one of my repos starts auto-packing after every merge I've forgotten the fix, search for it again and find this question first.

When one of my repos starts "Auto packing the repository for optimum performance" after every merge,

git gc --prune=now

fixes it. (Being on a Mac, I don't have the FIND: Parameter format not correct problem.) Right now I'm using git 2.4.1, but this has worked for me for several 2.* versions.

This answer to How to remove unreferenced blobs from my git repo suggests that one might need to clear one's reflog with

git reflog expire --expire-unreachable=now --all

for the above command to be maximally effective, but I've never needed to do that to fix auto-packing after every merge.

like image 20
Dave Schweisguth Avatar answered Sep 25 '22 14:09

Dave Schweisguth