[PATCH] fast-export: Add a --full-tree option

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Elijah Newren <newren@xxxxxxxxx>

This option makes fast-export issue a 'deleteall' directive and then the
full set of files that make up each commit, rather than just showing the
list of files that have changed since the (first) parent commit.

This is useful in at least two cases:

(1) When rewriting history for large repositories (i.e. where
git-filter-branch is much too slow to be functional), it is useful to use
fast-export + some filter + fast-import.  Sometimes it is easier to write
the necessary filter in terms of all the files in a commit rather than
just the differences from the first parent.

(2) When rewriting history and trying to remove early versions of some
subtrees, one can almost do so with the following recipe:
  Run fast-export once with a strict subset of paths up to a certain
  point in history, and then rerun fast-export on a more complete set of
  paths for the remainder of history.
Unfortunately, this results in files missing between the special history
point and their first modification after that time (and any unchanged
files in that span of history just missing altogether).  Running the
second fast-export with this new --full-tree option will fix this.

(git-filter-branch should be sufficient to handle the second usecase if
one is facing a situation that exactly matches that wording, but
variations of that usecase may result in fast-export being a better
choice for large repositories, and it would be nice to provide the
capability for it to handle such situations.)

Signed-off-by: Elijah Newren <newren@xxxxxxxxx>
---
This is a resend of an earlier patch that didn't get reviewed or make it
to pu.  I tried to make the commit message and documentation clearer and
explain in more detail the reasons for this change.

Also, note that this patch has a trivial dependence on my D/F conflict
fixes patch series that I just sent out, and will not apply cleanly (due
to a context region conflict) unless that patch series is applied first.
If wanted, I can change this by moving the t9350-fast-export.sh changes
to elsewhere in that file, or by rerolling this patch directly on top of
next.

 Documentation/git-fast-export.txt |    6 ++++++
 builtin/fast-export.c             |    8 +++++++-
 t/t9350-fast-export.sh            |   35 +++++++++++++++++++++++++++++++++++
 3 files changed, 48 insertions(+), 1 deletions(-)

diff --git a/Documentation/git-fast-export.txt b/Documentation/git-fast-export.txt
index 98ec6b5..8a6a3cb 100644
--- a/Documentation/git-fast-export.txt
+++ b/Documentation/git-fast-export.txt
@@ -90,6 +90,12 @@ marks the same across runs.
 	resulting stream can only be used by a repository which
 	already contains the necessary objects.
 
+--full-tree::
+	This option will cause fast-export to issue a "deleteall"
+	directive for each commit followed by a full list of all files
+	in the commit (as opposed to just listing the files which are
+	different from the commit's first parent).
+
 [git-rev-list-args...]::
        A list of arguments, acceptable to 'git rev-parse' and
        'git rev-list', that specifies the specific objects and references
diff --git a/builtin/fast-export.c b/builtin/fast-export.c
index 9fe25ff..fe7a61b 100644
--- a/builtin/fast-export.c
+++ b/builtin/fast-export.c
@@ -26,6 +26,7 @@ static int progress;
 static enum { ABORT, VERBATIM, WARN, STRIP } signed_tag_mode = ABORT;
 static enum { ERROR, DROP, REWRITE } tag_of_filtered_mode = ABORT;
 static int fake_missing_tagger;
+static int full_tree;
 static int no_data;
 
 static int parse_opt_signed_tag_mode(const struct option *opt,
@@ -241,7 +242,8 @@ static void handle_commit(struct commit *commit, struct rev_info *rev)
 		message += 2;
 
 	if (commit->parents &&
-	    get_object_mark(&commit->parents->item->object) != 0) {
+	    get_object_mark(&commit->parents->item->object) != 0 &&
+	    !full_tree) {
 		parse_commit(commit->parents->item);
 		diff_tree_sha1(commit->parents->item->tree->object.sha1,
 			       commit->tree->object.sha1, "", &rev->diffopt);
@@ -281,6 +283,8 @@ static void handle_commit(struct commit *commit, struct rev_info *rev)
 		i++;
 	}
 
+	if (full_tree)
+		printf("deleteall\n");
 	log_tree_diff_flush(rev);
 	rev->diffopt.output_format = saved_output_format;
 
@@ -584,6 +588,8 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)
 			     "Import marks from this file"),
 		OPT_BOOLEAN(0, "fake-missing-tagger", &fake_missing_tagger,
 			     "Fake a tagger when tags lack one"),
+		OPT_BOOLEAN(0, "full-tree", &full_tree,
+			     "Output full tree for each commit"),
 		{ OPTION_NEGBIT, 0, "data", &no_data, NULL,
 			"Skip output of blob data",
 			PARSE_OPT_NOARG | PARSE_OPT_NEGHELP, NULL, 1 },
diff --git a/t/t9350-fast-export.sh b/t/t9350-fast-export.sh
index 1ee1461..05c79ea 100755
--- a/t/t9350-fast-export.sh
+++ b/t/t9350-fast-export.sh
@@ -400,4 +400,39 @@ test_expect_success 'directory becomes symlink'        '
 	(cd result && git show master:foo)
 '
 
+cat >> dirtosymlink/expected << EOF
+blob
+mark :5
+data 6
+hello
+
+blob
+mark :6
+data 7
+badlink
+commit refs/heads/master
+mark :7
+author A U Thor <author@xxxxxxxxxxx> 1112912713 -0700
+committer C O Mitter <committer@xxxxxxxxxxx> 1112912713 -0700
+data 6
+three
+from :4
+deleteall
+M 100644 :5 bar/world
+M 120000 :6 foo
+
+EOF
+
+test_expect_success 'full-tree'        '
+	(
+		cd dirtosymlink &&
+		git fast-export --export-marks=marks master -- foo > output1 &&
+		rm foo &&
+		ln -s badlink foo &&
+		git commit -mthree foo &&
+		git fast-export --import-marks=marks --full-tree master -- foo bar > output &&
+		test_cmp output expected
+	)
+'
+
 test_done
-- 
1.7.2.rc0.212.g0c601

--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]