From 97fc71ab3b935df5f32faae13035e40eeb03c07f Mon Sep 17 00:00:00 2001 From: Eoin Coffey Date: Thu, 22 May 2014 16:01:45 -0600 Subject: [PATCH 1/5] Add support for --author flag in example log implementation --- examples/log.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/examples/log.c b/examples/log.c index 471c5ff96..655b95d10 100644 --- a/examples/log.c +++ b/examples/log.c @@ -54,7 +54,7 @@ struct log_options { int min_parents, max_parents; git_time_t before; git_time_t after; - char *author; + const char *author; char *committer; }; @@ -75,6 +75,7 @@ int main(int argc, char *argv[]) git_oid oid; git_commit *commit = NULL; git_pathspec *ps = NULL; + const git_signature *sig; git_threads_init(); @@ -128,6 +129,12 @@ int main(int argc, char *argv[]) continue; } + if (opt.author != NULL) { + if ((sig = git_commit_author(commit)) == NULL || + strstr(sig->name, opt.author) == NULL) + continue; + } + if (count++ < opt.skip) continue; if (opt.limit != -1 && printed++ >= opt.limit) { @@ -401,6 +408,8 @@ static int parse_options( set_sorting(s, GIT_SORT_TOPOLOGICAL); else if (!strcmp(a, "--reverse")) set_sorting(s, GIT_SORT_REVERSE); + else if (match_str_arg(&opt->author, &args, "--author")) + /** Found valid --author */; else if (match_str_arg(&s->repodir, &args, "--git-dir")) /** Found git-dir. */; else if (match_int_arg(&opt->skip, &args, "--skip", 0)) From 161e6dc1cacb724543c81ee0a62ed28742a81190 Mon Sep 17 00:00:00 2001 From: Eoin Coffey Date: Fri, 23 May 2014 12:27:16 -0600 Subject: [PATCH 2/5] Add --committer option, and break out helper function --- examples/log.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/examples/log.c b/examples/log.c index 655b95d10..5a43f632a 100644 --- a/examples/log.c +++ b/examples/log.c @@ -44,6 +44,7 @@ struct log_state { /** utility functions that are called to configure the walker */ static void set_sorting(struct log_state *s, unsigned int sort_mode); +static int signature_does_not_match(const git_signature *sig, const char *filter); static void push_rev(struct log_state *s, git_object *obj, int hide); static int add_revision(struct log_state *s, const char *revstr); @@ -55,7 +56,7 @@ struct log_options { git_time_t before; git_time_t after; const char *author; - char *committer; + const char *committer; }; /** utility functions that parse options and help with log output */ @@ -75,7 +76,6 @@ int main(int argc, char *argv[]) git_oid oid; git_commit *commit = NULL; git_pathspec *ps = NULL; - const git_signature *sig; git_threads_init(); @@ -129,11 +129,11 @@ int main(int argc, char *argv[]) continue; } - if (opt.author != NULL) { - if ((sig = git_commit_author(commit)) == NULL || - strstr(sig->name, opt.author) == NULL) - continue; - } + if (signature_does_not_match(git_commit_author(commit), opt.author)) + continue; + + if (signature_does_not_match(git_commit_committer(commit), opt.committer)) + continue; if (count++ < opt.skip) continue; @@ -179,6 +179,18 @@ int main(int argc, char *argv[]) return 0; } +/** Determine if the given git_signature does not contain the filter text. */ +static int signature_does_not_match(const git_signature *sig, const char *filter) { + if (filter == NULL) + return 0; + + if (sig == NULL || + (strstr(sig->name, filter) == NULL && + strstr(sig->email, filter) == NULL)) + return 1; + return 0; +} + /** Push object (for hide or show) onto revwalker. */ static void push_rev(struct log_state *s, git_object *obj, int hide) { @@ -410,6 +422,8 @@ static int parse_options( set_sorting(s, GIT_SORT_REVERSE); else if (match_str_arg(&opt->author, &args, "--author")) /** Found valid --author */; + else if (match_str_arg(&opt->committer, &args, "--committer")) + /** Found valid --committer */; else if (match_str_arg(&s->repodir, &args, "--git-dir")) /** Found git-dir. */; else if (match_int_arg(&opt->skip, &args, "--skip", 0)) From 26cce32133363133b479cfd811523270db851466 Mon Sep 17 00:00:00 2001 From: Eoin Coffey Date: Fri, 23 May 2014 12:59:19 -0600 Subject: [PATCH 3/5] Add support for --grep --- examples/log.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/examples/log.c b/examples/log.c index 5a43f632a..965f854d7 100644 --- a/examples/log.c +++ b/examples/log.c @@ -44,7 +44,6 @@ struct log_state { /** utility functions that are called to configure the walker */ static void set_sorting(struct log_state *s, unsigned int sort_mode); -static int signature_does_not_match(const git_signature *sig, const char *filter); static void push_rev(struct log_state *s, git_object *obj, int hide); static int add_revision(struct log_state *s, const char *revstr); @@ -57,6 +56,7 @@ struct log_options { git_time_t after; const char *author; const char *committer; + const char *grep; }; /** utility functions that parse options and help with log output */ @@ -66,6 +66,9 @@ static void print_time(const git_time *intime, const char *prefix); static void print_commit(git_commit *commit); static int match_with_parent(git_commit *commit, int i, git_diff_options *); +/** utility functions for filtering */ +static int signature_does_not_match(const git_signature *sig, const char *filter); +static int log_message_does_not_match(const git_commit *commit, const char *filter); int main(int argc, char *argv[]) { @@ -135,6 +138,9 @@ int main(int argc, char *argv[]) if (signature_does_not_match(git_commit_committer(commit), opt.committer)) continue; + if (log_message_does_not_match(commit, opt.grep)) + continue; + if (count++ < opt.skip) continue; if (opt.limit != -1 && printed++ >= opt.limit) { @@ -188,6 +194,20 @@ static int signature_does_not_match(const git_signature *sig, const char *filter (strstr(sig->name, filter) == NULL && strstr(sig->email, filter) == NULL)) return 1; + + return 0; +} + +static int log_message_does_not_match(const git_commit *commit, const char *filter) { + const char *message = NULL; + + if (filter == NULL) + return 0; + + if ((message = git_commit_message(commit)) == NULL || + strstr(message, filter) == NULL) + return 1; + return 0; } @@ -424,6 +444,8 @@ static int parse_options( /** Found valid --author */; else if (match_str_arg(&opt->committer, &args, "--committer")) /** Found valid --committer */; + else if (match_str_arg(&opt->grep, &args, "--grep")) + /** Found valid --grep */; else if (match_str_arg(&s->repodir, &args, "--git-dir")) /** Found git-dir. */; else if (match_int_arg(&opt->skip, &args, "--skip", 0)) From 87493bca9c5c14f99adea5ceadf6caa8005a6ada Mon Sep 17 00:00:00 2001 From: Eoin Coffey Date: Fri, 23 May 2014 13:00:30 -0600 Subject: [PATCH 4/5] Remove simple --author, --committer, and --grep from PROJECTS --- PROJECTS.md | 6 ------ 1 file changed, 6 deletions(-) diff --git a/PROJECTS.md b/PROJECTS.md index 9472fb43c..d17214471 100644 --- a/PROJECTS.md +++ b/PROJECTS.md @@ -39,12 +39,6 @@ These are good small projects to get started with libgit2. the data is available, you would just need to add the code into the `print_commit()` routine (along with a way of passing the option into that function). - * For `examples/log.c`, implement any one of `--author=<...>`, - `--committer=<...>`, or `--grep=<...>` but just use simple string - match with `strstr()` instead of full regular expression - matching. (I.e. I'm suggesting implementing this as if - `--fixed-strings` was always turned on, because it will be a simpler - project.) * As an extension to the matching idea for `examples/log.c`, add the `-i` option to use `strcasestr()` for matches. * For `examples/log.c`, implement the `--first-parent` option now that From 33bf1b1ab0e14453e67e94dc6aa679dcdcce56e8 Mon Sep 17 00:00:00 2001 From: Eoin Coffey Date: Wed, 28 May 2014 09:40:08 -0600 Subject: [PATCH 5/5] examples/log.c: invert filtering impl and conditional --- examples/log.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/examples/log.c b/examples/log.c index 965f854d7..d5f75a297 100644 --- a/examples/log.c +++ b/examples/log.c @@ -67,8 +67,8 @@ static void print_commit(git_commit *commit); static int match_with_parent(git_commit *commit, int i, git_diff_options *); /** utility functions for filtering */ -static int signature_does_not_match(const git_signature *sig, const char *filter); -static int log_message_does_not_match(const git_commit *commit, const char *filter); +static int signature_matches(const git_signature *sig, const char *filter); +static int log_message_matches(const git_commit *commit, const char *filter); int main(int argc, char *argv[]) { @@ -132,13 +132,13 @@ int main(int argc, char *argv[]) continue; } - if (signature_does_not_match(git_commit_author(commit), opt.author)) + if (!signature_matches(git_commit_author(commit), opt.author)) continue; - if (signature_does_not_match(git_commit_committer(commit), opt.committer)) + if (!signature_matches(git_commit_committer(commit), opt.committer)) continue; - if (log_message_does_not_match(commit, opt.grep)) + if (!log_message_matches(commit, opt.grep)) continue; if (count++ < opt.skip) @@ -186,26 +186,26 @@ int main(int argc, char *argv[]) } /** Determine if the given git_signature does not contain the filter text. */ -static int signature_does_not_match(const git_signature *sig, const char *filter) { +static int signature_matches(const git_signature *sig, const char *filter) { if (filter == NULL) - return 0; + return 1; - if (sig == NULL || - (strstr(sig->name, filter) == NULL && - strstr(sig->email, filter) == NULL)) + if (sig != NULL && + (strstr(sig->name, filter) != NULL || + strstr(sig->email, filter) != NULL)) return 1; return 0; } -static int log_message_does_not_match(const git_commit *commit, const char *filter) { +static int log_message_matches(const git_commit *commit, const char *filter) { const char *message = NULL; if (filter == NULL) - return 0; + return 1; - if ((message = git_commit_message(commit)) == NULL || - strstr(message, filter) == NULL) + if ((message = git_commit_message(commit)) != NULL && + strstr(message, filter) != NULL) return 1; return 0;