Hi, On Wed, 5 Sep 2007, Kristian Høgsberg wrote: > contrib/examples/git-commit.sh | 665 +++++++++++++++++++++++++++++++++++ > git-commit.sh | 665 ----------------------------------- You might want to use "git format-patch -M" next time ;-) > @@ -357,7 +358,6 @@ BUILTIN_OBJS = \ > builtin-rev-parse.o \ > builtin-revert.o \ > builtin-rm.o \ > - builtin-runstatus.o \ Better keep it; some people's scripts could depend on it. > +struct option { > + enum option_type type; > + const char *long_name; > + char short_name; > + void *value; > +}; > + > +static int scan_options(const char ***argv, struct option *options) > +{ I would not (no longer, anyway) be opposed to replacing the option parsing in git with getopt(); I hear that it is small enough to keep a copy in compat/getopt.c. But let's go forward with builtin-commit; getopt() can come later. > +static char * > +prepare_index(const char **files, const char *prefix) > +{ > + int fd; > + struct tree *tree; > + struct lock_file *next_index_lock; > + > + fd = hold_locked_index(&lock_file, 1); > + if (read_cache() < 0) > + die("index file corrupt"); > + > + if (all) { > + add_files_to_cache(fd, files, NULL); > + return lock_file.filename; > + } else if (also) { > + add_files_to_cache(fd, files, prefix); > + return lock_file.filename; > + } > + > + if (interactive) > + interactive_add(); > + > + if (*files == NULL) { > + /* Commit index as-is. */ > + rollback_lock_file(&lock_file); > + return get_index_file(); > + } > + > + /* > + * FIXME: Warn on unknown files. Shell script does > + * > + * commit_only=`git-ls-files --error-unmatch -- "$@"` > + */ > + > + /* > + * FIXME: shell script does > + * > + * git-read-tree --index-output="$TMP_INDEX" -i -m HEAD > + * > + * which warns about unmerged files in the index. > + */ > + > + /* update the user index file */ > + add_files_to_cache(fd, files, prefix); I suspect this, or ... > + > + if (!initial_commit) { > + tree = parse_tree_indirect(head_sha1); > + if (!tree) > + die("failed to unpack HEAD tree object"); > + if (read_tree(tree, 0, NULL)) > + die("failed to read HEAD tree object"); > + } > + > + /* Uh oh, abusing lock_file to create a garbage collected file */ > + next_index_lock = xmalloc(sizeof(*next_index_lock)); > + fd = hold_lock_file_for_update(next_index_lock, > + git_path("next-index-%d", getpid()), 1); > + add_files_to_cache(fd, files, prefix); ... this, but not both. > +/* Find out if the message starting at position 'start' in the strbuf > + * contains only whitespace and Signed-off-by lines. */ > +static int message_is_empty(struct strbuf *sb, int start) > +{ > + static const char signed_off_by[] = "Signed-off-by: "; I think you already defined that globally earlier. In the function message_is_empty() you write: > + /* See if the template is just a prefix of the message. */ > + strbuf_init(&tmpl); > + if (template_file && strbuf_read_path(&tmpl, template_file) > 0) { > + stripspace(&tmpl, 1); > + if (start + tmpl.len <= sb->len && > + memcmp(tmpl.buf, sb->buf + start, tmpl.len) == 0) > + start += tmpl.len; Could we not bail out here, if there is no match? In that case, the message is clearly not empty... > + /* Check if the rest is just whitespace and Signed-of-by's. */ > + for (i = start; i < sb->len; i++) { > + nl = memchr(sb->buf + i, '\n', sb->len - i); > + if (nl) > + eol = nl - sb->buf; > + else > + eol = sb->len; Why not just "if (isspace(sb->buf[i]) || sb->buf[i] == '\n') continue;"? This would also catch the cases where people indent their S-O-Bs. > + > + if (strlen(signed_off_by) <= eol - i && > + !prefixcmp(sb->buf + i, signed_off_by)) { > + i = eol; > + continue; > + } > + while (i < eol) > + if (!isspace(sb->buf[i++])) > + return 0; > + } > + > + return 1; > +} I did not review the rest of the code closely yet... All in all: well done! Ciao, Dscho