mktree --batch: build more than one tree object
authorJosh Micich <josh.micich@gmail.com>
Thu, 14 May 2009 19:51:15 +0000 (12:51 -0700)
committerJunio C Hamano <gitster@pobox.com>
Sat, 16 May 2009 17:28:59 +0000 (10:28 -0700)
This option works in a similar way to the '--batch' option of 'git cat-file'.
It enables creation of many tree objects with a single process.

The change was motivated by performance considerations in applications that
need to create many tree objects. A non-rigorous test showed tree creation
times improved from (roughly) 200ms to 50ms.

Signed-off-by: Josh Micich <josh.micich@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/git-mktree.txt
builtin-mktree.c
index 7336f48bd1e90dabf8e735dc27023b65309e1aef..81e3326772d94464708cc2037715e1e62eae5f11 100644 (file)
@@ -8,7 +8,7 @@ git-mktree - Build a tree-object from ls-tree formatted text
 
 SYNOPSIS
 --------
 
 SYNOPSIS
 --------
-'git mktree' [-z] [--missing]
+'git mktree' [-z] [--missing] [--batch]
 
 DESCRIPTION
 -----------
 
 DESCRIPTION
 -----------
@@ -28,6 +28,12 @@ OPTIONS
        object.  This option has no effect on the treatment of gitlink entries
        (aka "submodules") which are always allowed to be missing.
 
        object.  This option has no effect on the treatment of gitlink entries
        (aka "submodules") which are always allowed to be missing.
 
+--batch::
+       Allow building of more than one tree object before exiting.  Each
+       tree is separated by as single blank line. The final new-line is
+       optional.  Note - if the '-z' option is used, lines are terminated
+       with NUL.
+
 Author
 ------
 Written by Junio C Hamano <gitster@pobox.com>
 Author
 ------
 Written by Junio C Hamano <gitster@pobox.com>
index 5ff04753b756a72c521d6a95321417812e90e865..73b0abbd8d9bb6d3b312c382b72f8a6e9d124cfa 100644 (file)
@@ -63,7 +63,7 @@ static void write_tree(unsigned char *sha1)
 }
 
 static const char *mktree_usage[] = {
 }
 
 static const char *mktree_usage[] = {
-       "git mktree [-z] [--missing]",
+       "git mktree [-z] [--missing] [--batch]",
        NULL
 };
 
        NULL
 };
 
@@ -122,20 +122,46 @@ int cmd_mktree(int ac, const char **av, const char *prefix)
        unsigned char sha1[20];
        int line_termination = '\n';
        int allow_missing = 0;
        unsigned char sha1[20];
        int line_termination = '\n';
        int allow_missing = 0;
+       int is_batch_mode = 0;
+       int got_eof = 0;
+
        const struct option option[] = {
                OPT_SET_INT('z', NULL, &line_termination, "input is NUL terminated", '\0'),
                OPT_SET_INT( 0 , "missing", &allow_missing, "allow missing objects", 1),
        const struct option option[] = {
                OPT_SET_INT('z', NULL, &line_termination, "input is NUL terminated", '\0'),
                OPT_SET_INT( 0 , "missing", &allow_missing, "allow missing objects", 1),
+               OPT_SET_INT( 0 , "batch", &is_batch_mode, "allow creation of more than one tree", 1),
                OPT_END()
        };
 
        ac = parse_options(ac, av, option, mktree_usage, 0);
 
                OPT_END()
        };
 
        ac = parse_options(ac, av, option, mktree_usage, 0);
 
-       while (strbuf_getline(&sb, stdin, line_termination) != EOF)
-               mktree_line(sb.buf, sb.len, line_termination, allow_missing);
-
+       while (!got_eof) {
+               while (1) {
+                       if (strbuf_getline(&sb, stdin, line_termination) == EOF) {
+                               got_eof = 1;
+                               break;
+                       }
+                       if (sb.buf[0] == '\0') {
+                               /* empty lines denote tree boundaries in batch mode */
+                               if (is_batch_mode)
+                                       break;
+                               die("input format error: (blank line only valid in batch mode)");
+                       }
+                       mktree_line(sb.buf, sb.len, line_termination, allow_missing);
+               }
+               if (is_batch_mode && got_eof && used < 1) {
+                       /*
+                        * Execution gets here if the last tree entry is terminated with a
+                        * new-line.  The final new-line has been made optional to be
+                        * consistent with the original non-batch behaviour of mktree.
+                        */
+                       ; /* skip creating an empty tree */
+               } else {
+                       write_tree(sha1);
+                       puts(sha1_to_hex(sha1));
+                       fflush(stdout);
+               }
+               used=0; /* reset tree entry buffer for re-use in batch mode */
+       }
        strbuf_release(&sb);
        strbuf_release(&sb);
-
-       write_tree(sha1);
-       puts(sha1_to_hex(sha1));
        exit(0);
 }
        exit(0);
 }