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 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 object. This option has no effect on the treatment of gitlink entries
(aka "submodules") which are always allowed to be missing. (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 Author
------ ------
Written by Junio C Hamano <gitster@pobox.com> 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[] = { 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]; unsigned char sha1[20];
int line_termination = '\n'; int line_termination = '\n';
int allow_missing = 0; int allow_missing = 0;
int is_batch_mode = 0;
int got_eof = 0;
const struct option option[] = { const struct option option[] = {
OPT_SET_INT('z', NULL, &line_termination, "input is NUL terminated", '\0'), 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 , "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() OPT_END()
}; };
ac = parse_options(ac, av, option, mktree_usage, 0); ac = parse_options(ac, av, option, mktree_usage, 0);
while (strbuf_getline(&sb, stdin, line_termination) != EOF) while (!got_eof) {
mktree_line(sb.buf, sb.len, line_termination, allow_missing); 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);
} }