Git cheat sheet

Git commands that are not intuitively found:

  • Removing a subtree from a repository including all of its history (e.g. when non-open-source files were committed to a repository before pushing the repo to an external server or to remove old directories after splitting a repo): git filter-branch --index-filter "git rm -r -f --cached --ignore-unmatch <DIRECTORY TO REMOVE>" --prune-empty HEAD
  • Removing everything besides a specific directory (from http://stackoverflow.com/questions/359424/detach-subdirectory-into-separate-git-repository):
    git clone --no-hardlinks XYZ ABC
    cd ABC
    git filter-branch --subdirectory-filter ABC -- --all
    git reset --hard
    # and now really, really clean up all objects not referenced anymore...
    git remote rm origin
    git update-ref -d refs/original/refs/heads/master
    git reflog expire --expire=now --all
    git repack -ad
    git clean -d -f
    git gc --aggressive
    git prune
    # instead of the above, the following might reclaim more space, a lot quicker:
    cd ..; mkdir ABC-min.git; cd ABC-min.git
    git init --bare
    cd ../ABC
    git push ../ABC-min.git HEAD

  • Removing everything besides a list of files and directories and tracking their history even through renames and copies, which the above method doesn't track (from http://stackoverflow.com/questions/5998987/splitting-a-set-of-files-with...):
    git clone --no-hardlinks XYZ ABC
    cd ABC
    -d"\\n" git rm --cached -r' -- --all
    git filter-branch --prune-empty --index-filter 'git ls-tree -r --name-only --full-tree $GIT_COMMIT \
    | grep -iv "filename1" | grep -iv "filename2" | grep -iv "directory-regex1" | grep -iv "directory-regex2" | ... \
    | grep -v "^git-changelog" | xargs -r -d"\\n" git rm --cached -r' -- --all
    # same as above with git push/pull to reclaim space