X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;ds=sidebyside;f=Documentation%2Fgit-filter-branch.txt;h=895d7503100632f5ab79af548fed3b3a6d79c413;hb=37ec2b4c26901d5f1ca19948189dc2b6f21523d5;hp=eaea82d0a690154223d0553603a08cf1fa27c8ce;hpb=b9dcf846e20ed5287e239c9a0942c5d150081bab;p=git.git diff --git a/Documentation/git-filter-branch.txt b/Documentation/git-filter-branch.txt index eaea82d0a..895d75031 100644 --- a/Documentation/git-filter-branch.txt +++ b/Documentation/git-filter-branch.txt @@ -12,24 +12,24 @@ SYNOPSIS [--index-filter ] [--parent-filter ] [--msg-filter ] [--commit-filter ] [--tag-name-filter ] [--subdirectory-filter ] - [-d ] [...] + [--original ] [-d ] [-f | --force] + [...] DESCRIPTION ----------- -Lets you rewrite git revision history by creating a new branch from -your current branch, applying custom filters on each revision. +Lets you rewrite git revision history by rewriting the branches mentioned +in the , applying custom filters on each revision. Those filters can modify each tree (e.g. removing a file or running a perl rewrite on all files) or information about each commit. Otherwise, all information (including original commit times or merge information) will be preserved. -The command takes the new branch name as a mandatory argument and -the filters as optional arguments. If you specify no filters, the -commits will be recommitted without any changes, which would normally -have no effect and result in the new branch pointing to the same -branch as your current branch. Nevertheless, this may be useful in -the future for compensating for some git bugs or such, therefore -such a usage is permitted. +The command will only rewrite the _positive_ refs mentioned in the +command line (i.e. if you pass 'a..b', only 'b' will be rewritten). +If you specify no filters, the commits will be recommitted without any +changes, which would normally have no effect. Nevertheless, this may be +useful in the future for compensating for some git bugs or such, +therefore such a usage is permitted. *WARNING*! The rewritten history will have different object names for all the objects and will not converge with the original branch. You will not @@ -38,12 +38,13 @@ original branch. Please do not use this command if you do not know the full implications, and avoid using it anyway, if a simple single commit would suffice to fix your problem. -Always verify that the rewritten version is correct before disposing -the original branch. +Always verify that the rewritten version is correct: The original refs, +if different from the rewritten ones, will be stored in the namespace +'refs/original/'. Note that since this operation is extensively I/O expensive, it might -be a good idea to redirect the temporary directory off-disk, e.g. on -tmpfs. Reportedly the speedup is very noticeable. +be a good idea to redirect the temporary directory off-disk with the +'-d' option, e.g. on tmpfs. Reportedly the speedup is very noticeable. Filters @@ -111,6 +112,11 @@ OPTIONS As a special extension, the commit filter may emit multiple commit ids; in that case, ancestors of the original commit will have all of them as parents. ++ +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 gitlink:git-rebase[1] instead). --tag-name-filter :: This is the filter for rewriting tag names. When passed, @@ -120,7 +126,7 @@ have all of them as parents. tag name is expected on standard output. + The original tags are not deleted, but can be overwritten; -use "--tag-name-filter=cat" to simply update the tags. In this +use "--tag-name-filter cat" to simply update the tags. In this case, be very careful and make sure you have the old tags backed up in case the conversion has run afoul. + @@ -134,6 +140,10 @@ definition impossible to preserve signatures at any rate.) The result will contain that directory (and only that) as its project root. +--original :: + Use this option to set the namespace where the original commits + will be stored. The default value is 'refs/original'. + -d :: Use this option to set the path to the temporary directory used for rewriting. When applying a tree filter, the command needs to @@ -142,6 +152,11 @@ definition impossible to preserve signatures at any rate.) does this in the '.git-rewrite/' directory but you can override that choice by this parameter. +-f|--force:: + `git filter-branch` refuses to start with an existing temporary + directory or when there are already refs starting with + 'refs/original/', unless forced. + :: When options are given after the new branch name, they will be passed to gitlink:git-rev-list[1]. Only commits in the resulting @@ -156,41 +171,40 @@ Suppose you want to remove a file (containing confidential information or copyright violation) from all commits: ------------------------------------------------------- -git filter-branch --tree-filter 'rm filename' newbranch +git filter-branch --tree-filter 'rm filename' HEAD ------------------------------------------------------- A significantly faster version: -------------------------------------------------------------------------------- -git filter-branch --index-filter 'git update-index --remove filename' newbranch -------------------------------------------------------------------------------- +-------------------------------------------------------------------------- +git filter-branch --index-filter 'git update-index --remove filename' HEAD +-------------------------------------------------------------------------- -Now, you will get the rewritten history saved in the branch 'newbranch' -(your current branch is left untouched). +Now, you will get the rewritten history saved in HEAD. To set a commit (which typically is at the tip of another history) to be the parent of the current initial commit, in order to paste the other history behind the current history: ------------------------------------------------------------------------- -git filter-branch --parent-filter 'sed "s/^\$/-p /"' newbranch ------------------------------------------------------------------------- +------------------------------------------------------------------- +git filter-branch --parent-filter 'sed "s/^\$/-p /"' HEAD +------------------------------------------------------------------- -(if the parent string is empty - therefore we are dealing with the -initial commit - add graftcommit as a parent). Note that this assumes +(if the parent string is empty - which happens when we are dealing with +the initial commit - add graftcommit as a parent). Note that this assumes history with a single root (that is, no merge without common ancestors happened). If this is not the case, use: -------------------------------------------------------------------------------- +-------------------------------------------------------------------------- git filter-branch --parent-filter \ - 'cat; test $GIT_COMMIT = && echo "-p "' newbranch -------------------------------------------------------------------------------- + 'cat; test $GIT_COMMIT = && echo "-p "' HEAD +-------------------------------------------------------------------------- or even simpler: ----------------------------------------------- echo "$commit-id $graft-id" >> .git/info/grafts -git filter-branch newbranch $graft-id.. +git filter-branch $graft-id..HEAD ----------------------------------------------- To remove commits authored by "Darl McBribe" from the history: @@ -199,34 +213,45 @@ To remove commits authored by "Darl McBribe" from the history: git filter-branch --commit-filter ' if [ "$GIT_AUTHOR_NAME" = "Darl McBribe" ]; then - shift; - while [ -n "$1" ]; - do - shift; - echo "$1"; - shift; - done; + skip_commit "$@"; else git commit-tree "$@"; - fi' newbranch + fi' HEAD ------------------------------------------------------------------------------ +The function 'skip_commit' is defined as follows: + +-------------------------- +skip_commit() +{ + shift; + while [ -n "$1" ]; + do + shift; + map "$1"; + shift; + done; +} +-------------------------- + The shift magic first throws away the tree id and then the -p parameters. Note that this handles merges properly! In case Darl committed a merge between P1 and P2, it will be propagated properly and all children of the merge will become merge commits with P1,P2 as their parents instead of the merge commit. + To restrict rewriting to only part of the history, specify a revision range in addition to the new branch name. The new branch name will point to the top-most revision that a 'git rev-list' of this range will print. -Note that the changes introduced by the commits, and not reverted by -subsequent commits, will still be in the rewritten branch. If you want +*NOTE* the changes introduced by the commits, and which are not reverted +by subsequent commits, will still be in the rewritten branch. If you want to throw out _changes_ together with the commits, you should use the interactive mode of gitlink:git-rebase[1]. + Consider this history: ------------------ @@ -238,14 +263,14 @@ A--B-----C To rewrite only commits D,E,F,G,H, but leave A, B and C alone, use: -------------------------------- -git filter-branch ... new-H C..H +git filter-branch ... C..H -------------------------------- To rewrite commits E,F,G,H, use one of these: ---------------------------------------- -git filter-branch ... new-H C..H --not D -git filter-branch ... new-H D..H --not C +git filter-branch ... C..H --not D +git filter-branch ... D..H --not C ---------------------------------------- To move the whole tree into a subdirectory, or remove it from there: @@ -255,7 +280,7 @@ git filter-branch --index-filter \ 'git ls-files -s | sed "s-\t-&newsubdir/-" | GIT_INDEX_FILE=$GIT_INDEX_FILE.new \ git update-index --index-info && - mv $GIT_INDEX_FILE.new $GIT_INDEX_FILE' directorymoved + mv $GIT_INDEX_FILE.new $GIT_INDEX_FILE' HEAD ---------------------------------------------------------------