{"thread":{"id":"24226","subject":"[PATCH] fast-export: Add a --full-tree option","startedAt":"2010-06-29T01:22:05Z","lastAt":"2010-06-29T13:02:02Z","messageCount":2,"participants":["newren@gmail.com","Elijah Newren"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"144435","messageId":"1277774525-12530-1-git-send-email-newren@gmail.com","threadId":"24226","inReplyTo":null,"subject":"[PATCH] fast-export: Add a --full-tree option","fromName":"","fromEmail":"newren@gmail.com","sentAt":"2010-06-29T01:22:05Z","receivedAt":"2010-06-29T01:22:05Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"From: Elijah Newren <newren@gmail.com>\n\nThis option makes fast-export issue a 'deleteall' directive and then the\nfull set of files that make up each commit, rather than just showing the\nlist of files that have changed since the (first) parent commit.\n\nThis is useful in at least two cases:\n\n(1) When rewriting history for large repositories (i.e. where\ngit-filter-branch is much too slow to be functional), it is useful to use\nfast-export + some filter + fast-import.  Sometimes it is easier to write\nthe necessary filter in terms of all the files in a commit rather than\njust the differences from the first parent.\n\n(2) When rewriting history and trying to remove early versions of some\nsubtrees, one can almost do so with the following recipe:\n  Run fast-export once with a strict subset of paths up to a certain\n  point in history, and then rerun fast-export on a more complete set of\n  paths for the remainder of history.\nUnfortunately, this results in files missing between the special history\npoint and their first modification after that time (and any unchanged\nfiles in that span of history just missing altogether).  Running the\nsecond fast-export with this new --full-tree option will fix this.\n\n(git-filter-branch should be sufficient to handle the second usecase if\none is facing a situation that exactly matches that wording, but\nvariations of that usecase may result in fast-export being a better\nchoice for large repositories, and it would be nice to provide the\ncapability for it to handle such situations.)\n\nSigned-off-by: Elijah Newren <newren@gmail.com>\n---\nThis is a resend of an earlier patch that didn't get reviewed or make it\nto pu.  I tried to make the commit message and documentation clearer and\nexplain in more detail the reasons for this change.\n\nAlso, note that this patch has a trivial dependence on my D/F conflict\nfixes patch series that I just sent out, and will not apply cleanly (due\nto a context region conflict) unless that patch series is applied first.\nIf wanted, I can change this by moving the t9350-fast-export.sh changes\nto elsewhere in that file, or by rerolling this patch directly on top of\nnext.\n\n Documentation/git-fast-export.txt |    6 ++++++\n builtin/fast-export.c             |    8 +++++++-\n t/t9350-fast-export.sh            |   35 +++++++++++++++++++++++++++++++++++\n 3 files changed, 48 insertions(+), 1 deletions(-)\n\ndiff --git a/Documentation/git-fast-export.txt b/Documentation/git-fast-export.txt\nindex 98ec6b5..8a6a3cb 100644\n--- a/Documentation/git-fast-export.txt\n+++ b/Documentation/git-fast-export.txt\n@@ -90,6 +90,12 @@ marks the same across runs.\n \tresulting stream can only be used by a repository which\n \talready contains the necessary objects.\n \n+--full-tree::\n+\tThis option will cause fast-export to issue a \"deleteall\"\n+\tdirective for each commit followed by a full list of all files\n+\tin the commit (as opposed to just listing the files which are\n+\tdifferent from the commit's first parent).\n+\n [git-rev-list-args...]::\n        A list of arguments, acceptable to 'git rev-parse' and\n        'git rev-list', that specifies the specific objects and references\ndiff --git a/builtin/fast-export.c b/builtin/fast-export.c\nindex 9fe25ff..fe7a61b 100644\n--- a/builtin/fast-export.c\n+++ b/builtin/fast-export.c\n@@ -26,6 +26,7 @@ static int progress;\n static enum { ABORT, VERBATIM, WARN, STRIP } signed_tag_mode = ABORT;\n static enum { ERROR, DROP, REWRITE } tag_of_filtered_mode = ABORT;\n static int fake_missing_tagger;\n+static int full_tree;\n static int no_data;\n \n static int parse_opt_signed_tag_mode(const struct option *opt,\n@@ -241,7 +242,8 @@ static void handle_commit(struct commit *commit, struct rev_info *rev)\n \t\tmessage += 2;\n \n \tif (commit->parents &&\n-\t    get_object_mark(&commit->parents->item->object) != 0) {\n+\t    get_object_mark(&commit->parents->item->object) != 0 &&\n+\t    !full_tree) {\n \t\tparse_commit(commit->parents->item);\n \t\tdiff_tree_sha1(commit->parents->item->tree->object.sha1,\n \t\t\t       commit->tree->object.sha1, \"\", &rev->diffopt);\n@@ -281,6 +283,8 @@ static void handle_commit(struct commit *commit, struct rev_info *rev)\n \t\ti++;\n \t}\n \n+\tif (full_tree)\n+\t\tprintf(\"deleteall\\n\");\n \tlog_tree_diff_flush(rev);\n \trev->diffopt.output_format = saved_output_format;\n \n@@ -584,6 +588,8 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix)\n \t\t\t     \"Import marks from this file\"),\n \t\tOPT_BOOLEAN(0, \"fake-missing-tagger\", &fake_missing_tagger,\n \t\t\t     \"Fake a tagger when tags lack one\"),\n+\t\tOPT_BOOLEAN(0, \"full-tree\", &full_tree,\n+\t\t\t     \"Output full tree for each commit\"),\n \t\t{ OPTION_NEGBIT, 0, \"data\", &no_data, NULL,\n \t\t\t\"Skip output of blob data\",\n \t\t\tPARSE_OPT_NOARG | PARSE_OPT_NEGHELP, NULL, 1 },\ndiff --git a/t/t9350-fast-export.sh b/t/t9350-fast-export.sh\nindex 1ee1461..05c79ea 100755\n--- a/t/t9350-fast-export.sh\n+++ b/t/t9350-fast-export.sh\n@@ -400,4 +400,39 @@ test_expect_success 'directory becomes symlink'        '\n \t(cd result && git show master:foo)\n '\n \n+cat >> dirtosymlink/expected << EOF\n+blob\n+mark :5\n+data 6\n+hello\n+\n+blob\n+mark :6\n+data 7\n+badlink\n+commit refs/heads/master\n+mark :7\n+author A U Thor <author@example.com> 1112912713 -0700\n+committer C O Mitter <committer@example.com> 1112912713 -0700\n+data 6\n+three\n+from :4\n+deleteall\n+M 100644 :5 bar/world\n+M 120000 :6 foo\n+\n+EOF\n+\n+test_expect_success 'full-tree'        '\n+\t(\n+\t\tcd dirtosymlink &&\n+\t\tgit fast-export --export-marks=marks master -- foo > output1 &&\n+\t\trm foo &&\n+\t\tln -s badlink foo &&\n+\t\tgit commit -mthree foo &&\n+\t\tgit fast-export --import-marks=marks --full-tree master -- foo bar > output &&\n+\t\ttest_cmp output expected\n+\t)\n+'\n+\n test_done\n-- \n1.7.2.rc0.212.g0c601\n"},{"id":"144459","messageId":"AANLkTinwiFgFBKu7JGaS9WEHGOhkW50iE4pmvXlA3y-W@mail.gmail.com","threadId":"24226","inReplyTo":"1277774525-12530-1-git-send-email-newren@gmail.com","subject":"Re: [PATCH] fast-export: Add a --full-tree option","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2010-06-29T13:02:02Z","receivedAt":"2010-06-29T13:02:02Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Mon, Jun 28, 2010 at 7:22 PM,  <newren@gmail.com> wrote:\n> From: Elijah Newren <newren@gmail.com>\n>\n> This option makes fast-export issue a 'deleteall' directive and then the\n> full set of files that make up each commit, rather than just showing the\n> list of files that have changed since the (first) parent commit.\n>\n> This is useful in at least two cases:\n\nI just noticed looking searching through older list emails that\nJohannes has apparently left git development\n(http://kerneltrap.org/mailarchive/git/2010/4/27/29263), is that\ncorrect?  If so, that's a big loss for the community.  :-(\n\nI guess that also means I need to cc someone else to review this.\nAccording to shortlog --no-merges, I'm the top committer to\nfast-export, followed by Johannes (though his patches were bigger and\nincluded the initial write of the file), followed by a string of 2-3\ncommit persons.  Hmmm....  Shawn: could you take a quick look?\n\nThanks,\nElijah\n"}]}