Skip to contentSkip to conversation

filter-branch: support for incremental update + fix for ancient tag format

PATCH In review Ian Campbell 2 participants 8 messages Sep 21, 2017 – Sep 22, 2017 Documentation

lore
Share & tools
lore
#0 lore raw

v3 cover filter-branch: support for incremental update + fix for ancient tag format

This is the third version of my patches to add incremental support to git-filter-branch. Since the last time I have replaced git mktag -- allow-missing-tagger with git hash-object -t tag -w --stdin.

I've force pushed to [1] (Travis is still running) and have set off the process of re-rewriting the devicetree tree from scratch (a multi-day affair) to validate (it's looking good).

Ian.

[0] https://git.kernel.org/pub/scm/linux/kernel/git/devicetree/devicetree-rebasing.git/
[1] https://github.com/ijc/git/tree/git-filter-branch

#1 lore raw

PATCH v3 1/4 filter-branch: reset $GIT_* before cleaning up

This is pure code motion to enable a subsequent patch to add code which needs to happen with the reset $GIT_* but before the temporary directory has been cleaned up.

---
 git-filter-branch.sh | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)
git-filter-branch.sh +5 -5
index 3a74602ef..3da281f8a 100755
@@ -544,11 +544,6 @@ if [ "$filter_tag_name" ]; then
 	done
 fi
 
-cd "$orig_dir"
-rm -rf "$tempdir"
-
-trap - 0
-
 unset GIT_DIR GIT_WORK_TREE GIT_INDEX_FILE
 test -z "$ORIG_GIT_DIR" || {
 	GIT_DIR="$ORIG_GIT_DIR" && export GIT_DIR
@@ -562,6 +557,11 @@ test -z "$ORIG_GIT_INDEX_FILE" || {
 	export GIT_INDEX_FILE
 }
 
+cd "$orig_dir"
+rm -rf "$tempdir"
+
+trap - 0
+
 if [ "$(is_bare_repository)" = false ]; then
 	git read-tree -u -m HEAD || exit
 fi
Signature · 1 line
2.11.0
#2 lore raw

PATCH v3 2/4 filter-branch: preserve and restore $GIT_AUTHOR_* and $GIT_COMMITTER_*

In reply to Ian Campbell

These are modified by set_ident() but a subsequent patch would like to operate on their original values.

---
 git-filter-branch.sh | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)
git-filter-branch.sh +33 -0
index 3da281f8a..9edb94206 100755
@@ -219,6 +219,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
 
@@ -545,6 +552,8 @@ if [ "$filter_tag_name" ]; then
 fi
 
 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
 }
@@ -556,6 +565,30 @@ 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
+}
 
 cd "$orig_dir"
 rm -rf "$tempdir"
Signature · 1 line
2.11.0
#3 lore raw

PATCH v3 3/4 filter-branch: stash away ref map in a branch

In reply to Ian Campbell

With "--state-branch=<branchname>" option, the mapping from old object names and filtered ones in ./map/ directory is stashed away in the object database, and the one from the previous run is read to populate the ./map/ directory, allowing for incremental updates of large trees.

---
I have been using this as part of the device tree extraction from the Linux kernel source since 2013, about time I sent the patch upstream!

v2:
- added several preceding cleanup patches, including:
- new: use of mktag --allow-missing tagger.
- split-out: preserving $GIT_*.
- use git rev-parse rather than git show-ref.
- improved error handling for Perl sub-processes.
- collapsed some shell pipelines involving piping output of git and ls into Perl into the Perl scripts.
- style fixes for conditionals and sub-shells.
- fixup indentation.
- added documentation.
- improved commit message.

---
 Documentation/git-filter-branch.txt |  8 +++++-
 git-filter-branch.sh                | 49 ++++++++++++++++++++++++++++++++++++-
 2 files changed, 55 insertions(+), 2 deletions(-)
