X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=Documentation%2Fgit-filter-branch.txt;h=ab527b5b316a81eddd8a0eefb501448a3097182f;hb=974e6e42f7a66b69bd684af4f637ab064acfdf92;hp=68f97cd5aee2dc3d4bc1c3e507cf373bee8c1922;hpb=bc69776aa12c68958e381e8c24e8faa172dde2d8;p=git.git diff --git a/Documentation/git-filter-branch.txt b/Documentation/git-filter-branch.txt index 68f97cd5a..ab527b5b3 100644 --- a/Documentation/git-filter-branch.txt +++ b/Documentation/git-filter-branch.txt @@ -94,7 +94,9 @@ OPTIONS --index-filter :: This is the filter for rewriting the index. It is similar to the tree filter but does not check out the tree, which makes it much - faster. For hairy cases, see linkgit:git-update-index[1]. + faster. Frequently used with `git rm \--cached + \--ignore-unmatch ...`, see EXAMPLES below. For hairy + cases, see linkgit:git-update-index[1]. --parent-filter :: This is the filter for rewriting the commit's parent list. @@ -125,6 +127,10 @@ You can use the 'map' convenience function in this filter, and other convenience functions, too. For example, calling 'skip_commit "$@"' will leave out the current commit (but not its changes! If you want that, use 'git-rebase' instead). ++ +You can also use the 'git_commit_non_empty_tree "$@"' instead of +'git commit-tree "$@"' if you don't wish to keep commits with a single parent +and that makes no change to the tree. --tag-name-filter :: This is the filter for rewriting tag names. When passed, @@ -154,6 +160,16 @@ to other tags will be rewritten to point to the underlying commit. The result will contain that directory (and only that) as its project root. +--prune-empty:: + Some kind of filters will generate empty commits, that left the tree + untouched. This switch allow git-filter-branch to ignore such + commits. Though, this switch only applies for commits that have one + and only one parent, it will hence keep merges points. Also, this + option is not compatible with the use of '--commit-filter'. Though you + just need to use the function 'git_commit_non_empty_tree "$@"' instead + of the 'git commit-tree "$@"' idiom in your commit filter to make that + happen. + --original :: Use this option to set the namespace where the original commits will be stored. The default value is 'refs/original'. @@ -193,10 +209,14 @@ However, if the file is absent from the tree of some commit, a simple `rm filename` will fail for that tree and commit. Thus you may instead want to use `rm -f filename` as the script. -A significantly faster version: +Using `\--index-filter` with 'git-rm' yields a significantly faster +version. Like with using `rm filename`, `git rm --cached filename` +will fail if the file is absent from the tree of a commit. If you +want to "completely forget" a file, it does not matter when it entered +history, so we also add `\--ignore-unmatch`: -------------------------------------------------------------------------- -git filter-branch --index-filter 'git rm --cached filename' HEAD +git filter-branch --index-filter 'git rm --cached --ignore-unmatch filename' HEAD -------------------------------------------------------------------------- Now, you will get the rewritten history saved in HEAD. @@ -323,6 +343,47 @@ git filter-branch --index-filter \ --------------------------------------------------------------- + +Checklist for Shrinking a Repository +------------------------------------ + +git-filter-branch is often used to get rid of a subset of files, +usually with some combination of `\--index-filter` and +`\--subdirectory-filter`. People expect the resulting repository to +be smaller than the original, but you need a few more steps to +actually make it smaller, because git tries hard not to lose your +objects until you tell it to. First make sure that: + +* You really removed all variants of a filename, if a blob was moved + over its lifetime. `git log \--name-only \--follow \--all \-- + filename` can help you find renames. + +* You really filtered all refs: use `\--tag-name-filter cat \-- + \--all` when calling git-filter-branch. + +Then there are two ways to get a smaller repository. A safer way is +to clone, that keeps your original intact. + +* Clone it with `git clone +++file:///path/to/repo+++`. The clone + will not have the removed objects. See linkgit:git-clone[1]. (Note + that cloning with a plain path just hardlinks everything!) + +If you really don't want to clone it, for whatever reasons, check the +following points instead (in this order). This is a very destructive +approach, so *make a backup* or go back to cloning it. You have been +warned. + +* Remove the original refs backed up by git-filter-branch: say `git + for-each-ref \--format="%(refname)" refs/original/ | xargs -n 1 git + update-ref -d`. + +* Expire all reflogs with `git reflog expire \--expire=now \--all`. + +* Garbage collect all unreferenced objects with `git gc \--prune=now` + (or if your git-gc is not new enough to support arguments to + `\--prune`, use `git repack -ad; git prune` instead). + + Author ------ Written by Petr "Pasky" Baudis ,