* [PATCH] Document git-filter-branch
@ 2007-07-03 16:47 Johannes Schindelin
2007-07-03 22:05 ` Frank Lichtenheld
0 siblings, 1 reply; 12+ messages in thread
From: Johannes Schindelin @ 2007-07-03 16:47 UTC (permalink / raw)
To: git, gitster
This moves the documentation in git-filter-branch.sh to its own
man page, with a few touch ups.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
Sorry, for being so late. I just realised this is not yet in
git.git, and it would be better IMHO to have it in 1.5.3...
Documentation/cmd-list.perl | 1 +
Documentation/git-filter-branch.txt | 261 +++++++++++++++++++++++++++++++++++
git-filter-branch.sh | 187 +------------------------
3 files changed, 265 insertions(+), 184 deletions(-)
create mode 100644 Documentation/git-filter-branch.txt
diff --git a/Documentation/cmd-list.perl b/Documentation/cmd-list.perl
index f50f613..2143995 100755
--- a/Documentation/cmd-list.perl
+++ b/Documentation/cmd-list.perl
@@ -105,6 +105,7 @@ git-diff-tree plumbinginterrogators
git-fast-import ancillarymanipulators
git-fetch mainporcelain
git-fetch-pack synchingrepositories
+git-filter-branch ancillarymanipulators
git-fmt-merge-msg purehelpers
git-for-each-ref plumbinginterrogators
git-format-patch mainporcelain
diff --git a/Documentation/git-filter-branch.txt b/Documentation/git-filter-branch.txt
new file mode 100644
index 0000000..ee60a1a
--- /dev/null
+++ b/Documentation/git-filter-branch.txt
@@ -0,0 +1,261 @@
+git-filter-branch(1)
+====================
+
+NAME
+----
+git-filter-branch - Rewrite branches
+
+SYNOPSIS
+--------
+[verse]
+'git-filter-branch' [--env-filter <command>] [--tree-filter <command>]
+ [--index-filter <command>] [--parent-filter <command>]
+ [--msg-filter <command>] [--commit-filter <command>]
+ [--tag-name-filter <command>] [--subdirectory-filter <directory>]
+ [-d <directory>] <new-branch-name> [<rev-list options>...]
+
+DESCRIPTION
+-----------
+Lets you rewrite git revision history by creating a new branch from
+your current branch, 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.
+
+WARNING! The rewritten history will have different object names for all
+the objects and will not converge with the original branch. You will not
+be able to easily push and distribute the rewritten branch on top of the
+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.
+
+Note that since this operation is extensively I/O expensive, it might
+be a good idea to redirect the temporary directory it off-disk, e.g. on
+tmpfs. Reportedly the speedup is very noticeable.
+
+
+Filters
+~~~~~~~
+
+The filters are applied in the order as listed below. The <command>
+argument is always evaluated in shell using the 'eval' command.
+The $GIT_COMMIT environment variable is permanently set to contain
+the id of the commit being rewritten. The author/committer environment
+variables are set before the first filter is run.
+
+A 'map' function is available that takes an "original sha1 id" argument
+and outputs a "rewritten sha1 id" if the commit has been already
+rewritten, fails otherwise; the 'map' function can return several
+ids on separate lines if your commit filter emitted multiple commits.
+
+
+OPTIONS
+-------
+
+--env-filter <command>::
+ This is the filter for modifying the environment in which
+ the commit will be performed. Specifically, you might want
+ to rewrite the author/committer name/email/time environment
+ variables (see gitlink:git-commit[1] for details). Do not forget
+ to re-export the variables.
+
+--tree-filter <command>::
+ This is the filter for rewriting the tree and its contents.
+ The argument is evaluated in shell with the working
+ directory set to the root of the checked out tree. The new tree
+ is then used as-is (new files are auto-added, disappeared files
+ are auto-removed - .gitignore files nor any other ignore rules
+ HAVE NO EFFECT!).
+
+--index-filter <command>::
+ 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 gitlink:git-update-index[1].
+
+--parent-filter <command>::
+ This is the filter for rewriting the commit's parent list.
+ It will receive the parent string on stdin and shall output
+ the new parent string on stdout. The parent string is in
+ a format accepted by gitlink:git-commit-tree[1]: empty for
+ the initial commit, "-p parent" for a normal commit and
+ "-p parent1 -p parent2 -p parent3 ..." for a merge commit.
+
+--msg-filter <command>::
+ This is the filter for rewriting the commit messages.
+ The argument is evaluated in the shell with the original
+ commit message on standard input; its standard output is
+ used as the new commit message.
+
+--commit-filter <command>::
+ This is the filter for performing the commit.
+ If this filter is specified, it will be called instead of the
+ gitlink:git-commit-tree[1] command, with arguments of the form
+ "<TREE_ID> [-p <PARENT_COMMIT_ID>]..." and the log message on
+ stdin. The commit id is expected on stdout.
++
+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.
+
+--tag-name-filter <command>::
+ This is the filter for rewriting tag names. When passed,
+ it will be called for every tag ref that points to a rewritten
+ object (or to a tag object which points to a rewritten object).
+ The original tag name is passed via standard input, and the new
+ 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
+case, be very careful and make sure you have the old tags
+backed up in case the conversion has run afoul.
++
+Note that there is currently no support for proper rewriting of
+tag objects; in layman terms, if the tag has a message or signature
+attached, the rewritten tag won't have it. Sorry. (It is by
+definition impossible to preserve signatures at any rate.)
+
+--subdirectory-filter <directory>::
+ Only regard the history, as seen by the given subdirectory. The
+ result will contain that directory as its project root.
+
+-d <directory>::
+ Use this option to set the path to the temporary directory used for
+ rewriting. When applying a tree filter, the command needs to
+ temporary checkout the tree to some directory, which may consume
+ considerable space in case of large projects. By default it
+ does this in the '.git-rewrite/' directory but you can override
+ that choice by this parameter.
+
+<rev-list-options>::
+ When options are given after the new branch name, they will
+ be passed to gitlink:git-rev-list[1]. Only commits in the resulting
+ output will be filtered, although the filtered commits can still
+ reference parents which are outside of that set.
+
+
+Examples
+--------
+
+Suppose you want to remove a file (containing confidential information
+or copyright violation) from all commits:
+
+-------------------------------------------------------
+git filter-branch --tree-filter 'rm filename' newbranch
+-------------------------------------------------------
+
+A significantly faster version:
+
+-------------------------------------------------------------------------------
+git filter-branch --index-filter 'git update-index --remove filename' newbranch
+-------------------------------------------------------------------------------
+
+Now, you will get the rewritten history saved in the branch 'newbranch'
+(your current branch is left untouched).
+
+To "etch-graft" a commit to the revision history (set a commit to be
+the parent of the current initial commit and propagate that):
+
+----------------------------------------------------------------------
+git filter-branch --parent-filter sed\ 's/^$/-p <graft-id>/' newbranch
+----------------------------------------------------------------------
+
+(if the parent string is empty - therefore 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 = <commit-id> && echo "-p <graft-id>"' newbranch
+-------------------------------------------------------------------------------
+
+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;
+ else
+ git commit-tree "$@";
+ fi' newbranch
+------------------------------------------------------------------------------
+
+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
+to throw out _changes_ together with the commits, you should use the
+interactive mode of gitlink:git-rebase[1].
+
+Consider this history:
+
+------------------
+ D--E--F--G--H
+ / /
+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
+--------------------------------
+
+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
+----------------------------------------
+
+To move the whole tree into a subdirectory, or remove it from there:
+
+---------------------------------------------------------------
+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
+---------------------------------------------------------------
+
+
+Author
+------
+Written by Petr "Pasky" Baudis <pasky@suse.cz>,
+and the git list <git@vger.kernel.org>
+
+Documentation
+--------------
+Documentation by Petr Baudis and the git list.
+
+GIT
+---
+Part of the gitlink:git[7] suite
diff --git a/git-filter-branch.sh b/git-filter-branch.sh
index 3772951..22fb5bf 100644
--- a/git-filter-branch.sh
+++ b/git-filter-branch.sh
@@ -4,190 +4,9 @@
# Copyright (c) Petr Baudis, 2006
# Minimal changes to "port" it to core-git (c) Johannes Schindelin, 2007
#
-# Lets you rewrite GIT revision history by creating a new branch from
-# your current branch by 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 with 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.)
-#
-# WARNING! The rewritten history will have different ids for all the
-# objects and will not converge with the original branch. You will not
-# be able to easily push and distribute the rewritten branch. Please do
-# not use this command if you do not know the full implications, and
-# avoid using it anyway - do not do what a simple single commit on top
-# of the current version would fix.
-#
-# Always verify that the rewritten version is correct before disposing
-# the original branch.
-#
-# Note that since this operation is extensively I/O expensive, it might
-# be a good idea to do it off-disk, e.g. on tmpfs. Reportedly the speedup
-# is very noticeable.
-#
-# OPTIONS
-# -------
-# -d TEMPDIR:: The path to the temporary tree used for rewriting
-# When applying a tree filter, the command needs to temporary
-# checkout the tree to some directory, which may consume
-# considerable space in case of large projects. By default it
-# does this in the '.git-rewrite/' directory but you can override
-# that choice by this parameter.
-#
-# Filters
-# ~~~~~~~
-# The filters are applied in the order as listed below. The COMMAND
-# argument is always evaluated in shell using the 'eval' command.
-# The $GIT_COMMIT environment variable is permanently set to contain
-# the id of the commit being rewritten. The author/committer environment
-# variables are set before the first filter is run.
-#
-# A 'map' function is available that takes an "original sha1 id" argument
-# and outputs a "rewritten sha1 id" if the commit has been already
-# rewritten, fails otherwise; the 'map' function can return several
-# ids on separate lines if your commit filter emitted multiple commits
-# (see below).
-#
-# --env-filter COMMAND:: The filter for modifying environment
-# This is the filter for modifying the environment in which
-# the commit will be performed. Specifically, you might want
-# to rewrite the author/committer name/email/time environment
-# variables (see `git-commit` for details). Do not forget to
-# re-export the variables.
-#
-# --tree-filter COMMAND:: The filter for rewriting tree (and its contents)
-# This is the filter for rewriting the tree and its contents.
-# The COMMAND argument is evaluated in shell with the working
-# directory set to the root of the checked out tree. The new tree
-# is then used as-is (new files are auto-added, disappeared files
-# are auto-removed - .gitignore files nor any other ignore rules
-# HAVE NO EFFECT!).
-#
-# --index-filter COMMAND:: The filter for rewriting index
-# This is the filter for rewriting the Git's directory index.
-# It is similar to the tree filter but does not check out the
-# tree, which makes it much faster. However, you must use the
-# lowlevel Git index manipulation commands to do your work.
-#
-# --parent-filter COMMAND:: The filter for rewriting parents
-# This is the filter for rewriting the commit's parent list.
-# It will receive the parent string on stdin and shall output
-# the new parent string on stdout. The parent string is in
-# format accepted by `git commit-tree`: empty for initial
-# commit, "-p parent" for a normal commit and "-p parent1
-# -p parent2 -p parent3 ..." for a merge commit.
-#
-# --msg-filter COMMAND:: The filter for rewriting commit message
-# This is the filter for rewriting the commit messages.
-# The COMMAND argument is evaluated in shell with the original
-# commit message on standard input; its standard output is
-# is used as the new commit message.
-#
-# --commit-filter COMMAND:: The filter for performing the commit
-# If this filter is passed, it will be called instead of the
-# `git commit-tree` command, with those arguments:
-#
-# TREE_ID [-p PARENT_COMMIT_ID]...
-#
-# and the log message on stdin. The commit id is expected on
-# stdout. As a special extension, the commit filter may emit
-# multiple commit ids; in that case, all of them will be used
-# as parents instead of the original commit in further commits.
-#
-# --tag-name-filter COMMAND:: The filter for rewriting tag names.
-# If this filter is passed, it will be called for every tag ref
-# that points to a rewritten object (or to a tag object which
-# points to a rewritten object). The original tag name is passed
-# via standard input, and the new 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
-# case, be very careful and make sure you have the old tags
-# backed up in case the conversion has run afoul.
-#
-# Note that there is currently no support for proper rewriting of
-# tag objects; in layman terms, if the tag has a message or signature
-# attached, the rewritten tag won't have it. Sorry. (It is by
-# definition impossible to preserve signatures at any rate, though.)
-#
-# --subdirectory-filter DIRECTORY:: Only regard the history, as seen by
-# the given subdirectory. The result will contain that directory as
-# its project root.
-#
-# EXAMPLE USAGE
-# -------------
-# Suppose you want to remove a file (containing confidential information
-# or copyright violation) from all commits:
-#
-# git-filter-branch --tree-filter 'rm filename' newbranch
-#
-# A significantly faster version:
-#
-# git-filter-branch --index-filter 'git update-index --remove filename' newbranch
-#
-# Now, you will get the rewritten history saved in the branch 'newbranch'
-# (your current branch is left untouched).
-#
-# To "etch-graft" a commit to the revision history (set a commit to be
-# the parent of the current initial commit and propagate that):
-#
-# git-filter-branch --parent-filter sed\ 's/^$/-p graftcommitid/' newbranch
-#
-# (if the parent string is empty - therefore we are dealing with the
-# initial commit - add graftcommit as a parent). Note that this assumes
-# history with a single root (that is, no git-merge without common ancestors
-# happened). If this is not the case, use:
-#
-# git-filter-branch --parent-filter 'cat; [ "$GIT_COMMIT" = "COMMIT" ] && echo "-p GRAFTCOMMIT"' newbranch
-#
-# 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; else git commit-tree "$@"; fi' newbranch
-#
-# (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.
-#
-# Consider this history:
-#
-# D--E--F--G--H
-# / /
-# A--B-----C
-#
-# To rewrite commits D,E,F,G,H, use:
-#
-# git-filter-branch ... new-H 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
-#
-# To move the whole tree into a subdirectory, or remove it from there:
-#
-# 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
-
-# Testsuite: TODO
+# Lets you rewrite the revision history of the current branch, creating
+# a new branch. You can specify a number of filters to modify the commits,
+# files and trees.
set -e
--
1.5.3.rc0.2637.g1dd84-dirty
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH] Document git-filter-branch
2007-07-03 16:47 [PATCH] Document git-filter-branch Johannes Schindelin
@ 2007-07-03 22:05 ` Frank Lichtenheld
2007-07-03 23:17 ` Johannes Schindelin
` (2 more replies)
0 siblings, 3 replies; 12+ messages in thread
From: Frank Lichtenheld @ 2007-07-03 22:05 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: git, gitster
General note: All the stuff in all uppercase should probably also
have some asciidoc emphasis.
On Tue, Jul 03, 2007 at 05:47:44PM +0100, Johannes Schindelin wrote:
> +DESCRIPTION
> +-----------
> +Lets you rewrite git revision history by creating a new branch from
> +your current branch, 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.
> +
> +WARNING! The rewritten history will have different object names for all
> +the objects and will not converge with the original branch. You will not
> +be able to easily push and distribute the rewritten branch on top of the
> +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.
> +
> +Note that since this operation is extensively I/O expensive, it might
> +be a good idea to redirect the temporary directory it off-disk, e.g. on
^^^^^^
The "it" probably doesn't belong there.
> +tmpfs. Reportedly the speedup is very noticeable.
> +
> +
> +Filters
> +~~~~~~~
> +
> +The filters are applied in the order as listed below. The <command>
> +argument is always evaluated in shell using the 'eval' command.
> +The $GIT_COMMIT environment variable is permanently set to contain
^^^^^^^^^^^
I find the use of this word in this context odd and a little confusing.
Maybe better "always" or "each time"?
> +the id of the commit being rewritten. The author/committer environment
> +variables are set before the first filter is run.
Maybe give the actual names of the environment variables here?
> +A 'map' function is available that takes an "original sha1 id" argument
> +and outputs a "rewritten sha1 id" if the commit has been already
> +rewritten, fails otherwise; the 'map' function can return several
> +ids on separate lines if your commit filter emitted multiple commits.
> +
> +
> +OPTIONS
> +-------
> +
> +--env-filter <command>::
> + This is the filter for modifying the environment in which
> + the commit will be performed. Specifically, you might want
> + to rewrite the author/committer name/email/time environment
> + variables (see gitlink:git-commit[1] for details). Do not forget
> + to re-export the variables.
> +
> +--tree-filter <command>::
> + This is the filter for rewriting the tree and its contents.
> + The argument is evaluated in shell with the working
> + directory set to the root of the checked out tree. The new tree
> + is then used as-is (new files are auto-added, disappeared files
> + are auto-removed - .gitignore files nor any other ignore rules
> + HAVE NO EFFECT!).
Is "nor" correct here? Not just "or"?
[...]
> +--subdirectory-filter <directory>::
> + Only regard the history, as seen by the given subdirectory. The
^^^
Does this comma belong there?
> + result will contain that directory as its project root.
> +
> +-d <directory>::
> + Use this option to set the path to the temporary directory used for
> + rewriting. When applying a tree filter, the command needs to
> + temporary checkout the tree to some directory, which may consume
> + considerable space in case of large projects. By default it
> + does this in the '.git-rewrite/' directory but you can override
> + that choice by this parameter.
> +
> +<rev-list-options>::
> + When options are given after the new branch name, they will
> + be passed to gitlink:git-rev-list[1]. Only commits in the resulting
> + output will be filtered, although the filtered commits can still
> + reference parents which are outside of that set.
> +
> +
> +Examples
> +--------
> +
> +Suppose you want to remove a file (containing confidential information
> +or copyright violation) from all commits:
> +
> +-------------------------------------------------------
> +git filter-branch --tree-filter 'rm filename' newbranch
> +-------------------------------------------------------
> +
> +A significantly faster version:
> +
> +-------------------------------------------------------------------------------
> +git filter-branch --index-filter 'git update-index --remove filename' newbranch
> +-------------------------------------------------------------------------------
Even if your code goes beyond 80 chars, the surrounding "---" doesn't
have to and makes it even harder to read when reading the original
asciidoc text.
> +
> +Now, you will get the rewritten history saved in the branch 'newbranch'
> +(your current branch is left untouched).
> +
> +To "etch-graft" a commit to the revision history (set a commit to be
> +the parent of the current initial commit and propagate that):
> +
> +----------------------------------------------------------------------
> +git filter-branch --parent-filter sed\ 's/^$/-p <graft-id>/' newbranch
> +----------------------------------------------------------------------
Wouldn't have 'sed s/^$/-p <graft-id>/' exactly the same effect, since
the quotes are interpreted by the original shell anyway and not the
filter shell? Just wondering why it uses such a complicated way to
express it.
> +(if the parent string is empty - therefore 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:
> +
[...]
Gruesse,
--
Frank Lichtenheld <frank@lichtenheld.de>
www: http://www.djpig.de/
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] Document git-filter-branch
2007-07-03 22:05 ` Frank Lichtenheld
@ 2007-07-03 23:17 ` Johannes Schindelin
2007-07-04 11:29 ` Frank Lichtenheld
2007-07-11 16:53 ` [PATCH] Document git-filter-branch Jakub Narebski
2007-07-03 23:41 ` Johannes Schindelin
2007-07-04 7:32 ` [PATCH] filter-branch documentation: some more touch-ups Johannes Sixt
2 siblings, 2 replies; 12+ messages in thread
From: Johannes Schindelin @ 2007-07-03 23:17 UTC (permalink / raw)
To: Frank Lichtenheld; +Cc: git, gitster
Hi,
[if you comment on just a small portion of the text, could you please
quote only that? Thank you]
On Wed, 4 Jul 2007, Frank Lichtenheld wrote:
> General note: All the stuff in all uppercase should probably also
> have some asciidoc emphasis.
I do not understand. I grepped through all the docs for uppercase words
emphasized in any way, and could not find one.
> On Tue, Jul 03, 2007 at 05:47:44PM +0100, Johannes Schindelin wrote:
>
> > +Note that since this operation is extensively I/O expensive, it might
> > +be a good idea to redirect the temporary directory it off-disk, e.g. on
> ^^^^^^
> The "it" probably doesn't belong there.
Right.
> > +The filters are applied in the order as listed below. The <command>
> > +argument is always evaluated in shell using the 'eval' command.
> > +The $GIT_COMMIT environment variable is permanently set to contain
> ^^^^^^^^^^^
> I find the use of this word in this context odd and a little confusing.
> Maybe better "always" or "each time"?
How about
Prior to that, the $GIT_COMMIT environment variable will be set to
contain the id of the commit being rewritten.
> > +the id of the commit being rewritten. The author/committer environment
> > +variables are set before the first filter is run.
>
> Maybe give the actual names of the environment variables here?
If you think so:
Also, GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, GIT_AUTHOR_DATE,
GIT_COMMITTER_NAME, GIT_COMMITTER_EMAIL, and GIT_COMMITTER_DATE is
set according to the current commit.
> > + is then used as-is (new files are auto-added, disappeared files
> > + are auto-removed - .gitignore files nor any other ignore rules
> > + HAVE NO EFFECT!).
>
> Is "nor" correct here? Not just "or"?
Do you like
neither .gitignore files nor any other ignore rules HAVE ANY
EFFECT!
> [...]
> > +--subdirectory-filter <directory>::
> > + Only regard the history, as seen by the given subdirectory. The
> ^^^
> Does this comma belong there?
This is my bad English. What I meant was this:
Only ever look at the history, which touches the given
subdirectory. The result will contain that directory as its
project root.
> > +-------------------------------------------------------------------------------
> > +git filter-branch --index-filter 'git update-index --remove filename' newbranch
> > +-------------------------------------------------------------------------------
>
> Even if your code goes beyond 80 chars, the surrounding "---" doesn't
> have to and makes it even harder to read when reading the original
> asciidoc text.
I personally read the .txt files, and use asciidoc only when I am forced
to. So it makes a difference for me.
> > +----------------------------------------------------------------------
> > +git filter-branch --parent-filter sed\ 's/^$/-p <graft-id>/' newbranch
> > +----------------------------------------------------------------------
>
> Wouldn't have 'sed s/^$/-p <graft-id>/' exactly the same effect, since
> the quotes are interpreted by the original shell anyway and not the
> filter shell? Just wondering why it uses such a complicated way to
> express it.
Probably not. Since the shell would interpret "s/^$/-p" and "<graft-id>/"
as two arguments to sed.
Besides, like Pasky, I am used to quote the argument, and not the whole
line, that's why the line is still there as it is.
Thanks,
Dscho
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] Document git-filter-branch
2007-07-03 23:17 ` Johannes Schindelin
@ 2007-07-04 11:29 ` Frank Lichtenheld
2007-07-04 14:50 ` [PATCH] filter-branch: a few more touch ups to the man page Johannes Schindelin
2007-07-11 16:53 ` [PATCH] Document git-filter-branch Jakub Narebski
1 sibling, 1 reply; 12+ messages in thread
From: Frank Lichtenheld @ 2007-07-04 11:29 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: git, gitster
On Wed, Jul 04, 2007 at 12:17:05AM +0100, Johannes Schindelin wrote:
> Hi,
>
> [if you comment on just a small portion of the text, could you please
> quote only that? Thank you]
>
> On Wed, 4 Jul 2007, Frank Lichtenheld wrote:
>
> > General note: All the stuff in all uppercase should probably also
> > have some asciidoc emphasis.
>
> I do not understand. I grepped through all the docs for uppercase words
> emphasized in any way, and could not find one.
True. On the other hand it is used at least in the case of WARNING as
a means of emphasis and this should be reflected in the end result
as markup. So I still suggest changing it to *WARNING* or even
*Warning* if you don't want to double the emphasis.
> > On Tue, Jul 03, 2007 at 05:47:44PM +0100, Johannes Schindelin wrote:
> > > +the id of the commit being rewritten. The author/committer environment
> > > +variables are set before the first filter is run.
> >
> > Maybe give the actual names of the environment variables here?
>
> If you think so:
>
> Also, GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, GIT_AUTHOR_DATE,
> GIT_COMMITTER_NAME, GIT_COMMITTER_EMAIL, and GIT_COMMITTER_DATE is
> set according to the current commit.
"are" set. And yeah, it doesn't look pretty. I still prefer having the
list somewhere in the text, though.
> > > + Only regard the history, as seen by the given subdirectory. The
> > ^^^
> > Does this comma belong there?
>
> This is my bad English. What I meant was this:
>
> Only ever look at the history, which touches the given
> subdirectory. The result will contain that directory as its
> project root.
I'm still not sure there should be a comma in this sentence, but my
English grammar is a bit rusty.
Gruesse,
--
Frank Lichtenheld <frank@lichtenheld.de>
www: http://www.djpig.de/
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH] filter-branch: a few more touch ups to the man page
2007-07-04 11:29 ` Frank Lichtenheld
@ 2007-07-04 14:50 ` Johannes Schindelin
2007-07-04 15:06 ` Frank Lichtenheld
0 siblings, 1 reply; 12+ messages in thread
From: Johannes Schindelin @ 2007-07-04 14:50 UTC (permalink / raw)
To: Frank Lichtenheld; +Cc: git, gitster
All based on comments from Frank Lichtenheld.
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
On Wed, 4 Jul 2007, Frank Lichtenheld wrote:
> On Wed, Jul 04, 2007 at 12:17:05AM +0100, Johannes Schindelin wrote:
> >
> > On Wed, 4 Jul 2007, Frank Lichtenheld wrote:
> >
> > > General note: All the stuff in all uppercase should probably
> > > also have some asciidoc emphasis.
>
> [...] it is used at least in the case of WARNING as a means of
> emphasis and this should be reflected in the end result as
> markup. So I still suggest changing it to *WARNING* or even
> *Warning* if you don't want to double the emphasis.
>
> > Also, GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, GIT_AUTHOR_DATE,
> > GIT_COMMITTER_NAME, GIT_COMMITTER_EMAIL, and
> > GIT_COMMITTER_DATE is set according to the current commit.
>
> "are" set. And yeah, it doesn't look pretty. I still prefer
> having the list somewhere in the text, though.
>
> > > > + Only regard the history, as seen by the given [...]
> > > ^^^
> > > Does this comma belong there?
> >
> > This is my bad English. What I meant was this:
> >
> > Only ever look at the history, which touches the given
> > subdirectory. The result will contain that directory as its
> > project root.
>
> I'm still not sure there should be a comma in this sentence, but
> my English grammar is a bit rusty.
Better?
Documentation/git-filter-branch.txt | 11 ++++++-----
1 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/Documentation/git-filter-branch.txt b/Documentation/git-filter-branch.txt
index 2074f31..363287d 100644
--- a/Documentation/git-filter-branch.txt
+++ b/Documentation/git-filter-branch.txt
@@ -31,7 +31,7 @@ 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.
-WARNING! The rewritten history will have different object names for all
+*WARNING*! The rewritten history will have different object names for all
the objects and will not converge with the original branch. You will not
be able to easily push and distribute the rewritten branch on top of the
original branch. Please do not use this command if you do not know the
@@ -54,7 +54,7 @@ argument is always evaluated in shell using the 'eval' command.
Prior to that, the $GIT_COMMIT environment variable will be set to contain
the id of the commit being rewritten. Also, GIT_AUTHOR_NAME,
GIT_AUTHOR_EMAIL, GIT_AUTHOR_DATE, GIT_COMMITTER_NAME, GIT_COMMITTER_EMAIL,
-and GIT_COMMITTER_DATE is set according to the current commit.
+and GIT_COMMITTER_DATE are set according to the current commit.
A 'map' function is available that takes an "original sha1 id" argument
and outputs a "rewritten sha1 id" if the commit has been already
@@ -78,7 +78,7 @@ OPTIONS
directory set to the root of the checked out tree. The new tree
is then used as-is (new files are auto-added, disappeared files
are auto-removed - neither .gitignore files nor any other ignore
- rules HAVE ANY EFFECT!).
+ rules *HAVE ANY EFFECT*!).
--index-filter <command>::
This is the filter for rewriting the index. It is similar to the
@@ -128,8 +128,9 @@ attached, the rewritten tag won't have it. Sorry. (It is by
definition impossible to preserve signatures at any rate.)
--subdirectory-filter <directory>::
- Only ever look at the history, which touches the given subdirectory.
- The result will contain that directory as its project root.
+ Only look at the history which touches the given subdirectory.
+ The result will contain that directory (and only that) as its
+ project root.
-d <directory>::
Use this option to set the path to the temporary directory used for
--
1.5.3.rc0.2663.gfbb70
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH] Document git-filter-branch
2007-07-03 23:17 ` Johannes Schindelin
2007-07-04 11:29 ` Frank Lichtenheld
@ 2007-07-11 16:53 ` Jakub Narebski
2007-07-11 17:03 ` Johannes Schindelin
1 sibling, 1 reply; 12+ messages in thread
From: Jakub Narebski @ 2007-07-11 16:53 UTC (permalink / raw)
To: git
[Cc: git@vger.kernel.org, Johannes Schindelin <Johannes.Schindelin@gmx.de>,
Frank Lichtenheld <frank@lichtenheld.de>]
Johannes Schindelin wrote:
> On Wed, 4 Jul 2007, Frank Lichtenheld wrote:
>>> +Note that since this operation is extensively I/O expensive, it might
>>> +be a good idea to redirect the temporary directory it off-disk, e.g. on
By the way, could git-filter-branch use git-fast-import to reduce I/O?
>>> +the id of the commit being rewritten. The author/committer environment
>>> +variables are set before the first filter is run.
>>
>> Maybe give the actual names of the environment variables here?
>
> If you think so:
>
> Also, GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, GIT_AUTHOR_DATE,
> GIT_COMMITTER_NAME, GIT_COMMITTER_EMAIL, and GIT_COMMITTER_DATE is
> set according to the current commit.
Or
Also, GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, GIT_AUTHOR_DATE,
GIT_COMMITTER_NAME, GIT_COMMITTER_EMAIL, and GIT_COMMITTER_DATE
are filled with data taken from the current commit.
--
Jakub Narebski
Warsaw, Poland
ShadeHawk on #git
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] Document git-filter-branch
2007-07-11 16:53 ` [PATCH] Document git-filter-branch Jakub Narebski
@ 2007-07-11 17:03 ` Johannes Schindelin
0 siblings, 0 replies; 12+ messages in thread
From: Johannes Schindelin @ 2007-07-11 17:03 UTC (permalink / raw)
To: Jakub Narebski; +Cc: Frank Lichtenheld, git
Hi,
On Wed, 11 Jul 2007, Jakub Narebski wrote:
> Johannes Schindelin wrote:
> > On Wed, 4 Jul 2007, Frank Lichtenheld wrote:
>
> >>> +Note that since this operation is extensively I/O expensive, it might
> >>> +be a good idea to redirect the temporary directory it off-disk, e.g. on
>
> By the way, could git-filter-branch use git-fast-import to reduce I/O?
That idea has been kicked around. But since skimo promised that he works
on rewrite-commits, which will be much faster. So I do not see any point
in working on filter-branch any more.
BTW good to see you back on the list!
Ciao,
Dscho
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH] Document git-filter-branch
2007-07-03 22:05 ` Frank Lichtenheld
2007-07-03 23:17 ` Johannes Schindelin
@ 2007-07-03 23:41 ` Johannes Schindelin
2007-07-04 7:32 ` [PATCH] filter-branch documentation: some more touch-ups Johannes Sixt
2 siblings, 0 replies; 12+ messages in thread
From: Johannes Schindelin @ 2007-07-03 23:41 UTC (permalink / raw)
To: Frank Lichtenheld; +Cc: git, gitster
This moves the documentation in git-filter-branch.sh to its own
man page, with a few touch ups (incorporating comments by Frank
Lichtenheld).
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
---
Changes as per my other reply to you. I kinda waited for the
emphasis hint, but I guess it's bed time in Germany.
Documentation/cmd-list.perl | 1 +
Documentation/git-filter-branch.txt | 262 +++++++++++++++++++++++++++++++++++
git-filter-branch.sh | 187 +------------------------
3 files changed, 266 insertions(+), 184 deletions(-)
create mode 100644 Documentation/git-filter-branch.txt
diff --git a/Documentation/cmd-list.perl b/Documentation/cmd-list.perl
index f50f613..2143995 100755
--- a/Documentation/cmd-list.perl
+++ b/Documentation/cmd-list.perl
@@ -105,6 +105,7 @@ git-diff-tree plumbinginterrogators
git-fast-import ancillarymanipulators
git-fetch mainporcelain
git-fetch-pack synchingrepositories
+git-filter-branch ancillarymanipulators
git-fmt-merge-msg purehelpers
git-for-each-ref plumbinginterrogators
git-format-patch mainporcelain
diff --git a/Documentation/git-filter-branch.txt b/Documentation/git-filter-branch.txt
new file mode 100644
index 0000000..2074f31
--- /dev/null
+++ b/Documentation/git-filter-branch.txt
@@ -0,0 +1,262 @@
+git-filter-branch(1)
+====================
+
+NAME
+----
+git-filter-branch - Rewrite branches
+
+SYNOPSIS
+--------
+[verse]
+'git-filter-branch' [--env-filter <command>] [--tree-filter <command>]
+ [--index-filter <command>] [--parent-filter <command>]
+ [--msg-filter <command>] [--commit-filter <command>]
+ [--tag-name-filter <command>] [--subdirectory-filter <directory>]
+ [-d <directory>] <new-branch-name> [<rev-list options>...]
+
+DESCRIPTION
+-----------
+Lets you rewrite git revision history by creating a new branch from
+your current branch, 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.
+
+WARNING! The rewritten history will have different object names for all
+the objects and will not converge with the original branch. You will not
+be able to easily push and distribute the rewritten branch on top of the
+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.
+
+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.
+
+
+Filters
+~~~~~~~
+
+The filters are applied in the order as listed below. The <command>
+argument is always evaluated in shell using the 'eval' command.
+Prior to that, the $GIT_COMMIT environment variable will be set to contain
+the id of the commit being rewritten. Also, GIT_AUTHOR_NAME,
+GIT_AUTHOR_EMAIL, GIT_AUTHOR_DATE, GIT_COMMITTER_NAME, GIT_COMMITTER_EMAIL,
+and GIT_COMMITTER_DATE is set according to the current commit.
+
+A 'map' function is available that takes an "original sha1 id" argument
+and outputs a "rewritten sha1 id" if the commit has been already
+rewritten, fails otherwise; the 'map' function can return several
+ids on separate lines if your commit filter emitted multiple commits.
+
+
+OPTIONS
+-------
+
+--env-filter <command>::
+ This is the filter for modifying the environment in which
+ the commit will be performed. Specifically, you might want
+ to rewrite the author/committer name/email/time environment
+ variables (see gitlink:git-commit[1] for details). Do not forget
+ to re-export the variables.
+
+--tree-filter <command>::
+ This is the filter for rewriting the tree and its contents.
+ The argument is evaluated in shell with the working
+ directory set to the root of the checked out tree. The new tree
+ is then used as-is (new files are auto-added, disappeared files
+ are auto-removed - neither .gitignore files nor any other ignore
+ rules HAVE ANY EFFECT!).
+
+--index-filter <command>::
+ 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 gitlink:git-update-index[1].
+
+--parent-filter <command>::
+ This is the filter for rewriting the commit's parent list.
+ It will receive the parent string on stdin and shall output
+ the new parent string on stdout. The parent string is in
+ a format accepted by gitlink:git-commit-tree[1]: empty for
+ the initial commit, "-p parent" for a normal commit and
+ "-p parent1 -p parent2 -p parent3 ..." for a merge commit.
+
+--msg-filter <command>::
+ This is the filter for rewriting the commit messages.
+ The argument is evaluated in the shell with the original
+ commit message on standard input; its standard output is
+ used as the new commit message.
+
+--commit-filter <command>::
+ This is the filter for performing the commit.
+ If this filter is specified, it will be called instead of the
+ gitlink:git-commit-tree[1] command, with arguments of the form
+ "<TREE_ID> [-p <PARENT_COMMIT_ID>]..." and the log message on
+ stdin. The commit id is expected on stdout.
++
+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.
+
+--tag-name-filter <command>::
+ This is the filter for rewriting tag names. When passed,
+ it will be called for every tag ref that points to a rewritten
+ object (or to a tag object which points to a rewritten object).
+ The original tag name is passed via standard input, and the new
+ 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
+case, be very careful and make sure you have the old tags
+backed up in case the conversion has run afoul.
++
+Note that there is currently no support for proper rewriting of
+tag objects; in layman terms, if the tag has a message or signature
+attached, the rewritten tag won't have it. Sorry. (It is by
+definition impossible to preserve signatures at any rate.)
+
+--subdirectory-filter <directory>::
+ Only ever look at the history, which touches the given subdirectory.
+ The result will contain that directory as its project root.
+
+-d <directory>::
+ Use this option to set the path to the temporary directory used for
+ rewriting. When applying a tree filter, the command needs to
+ temporary checkout the tree to some directory, which may consume
+ considerable space in case of large projects. By default it
+ does this in the '.git-rewrite/' directory but you can override
+ that choice by this parameter.
+
+<rev-list-options>::
+ When options are given after the new branch name, they will
+ be passed to gitlink:git-rev-list[1]. Only commits in the resulting
+ output will be filtered, although the filtered commits can still
+ reference parents which are outside of that set.
+
+
+Examples
+--------
+
+Suppose you want to remove a file (containing confidential information
+or copyright violation) from all commits:
+
+-------------------------------------------------------
+git filter-branch --tree-filter 'rm filename' newbranch
+-------------------------------------------------------
+
+A significantly faster version:
+
+-------------------------------------------------------------------------------
+git filter-branch --index-filter 'git update-index --remove filename' newbranch
+-------------------------------------------------------------------------------
+
+Now, you will get the rewritten history saved in the branch 'newbranch'
+(your current branch is left untouched).
+
+To "etch-graft" a commit to the revision history (set a commit to be
+the parent of the current initial commit and propagate that):
+
+----------------------------------------------------------------------
+git filter-branch --parent-filter sed\ 's/^$/-p <graft-id>/' newbranch
+----------------------------------------------------------------------
+
+(if the parent string is empty - therefore 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 = <commit-id> && echo "-p <graft-id>"' newbranch
+-------------------------------------------------------------------------------
+
+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;
+ else
+ git commit-tree "$@";
+ fi' newbranch
+------------------------------------------------------------------------------
+
+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
+to throw out _changes_ together with the commits, you should use the
+interactive mode of gitlink:git-rebase[1].
+
+Consider this history:
+
+------------------
+ D--E--F--G--H
+ / /
+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
+--------------------------------
+
+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
+----------------------------------------
+
+To move the whole tree into a subdirectory, or remove it from there:
+
+---------------------------------------------------------------
+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
+---------------------------------------------------------------
+
+
+Author
+------
+Written by Petr "Pasky" Baudis <pasky@suse.cz>,
+and the git list <git@vger.kernel.org>
+
+Documentation
+--------------
+Documentation by Petr Baudis and the git list.
+
+GIT
+---
+Part of the gitlink:git[7] suite
diff --git a/git-filter-branch.sh b/git-filter-branch.sh
index 3772951..22fb5bf 100644
--- a/git-filter-branch.sh
+++ b/git-filter-branch.sh
@@ -4,190 +4,9 @@
# Copyright (c) Petr Baudis, 2006
# Minimal changes to "port" it to core-git (c) Johannes Schindelin, 2007
#
-# Lets you rewrite GIT revision history by creating a new branch from
-# your current branch by 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 with 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.)
-#
-# WARNING! The rewritten history will have different ids for all the
-# objects and will not converge with the original branch. You will not
-# be able to easily push and distribute the rewritten branch. Please do
-# not use this command if you do not know the full implications, and
-# avoid using it anyway - do not do what a simple single commit on top
-# of the current version would fix.
-#
-# Always verify that the rewritten version is correct before disposing
-# the original branch.
-#
-# Note that since this operation is extensively I/O expensive, it might
-# be a good idea to do it off-disk, e.g. on tmpfs. Reportedly the speedup
-# is very noticeable.
-#
-# OPTIONS
-# -------
-# -d TEMPDIR:: The path to the temporary tree used for rewriting
-# When applying a tree filter, the command needs to temporary
-# checkout the tree to some directory, which may consume
-# considerable space in case of large projects. By default it
-# does this in the '.git-rewrite/' directory but you can override
-# that choice by this parameter.
-#
-# Filters
-# ~~~~~~~
-# The filters are applied in the order as listed below. The COMMAND
-# argument is always evaluated in shell using the 'eval' command.
-# The $GIT_COMMIT environment variable is permanently set to contain
-# the id of the commit being rewritten. The author/committer environment
-# variables are set before the first filter is run.
-#
-# A 'map' function is available that takes an "original sha1 id" argument
-# and outputs a "rewritten sha1 id" if the commit has been already
-# rewritten, fails otherwise; the 'map' function can return several
-# ids on separate lines if your commit filter emitted multiple commits
-# (see below).
-#
-# --env-filter COMMAND:: The filter for modifying environment
-# This is the filter for modifying the environment in which
-# the commit will be performed. Specifically, you might want
-# to rewrite the author/committer name/email/time environment
-# variables (see `git-commit` for details). Do not forget to
-# re-export the variables.
-#
-# --tree-filter COMMAND:: The filter for rewriting tree (and its contents)
-# This is the filter for rewriting the tree and its contents.
-# The COMMAND argument is evaluated in shell with the working
-# directory set to the root of the checked out tree. The new tree
-# is then used as-is (new files are auto-added, disappeared files
-# are auto-removed - .gitignore files nor any other ignore rules
-# HAVE NO EFFECT!).
-#
-# --index-filter COMMAND:: The filter for rewriting index
-# This is the filter for rewriting the Git's directory index.
-# It is similar to the tree filter but does not check out the
-# tree, which makes it much faster. However, you must use the
-# lowlevel Git index manipulation commands to do your work.
-#
-# --parent-filter COMMAND:: The filter for rewriting parents
-# This is the filter for rewriting the commit's parent list.
-# It will receive the parent string on stdin and shall output
-# the new parent string on stdout. The parent string is in
-# format accepted by `git commit-tree`: empty for initial
-# commit, "-p parent" for a normal commit and "-p parent1
-# -p parent2 -p parent3 ..." for a merge commit.
-#
-# --msg-filter COMMAND:: The filter for rewriting commit message
-# This is the filter for rewriting the commit messages.
-# The COMMAND argument is evaluated in shell with the original
-# commit message on standard input; its standard output is
-# is used as the new commit message.
-#
-# --commit-filter COMMAND:: The filter for performing the commit
-# If this filter is passed, it will be called instead of the
-# `git commit-tree` command, with those arguments:
-#
-# TREE_ID [-p PARENT_COMMIT_ID]...
-#
-# and the log message on stdin. The commit id is expected on
-# stdout. As a special extension, the commit filter may emit
-# multiple commit ids; in that case, all of them will be used
-# as parents instead of the original commit in further commits.
-#
-# --tag-name-filter COMMAND:: The filter for rewriting tag names.
-# If this filter is passed, it will be called for every tag ref
-# that points to a rewritten object (or to a tag object which
-# points to a rewritten object). The original tag name is passed
-# via standard input, and the new 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
-# case, be very careful and make sure you have the old tags
-# backed up in case the conversion has run afoul.
-#
-# Note that there is currently no support for proper rewriting of
-# tag objects; in layman terms, if the tag has a message or signature
-# attached, the rewritten tag won't have it. Sorry. (It is by
-# definition impossible to preserve signatures at any rate, though.)
-#
-# --subdirectory-filter DIRECTORY:: Only regard the history, as seen by
-# the given subdirectory. The result will contain that directory as
-# its project root.
-#
-# EXAMPLE USAGE
-# -------------
-# Suppose you want to remove a file (containing confidential information
-# or copyright violation) from all commits:
-#
-# git-filter-branch --tree-filter 'rm filename' newbranch
-#
-# A significantly faster version:
-#
-# git-filter-branch --index-filter 'git update-index --remove filename' newbranch
-#
-# Now, you will get the rewritten history saved in the branch 'newbranch'
-# (your current branch is left untouched).
-#
-# To "etch-graft" a commit to the revision history (set a commit to be
-# the parent of the current initial commit and propagate that):
-#
-# git-filter-branch --parent-filter sed\ 's/^$/-p graftcommitid/' newbranch
-#
-# (if the parent string is empty - therefore we are dealing with the
-# initial commit - add graftcommit as a parent). Note that this assumes
-# history with a single root (that is, no git-merge without common ancestors
-# happened). If this is not the case, use:
-#
-# git-filter-branch --parent-filter 'cat; [ "$GIT_COMMIT" = "COMMIT" ] && echo "-p GRAFTCOMMIT"' newbranch
-#
-# 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; else git commit-tree "$@"; fi' newbranch
-#
-# (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.
-#
-# Consider this history:
-#
-# D--E--F--G--H
-# / /
-# A--B-----C
-#
-# To rewrite commits D,E,F,G,H, use:
-#
-# git-filter-branch ... new-H 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
-#
-# To move the whole tree into a subdirectory, or remove it from there:
-#
-# 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
-
-# Testsuite: TODO
+# Lets you rewrite the revision history of the current branch, creating
+# a new branch. You can specify a number of filters to modify the commits,
+# files and trees.
set -e
--
1.5.3.rc0.2640.g59df9-dirty
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH] filter-branch documentation: some more touch-ups.
2007-07-03 22:05 ` Frank Lichtenheld
2007-07-03 23:17 ` Johannes Schindelin
2007-07-03 23:41 ` Johannes Schindelin
@ 2007-07-04 7:32 ` Johannes Sixt
2007-07-04 10:58 ` Johannes Schindelin
2 siblings, 1 reply; 12+ messages in thread
From: Johannes Sixt @ 2007-07-04 7:32 UTC (permalink / raw)
To: Johannes Schindelin
Cc: git, gitster, Frank Lichtenheld, j.sixt, Johannes Sixt
- The map function used to fail, but no longer does (since 3520e1e8687.)
- Fix the "edge-graft" example.
- Show the same using .git/info/grafts.
Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
---
I think that "edge-graft" makes more sense than "etch-graft".
Native speakers, please?
I tried the example, and its quoting was incorrect. The reason is that
the shell removes the single quotes even if they are in the middle of
a word; so they didn't end up in the eval'd script and made sed barf.
-- Hannes
Documentation/git-filter-branch.txt | 20 ++++++++++++++------
1 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/Documentation/git-filter-branch.txt b/Documentation/git-filter-branch.txt
index ee60a1a..528ccc8 100644
--- a/Documentation/git-filter-branch.txt
+++ b/Documentation/git-filter-branch.txt
@@ -57,8 +57,9 @@ variables are set before the first filter is run.
A 'map' function is available that takes an "original sha1 id" argument
and outputs a "rewritten sha1 id" if the commit has been already
-rewritten, fails otherwise; the 'map' function can return several
-ids on separate lines if your commit filter emitted multiple commits.
+rewritten, and "original sha1 id" otherwise; the 'map' function can
+return several ids on separate lines if your commit filter emitted
+multiple commits.
OPTIONS
@@ -164,12 +165,12 @@ git filter-branch --index-filter 'git update-index --remove filename' newbranch
Now, you will get the rewritten history saved in the branch 'newbranch'
(your current branch is left untouched).
-To "etch-graft" a commit to the revision history (set a commit to be
+To "edge-graft" a commit to the revision history (set a commit to be
the parent of the current initial commit and propagate that):
-----------------------------------------------------------------------
-git filter-branch --parent-filter sed\ 's/^$/-p <graft-id>/' newbranch
-----------------------------------------------------------------------
+------------------------------------------------------------------------
+git filter-branch --parent-filter 'sed "s/^\$/-p <graft-id>/"' newbranch
+------------------------------------------------------------------------
(if the parent string is empty - therefore we are dealing with the
initial commit - add graftcommit as a parent). Note that this assumes
@@ -181,6 +182,13 @@ git filter-branch --parent-filter \
'cat; test $GIT_COMMIT = <commit-id> && echo "-p <graft-id>"' newbranch
-------------------------------------------------------------------------------
+or even simpler:
+
+-----------------------------------------------
+echo "$commit-id $graft-id" >> .git/info/grafts
+git filter-branch newbranch $graft-id..
+-----------------------------------------------
+
To remove commits authored by "Darl McBribe" from the history:
------------------------------------------------------------------------------
--
1.5.3.rc0.5.g7cd9
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH] filter-branch documentation: some more touch-ups.
2007-07-04 7:32 ` [PATCH] filter-branch documentation: some more touch-ups Johannes Sixt
@ 2007-07-04 10:58 ` Johannes Schindelin
2007-07-04 16:56 ` Junio C Hamano
0 siblings, 1 reply; 12+ messages in thread
From: Johannes Schindelin @ 2007-07-04 10:58 UTC (permalink / raw)
To: Johannes Sixt; +Cc: git, gitster, Frank Lichtenheld, j.sixt
Hi,
On Wed, 4 Jul 2007, Johannes Sixt wrote:
> - The map function used to fail, but no longer does (since 3520e1e8687.)
> - Fix the "edge-graft" example.
> - Show the same using .git/info/grafts.
>
> Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
> ---
>
> I think that "edge-graft" makes more sense than "etch-graft".
> Native speakers, please?
I looked at dict.leo.org, and it does not know either version. Maybe it is
just "graft"?
Except for that,
Acked-by: Johannes E. Schindelin <johannes.schindelin@gmx.de>
> I tried the example, and its quoting was incorrect. The reason is that
> the shell removes the single quotes even if they are in the middle of
> a word; so they didn't end up in the eval'd script and made sed barf.
Thanks for sanity checking. It looked so obviously correct to me that I
did not bother checking, but your are correct, they were broken.
Unfortunately, I even would have missed it writing a test case, because
that need an extra level of quoting!
Ciao,
Dscho
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH] filter-branch documentation: some more touch-ups.
2007-07-04 10:58 ` Johannes Schindelin
@ 2007-07-04 16:56 ` Junio C Hamano
0 siblings, 0 replies; 12+ messages in thread
From: Junio C Hamano @ 2007-07-04 16:56 UTC (permalink / raw)
To: Johannes Schindelin; +Cc: Johannes Sixt, git, Frank Lichtenheld, j.sixt
Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:
> On Wed, 4 Jul 2007, Johannes Sixt wrote:
>
>> - The map function used to fail, but no longer does (since 3520e1e8687.)
>> - Fix the "edge-graft" example.
>> - Show the same using .git/info/grafts.
>>
>> Signed-off-by: Johannes Sixt <johannes.sixt@telecom.at>
>> ---
>>
>> I think that "edge-graft" makes more sense than "etch-graft".
>> Native speakers, please?
>
> I looked at dict.leo.org, and it does not know either version. Maybe it is
> just "graft"?
Why even need a new term there, if you are not going to use it
elsewhere? Instead of saying:
-To "etch-graft" a commit to the revision history (set a commit to be
+To "edge-graft" a commit to the revision history (set a commit to be
the parent of the current initial commit and propagate that):
----------------------------------------------------------------------
git filter-branch --parent-filter sed\ 's/^$/-p <graft-id>/' newbranch
----------------------------------------------------------------------
You could say:
To set a commit to be the parent of the current initial
commit and propagate that:
without inventing unfamiliar word that is not used anywhere else
in the documentation.
One thing that you may want to stress is that <graft-id> does
not represent a single commit, but the history that leads to it.
So "set a commit to be a parent" is technically correct, but it
is not "To edge-graft _a_ commit", but more like "Paste another
history behind the current beginning of time".
You have two filmstrips, the first frame of one filmstrip, your
current history, should logically follow the last frame of the
other filmstrip but they are separated into two. You are
splicing them together to make a single, longer, filmstrip.
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2007-07-11 17:10 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-07-03 16:47 [PATCH] Document git-filter-branch Johannes Schindelin
2007-07-03 22:05 ` Frank Lichtenheld
2007-07-03 23:17 ` Johannes Schindelin
2007-07-04 11:29 ` Frank Lichtenheld
2007-07-04 14:50 ` [PATCH] filter-branch: a few more touch ups to the man page Johannes Schindelin
2007-07-04 15:06 ` Frank Lichtenheld
2007-07-11 16:53 ` [PATCH] Document git-filter-branch Jakub Narebski
2007-07-11 17:03 ` Johannes Schindelin
2007-07-03 23:41 ` Johannes Schindelin
2007-07-04 7:32 ` [PATCH] filter-branch documentation: some more touch-ups Johannes Sixt
2007-07-04 10:58 ` Johannes Schindelin
2007-07-04 16:56 ` Junio C Hamano
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).