diff options
Diffstat (limited to 'git-filter-branch.sh')
-rwxr-xr-x | git-filter-branch.sh | 104 |
1 files changed, 92 insertions, 12 deletions
diff --git a/git-filter-branch.sh b/git-filter-branch.sh index b7827e7..1b7e4b2 100755 --- a/git-filter-branch.sh +++ b/git-filter-branch.sh @@ -81,12 +81,12 @@ set_ident () { finish_ident COMMITTER } -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>] + [--original <namespace>] + [-d <directory>] [-f | --force] [--state-branch <branch>] [--] [<rev-list options>...]" OPTIONS_SPEC= @@ -106,6 +106,7 @@ filter_msg=cat filter_commit= filter_tag_name= filter_subdir= +state_branch= orig_namespace=refs/original/ force= prune_empty= @@ -181,6 +182,9 @@ do --original) orig_namespace=$(expr "$OPTARG/" : '\(.*[^/]\)/*$')/ ;; + --state-branch) + state_branch="$OPTARG" + ;; *) usage ;; @@ -219,6 +223,13 @@ trap 'cd "$orig_dir"; rm -rf "$tempdir"' 0 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 @@ -252,6 +263,26 @@ export GIT_INDEX_FILE # 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" @@ -530,7 +561,7 @@ if [ "$filter_tag_name" ]; then }' \ -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 @@ -544,12 +575,9 @@ if [ "$filter_tag_name" ]; then 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 } @@ -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 |