mktree --batch: build more than one tree object

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>
This commit is contained in:
Josh Micich 2009-05-14 12:51:15 -07:00 committed by Junio C Hamano
parent e01662bb5d
commit f1cf2d8b14
2 changed files with 40 additions and 8 deletions

View file

@ -8,7 +8,7 @@ git-mktree - Build a tree-object from ls-tree formatted text
SYNOPSIS
--------
'git mktree' [-z] [--missing]
'git mktree' [-z] [--missing] [--batch]
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.
--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>

View file

@ -63,7 +63,7 @@ static void write_tree(unsigned char *sha1)
}
static const char *mktree_usage[] = {
"git mktree [-z] [--missing]",
"git mktree [-z] [--missing] [--batch]",
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;
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),
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);
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);
write_tree(sha1);
puts(sha1_to_hex(sha1));
exit(0);
}