Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Git: how to repack all loose commits

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.

like image 510
Paul Pladijs Avatar asked Nov 28 '11 10:11

Paul Pladijs


People also ask

How to recover lost commits in Git?

commands to recover your lost commits in Git. Note: Using the reflog will only work for a certain amount of time after the commits are lost. Git cleans the reflog periodically, so don’t wait too long! The first step to recovering your lost commits is to recover the list of all your previous commits and actions done on the repository.

How do I revert changes to a specific commit in Git?

Just click “revert” on the commit. If you’re at the HEAD of your commit tree, and you’d like to do this without making new commits, and you haven’t pushed the change yet, you can hard reset your local branch to the old commit. The reason this needs to be a hard reset is because a soft reset would still include the unstaged changes from the revert.

Is it possible to break a git repository?

Your repository is already broken. Don't break it any further without first making sure nobody can access it except you, making a backup (tar, rsync) of the repository and first trying the commands in a copy of the repository. All the files in .git are gone!

How does gitgit repack work?

git repack ensures this by determining a "cut" of packfiles that need to be repacked into one in order to ensure a geometric progression. It picks the smallest set of packfiles such that as many of the larger packfiles (by count of objects contained in that pack) may be left intact.


2 Answers

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.

like image 152
VonC Avatar answered Sep 23 '22 21:09

VonC


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.

like image 44
patthoyts Avatar answered Sep 21 '22 21:09

patthoyts