Merge branch 'dg/filter-branch-filter-order-doc'
authorJunio C Hamano <gitster@pobox.com>
Thu, 19 Oct 2017 05:45:45 +0000 (14:45 +0900)
committerJunio C Hamano <gitster@pobox.com>
Thu, 19 Oct 2017 05:45:45 +0000 (14:45 +0900)
Update the documentation for "git filter-branch" so that the filter
options are listed in the same order as they are applied, as
described in an earlier part of the doc.

* dg/filter-branch-filter-order-doc:
doc: list filter-branch subdirectory-filter first

1  2 
Documentation/git-filter-branch.txt
git-filter-branch.sh
index bebdcdec5ad4775588abe8814c59a269c7c1a832,394f74451a659cf5cbc22aaccb5937d2ac88ca29..3a52e4dce39eeaf6eba896ccbf9e0505cebb3ec9
@@@ -8,13 -8,13 +8,13 @@@ git-filter-branch - Rewrite branche
  SYNOPSIS
  --------
  [verse]
- 'git filter-branch' [--setup <command>] [--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>] [--prune-empty]
+ 'git filter-branch' [--setup <command>] [--subdirectory-filter <directory>]
+       [--env-filter <command>] [--tree-filter <command>]
+       [--index-filter <command>] [--parent-filter <command>]
+       [--msg-filter <command>] [--commit-filter <command>]
+       [--tag-name-filter <command>] [--prune-empty]
        [--original <namespace>] [-d <directory>] [-f | --force]
 -      [--] [<rev-list options>...]
 +      [--state-branch <branch>] [--] [<rev-list options>...]
  
  DESCRIPTION
  -----------
@@@ -89,6 -89,11 +89,11 @@@ OPTION
        can be used or modified in the following filter steps except
        the commit filter, for technical reasons.
  
+ --subdirectory-filter <directory>::
+       Only look at the history which touches the given subdirectory.
+       The result will contain that directory (and only that) as its
+       project root. Implies <<Remap_to_ancestor>>.
  --env-filter <command>::
        This filter may be used if you only need to modify the environment
        in which the commit will be performed.  Specifically, you might
@@@ -167,11 -172,6 +172,6 @@@ be removed, buyer beware. There is als
  author or timestamp (or the tag message for that matter). Tags which point
  to other tags will be rewritten to point to the underlying commit.
  
- --subdirectory-filter <directory>::
-       Only look at the history which touches the given subdirectory.
-       The result will contain that directory (and only that) as its
-       project root. Implies <<Remap_to_ancestor>>.
  --prune-empty::
        Some filters will generate empty commits that leave the tree untouched.
        This option instructs git-filter-branch to remove such commits if they
        directory or when there are already refs starting with
        'refs/original/', unless forced.
  
 +--state-branch <branch>::
 +      This option will cause the mapping from old to new objects to
 +      be loaded from named branch upon startup and saved as a new
 +      commit to that branch upon exit, enabling incremental of large
 +      trees. If '<branch>' does not exist it will be created.
 +
  <rev-list options>...::
        Arguments for 'git rev-list'.  All positive refs included by
        these options are rewritten.  You may also specify options
diff --combined git-filter-branch.sh
index 3365a3b866b510db5bf9ca20a0341c34c21b7a69,b7827e745a92a380bdb2e8c940a65742a7c43463..1b7e4b2cdbdf36e090c4b1f531dcc48222d8f8b1
@@@ -81,12 -81,12 +81,12 @@@ set_ident () 
        finish_ident COMMITTER
  }
  
- USAGE="[--setup <command>] [--env-filter <command>]
 -USAGE="[--setup <command>] [--subdirectory-filter <directory>]
 -      [--env-filter <command>] [--tree-filter <command>]
 -      [--index-filter <command>] [--parent-filter <command>]
 -      [--msg-filter <command>] [--commit-filter <command>]
 -      [--tag-name-filter <command>] [--prune-empty]
 -      [--original <namespace>] [-d <directory>] [-f | --force]
++USAGE="[--setup <command>] [--subdirectory-filter <directory>] [--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>] [--original <namespace>]
++      [--original <namespace>]
 +      [-d <directory>] [-f | --force] [--state-branch <branch>]
        [--] [<rev-list options>...]"
  
  OPTIONS_SPEC=
@@@ -106,7 -106,6 +106,7 @@@ filter_msg=ca
  filter_commit=
  filter_tag_name=
  filter_subdir=
 +state_branch=
  orig_namespace=refs/original/
  force=
  prune_empty=
        --setup)
                filter_setup="$OPTARG"
                ;;
+       --subdirectory-filter)
+               filter_subdir="$OPTARG"
+               remap_to_ancestor=t
+               ;;
        --env-filter)
                filter_env="$OPTARG"
                ;;
        --tag-name-filter)
                filter_tag_name="$OPTARG"
                ;;
-       --subdirectory-filter)
-               filter_subdir="$OPTARG"
-               remap_to_ancestor=t
-               ;;
        --original)
                orig_namespace=$(expr "$OPTARG/" : '\(.*[^/]\)/*$')/
                ;;
 +      --state-branch)
 +              state_branch="$OPTARG"
 +              ;;
        *)
                usage
                ;;
