Git: how to repack all loose commits
Asked Answered
C

2

7

After using git gc and git repack (with various options) I still have 4825 loose commits in the folder .git/objects. I would like to have all of them in the pack file with the rest or in another pack file.

I'm doing lots commit rewriting (amend + rebase) hence it's perfectly normal to have many unreachable commits. My .gitconfig contains these parameters to keep reflogs and unreachable commits for a long time.

[gc]
    reflogExpire = 300 days
    reflogExpireUnreachable = 200 days
    pruneExpire = 90 days

You may wonder if it make sense but I already needed and have recovered a few commits made several months ago. It happens we develop for many months on a new set of higher priority branches and afterwards continue on the older lower priority branches.

The main reason for this question is that git gui keeps on complaining to compress my database despites I have done this many times. If we are not able to pack those loose commits then this "complaining" might be a bug in git gui.

Carolann answered 28/11, 2011 at 10:1 Comment(2)
wow, I had no idea people can actually work with that many loose commitsStunk
dupe / related? stackoverflow.com/questions/3765234/…Parton
A
1

Considering that git bundle is used to work with packaging objects only (calling fetch-pack), did you try to bundle, and then clone your repo?

git bundle create aBundle --all # hopefully package everything, 
                                # the result being *one* file.
git clone aBundle newRepo       # recreate a full repo
# check if the cloned repo contains only packaged object

If this works, you might go on, using the new cloned repo as your main repo.

Arielle answered 28/11, 2011 at 11:30 Comment(2)
I'm afraid this doesn't help. I created such a bundle and it is 60 MB. However my file pack in .git/objects/pack is 64 MB and all the loose objects objects together take 32 MB. I tried to reference a dangling commit (of my repository) in the bundle but it didn't work (anybody knows how?).Carolann
@PaulPladijs: but does a clone of that bundle contains any unpacked object? I agree that a git bundle is likely to consider only referenced commit, though.Arielle
D
1

The warning from git-gui is just a hint that you might want to do some maintenance. For most people having a high number of objects is just slowing them down. In your case, you should disable the warning. The function in question is hint_gc and it is called from near the end of the git-gui script file. Just comment it out as below.

if {[is_enabled multicommit]} {
        #after 1000 hint_gc
}

The multicommit business is a flag that determines if we are running as committool or a general purpose app.

If you want to use git-gui normally elsewhere, then you could add a respository specific flag instead. Something like:

if {[is_enabled multicommit] && ![is_config_true gui.skip_gc_warning]} {
        after 1000 hint_gc
}

should let you use git config --bool gui.skip_gc_warning true to disable that on a per-repository basis.

Diversified answered 28/11, 2011 at 16:13 Comment(1)
This is a good idea! I tried it but you have to remove the underscores _ in skip_gc_warning to make it work. I'm still waiting for a repack solution (I'm curious if it's possible). Otherwise this may become the best answer.Carolann

© 2022 - 2024 — McMap. All rights reserved.