Documentation/git-filter-branch.txt +7 -1
index 9e5169aa6..bebdcdec5 100644
@@ -14,7 +14,7 @@ SYNOPSIS
 	[--commit-filter <command>] [--tag-name-filter <command>]
 	[--subdirectory-filter <directory>] [--prune-empty]
 	[--original <namespace>] [-d <directory>] [-f | --force]
-	[--] [<rev-list options>...]
+	[--state-branch <branch>] [--] [<rev-list options>...]
 
 DESCRIPTION
 -----------
@@ -198,6 +198,12 @@ to other tags will be rewritten to point to the underlying commit.
 	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
git-filter-branch.sh +48 -1

79 lines not on this page · raw message

Signature · 1 line
2.11.0
#4 lore raw

PATCH v3 4/4 filter-branch: use hash-object instead of mktag

In reply to Ian Campbell

This allows us to recreate even historical tags which would now be consider invalid, such as v2.6.12-rc2..v2.6.13-rc3 in the Linux kernel source tree which lack the tagger header.

    $ git rev-parse v2.6.12-rc2
    9e734775f7c22d2f89943ad6c745571f1930105f
    $ git cat-file tag v2.6.12-rc2 | git mktag
    error: char76: could not find "tagger "
    fatal: invalid tag signature file
    $ git cat-file tag v2.6.12-rc2 | git hash-object -t tag -w --stdin
    9e734775f7c22d2f89943ad6c745571f1930105f
---
 git-filter-branch.sh | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
git-filter-branch.sh +1 -1
index 956869b8e..3365a3b86 100755
@@ -561,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
Signature · 1 line
2.11.0
#5 lore raw
In reply to Ian Campbell
Quoted 7 lines · Ian Campbell

This is the third version of my patches to add incremental support to git-filter-branch. Since the last time I have replaced git mktag -- allow-missing-tagger with git hash-object -t tag -w --stdin.

I've force pushed to [1] (Travis is still running) and have set off the process of re-rewriting the devicetree tree from scratch (a multi-day affair) to validate (it's looking good).

Thanks.

#6 lore raw
Quoted 11 lines · Junio C Hamano
Quoted 7 lines · Ian Campbell

This is the third version of my patches to add incremental support to git-filter-branch. Since the last time I have replaced git mktag -- allow-missing-tagger with git hash-object -t tag -w --stdin.

I've force pushed to [1] (Travis is still running) and have set off the process of re-rewriting the devicetree tree from scratch (a multi-day affair) to validate (it's looking good).

Thanks.

Travis is happy and the dt reconvert looks sensible (only took 60 hours ;-)).

Don't know if this is useful to your workflow but:

The following changes since commit 4384e3cde2ce8ecd194202e171ae16333d241326:

  Git 2.14 (2017-08-04 09:31:12 -0700)

are available in the git repository at:

  https://github.com/ijc/git git-filter-branch

for you to fetch changes up to e31c74f709fbf2827d57b4abf826bb836f120329:

  filter-branch: use hash-object instead of mktag (2017-09-21 08:44:59 +0100)

----------------------------------------------------------------
Ian Campbell (4):
      filter-branch: reset $GIT_* before cleaning up
      filter-branch: preserve and restore $GIT_AUTHOR_* and $GIT_COMMITTER_*
      filter-branch: stash away ref map in a branch
      filter-branch: use hash-object instead of mktag

 Documentation/git-filter-branch.txt |  8 +++++++-
 git-filter-branch.sh                | 94 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------

 2 files changed, 94 insertions(+), 8 deletions(-)
#7 lore raw
Quoted 2 lines · Ian Campbell

Travis is happy and the dt reconvert looks sensible (only took 60 hours ;-)).

Good.

Quoted 7 lines

Don't know if this is useful to your workflow but:

The following changes since commit 4384e3cde2ce8ecd194202e171ae16333d241326:

  Git 2.14 (2017-08-04 09:31:12 -0700)

are available...

That should match (modulo that they lack my sign-off, for obvious reasons) what I have in the 'pu' branch, four commits on a single strand of pearls ending at b2c1ca6b ("filter-branch: use hash-object instead of mktag", 2017-09-21).

Thanks.