@@@ -223,13 -219,6 +223,13 @@@ trap 'cd "$orig_dir"; rm -rf "$tempdir"
  ORIG_GIT_DIR="$GIT_DIR"
  ORIG_GIT_WORK_TREE="$GIT_WORK_TREE"
  ORIG_GIT_INDEX_FILE="$GIT_INDEX_FILE"
 +ORIG_GIT_AUTHOR_NAME="$GIT_AUTHOR_NAME"
 +ORIG_GIT_AUTHOR_EMAIL="$GIT_AUTHOR_EMAIL"
 +ORIG_GIT_AUTHOR_DATE="$GIT_AUTHOR_DATE"
 +ORIG_GIT_COMMITTER_NAME="$GIT_COMMITTER_NAME"
 +ORIG_GIT_COMMITTER_EMAIL="$GIT_COMMITTER_EMAIL"
 +ORIG_GIT_COMMITTER_DATE="$GIT_COMMITTER_DATE"
 +
  GIT_WORK_TREE=.
  export GIT_DIR GIT_WORK_TREE
  
@@@ -263,26 -252,6 +263,26 @@@ export GIT_INDEX_FIL
  # map old->new commit ids for rewriting parents
  mkdir ../map || die "Could not create map/ directory"
  
 +if test -n "$state_branch"
 +then
 +      state_commit=$(git rev-parse --no-flags --revs-only "$state_branch")
 +      if test -n "$state_commit"
 +      then
 +              echo "Populating map from $state_branch ($state_commit)" 1>&2
 +              perl -e'open(MAP, "-|", "git show $ARGV[0]:filter.map") or die;
 +                      while (<MAP>) {
 +                              m/(.*):(.*)/ or die;
 +                              open F, ">../map/$1" or die;
 +                              print F "$2" or die;
 +                              close(F) or die;
 +                      }
 +                      close(MAP) or die;' "$state_commit" \
 +                              || die "Unable to load state from $state_branch:filter.map"
 +      else
 +              echo "Branch $state_branch does not exist. Will create" 1>&2
 +      fi
 +fi
 +
  # we need "--" only if there are no path arguments in $@
  nonrevs=$(git rev-parse --no-revs "$@") || exit
  if test -z "$nonrevs"
@@@ -561,7 -530,7 +561,7 @@@ if [ "$filter_tag_name" ]; the
                                        }' \
                                    -e '/^-----BEGIN PGP SIGNATURE-----/q' \
                                    -e 'p' ) |
 -                              git mktag) ||
 +                              git hash-object -t tag -w --stdin) ||
                                die "Could not create new tag object for $ref"
                        if git cat-file tag "$ref" | \
                           sane_grep '^-----BEGIN PGP SIGNATURE-----' >/dev/null 2>&1
        done
  fi
  
 -cd "$orig_dir"
 -rm -rf "$tempdir"
 -
 -trap - 0
 -
  unset GIT_DIR GIT_WORK_TREE GIT_INDEX_FILE
 +unset GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL GIT_AUTHOR_DATE
 +unset GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL GIT_COMMITTER_DATE
  test -z "$ORIG_GIT_DIR" || {
        GIT_DIR="$ORIG_GIT_DIR" && export GIT_DIR
  }
@@@ -589,58 -561,6 +589,58 @@@ test -z "$ORIG_GIT_INDEX_FILE" || 
        GIT_INDEX_FILE="$ORIG_GIT_INDEX_FILE" &&
        export GIT_INDEX_FILE
  }
 +test -z "$ORIG_GIT_AUTHOR_NAME" || {
 +      GIT_AUTHOR_NAME="$ORIG_GIT_AUTHOR_NAME" &&
 +      export GIT_AUTHOR_NAME
 +}
 +test -z "$ORIG_GIT_AUTHOR_EMAIL" || {
 +      GIT_AUTHOR_EMAIL="$ORIG_GIT_AUTHOR_EMAIL" &&
 +      export GIT_AUTHOR_EMAIL
 +}
 +test -z "$ORIG_GIT_AUTHOR_DATE" || {
 +      GIT_AUTHOR_DATE="$ORIG_GIT_AUTHOR_DATE" &&
 +      export GIT_AUTHOR_DATE
 +}
 +test -z "$ORIG_GIT_COMMITTER_NAME" || {
 +      GIT_COMMITTER_NAME="$ORIG_GIT_COMMITTER_NAME" &&
 +      export GIT_COMMITTER_NAME
 +}
 +test -z "$ORIG_GIT_COMMITTER_EMAIL" || {
 +      GIT_COMMITTER_EMAIL="$ORIG_GIT_COMMITTER_EMAIL" &&
 +      export GIT_COMMITTER_EMAIL
 +}
 +test -z "$ORIG_GIT_COMMITTER_DATE" || {
 +      GIT_COMMITTER_DATE="$ORIG_GIT_COMMITTER_DATE" &&
 +      export GIT_COMMITTER_DATE
 +}
 +
 +if test -n "$state_branch"
 +then
 +      echo "Saving rewrite state to $state_branch" 1>&2
 +      state_blob=$(
 +              perl -e'opendir D, "../map" or die;
 +                      open H, "|-", "git hash-object -w --stdin" or die;
 +                      foreach (sort readdir(D)) {
 +                              next if m/^\.\.?$/;
 +                              open F, "<../map/$_" or die;
 +                              chomp($f = <F>);
 +                              print H "$_:$f\n" or die;
 +                      }
 +                      close(H) or die;' || die "Unable to save state")
 +      state_tree=$(/bin/echo -e "100644 blob $state_blob\tfilter.map" | git mktree)
 +      if test -n "$state_commit"
 +      then
 +              state_commit=$(/bin/echo "Sync" | git commit-tree "$state_tree" -p "$state_commit")
 +      else
 +              state_commit=$(/bin/echo "Sync" | git commit-tree "$state_tree" )
 +      fi
 +      git update-ref "$state_branch" "$state_commit"
 +fi
 +
 +cd "$orig_dir"
 +rm -rf "$tempdir"
 +
 +trap - 0
  
  if [ "$(is_bare_repository)" = false ]; then
        git read-tree -u -m HEAD || exit