From: Evan Silberman Subject: [patch] add a one-line-per-commit output mode to log To: gameoftrees@openbsd.org Date: Mon, 16 May 2022 22:40:35 -0700 I do git log --oneline reasonably often and it seemed like exactly the sort of thing I could take a stab at a patch for without having to do much other than harvest parts of other functions, and so it was. There's probably something wrong with this given it may be the most C I've ever written at once. And also the choice of -1 as the flag was too cute to resist proposing but also probably too cute to actually use. Happy to make revisions as requested. Regards, Evan ----------------------------------------------- commit ec3c42a13c09c6f725a351cde60673147397916c (log-oneline) from: Evan Silberman date: Tue May 17 05:33:00 2022 UTC Add a one-line-per-commit output mode to log Like git log --oneline. diff af2c4eff8bee6f826f378d225850e0d5bcc07140 18e0ebfa9101f1b666c4d4f7bb3114fb567f444a blob - b91cfb2cb4963721a9a86be9c2cdb397bc1a9278 blob + 9619c317dd8555751636ef0beec4cb916c71b390 --- got/got.1 +++ got/got.1 @@ -756,7 +756,7 @@ does not support negated ignore patterns prefixed with and gives no special significance to the location of path component separators, .Dq / , in a pattern. -.It Cm log Oo Fl b Oc Oo Fl c Ar commit Oc Oo Fl C Ar number Oc Oo Fl l Ar N Oc Oo Fl p Oc Oo Fl P Oc Oo Fl s Ar search-pattern Oc Oo Fl r Ar repository-path Oc Oo Fl R Oc Oo Fl x Ar commit Oc Op Ar path +.It Cm log Oo Fl 1 Oc Oo Fl b Oc Oo Fl c Ar commit Oc Oo Fl C Ar number Oc Oo Fl l Ar N Oc Oo Fl p Oc Oo Fl P Oc Oo Fl s Ar search-pattern Oc Oo Fl r Ar repository-path Oc Oo Fl R Oc Oo Fl x Ar commit Oc Op Ar path Display history of a repository. If a .Ar path @@ -771,6 +771,16 @@ The options for .Cm got log are as follows: .Bl -tag -width Ds +.It Fl 1 +Display a compact one-line summary of each commit, instead of the default +history format. +The one-line format prints the first seven characters of the SHA1 hash of each +commit, followed by a space and the first line of the log message. +The +.Fl p +and +.Fl P +options are ignored. .It Fl b Display individual commits which were merged into the current branch from other branches. blob - 80e5d2fbcd031246f1194edf450fa9da6e1a2901 blob + 90c0a6cee6568859b0ceeee1666b933671e529e8 --- got/got.c +++ got/got.c @@ -3809,6 +3809,45 @@ build_refs_str(char **refs_str, struct got_reflist_hea } static const struct got_error * +print_commit_oneline(struct got_commit_object *commit, struct got_object_id *id) +{ + const struct got_error *err = NULL; + char *id_str, *s, *nl, *logmsg0, *logmsg = NULL; + + err = got_object_id_str(&id_str, id); + if (err) + return err; + + err = got_object_commit_get_logmsg(&logmsg0, commit); + if (err) + goto done; + + s = logmsg0; + while (isspace((unsigned char)s[0])) + s++; + + logmsg = strdup(s); + if (logmsg == NULL) { + err = got_error_from_errno("strdup"); + goto done; + } + + nl = strchr(logmsg, '\n'); + if (nl) { + *nl = '\0'; + } + + printf("%.7s %s\n", id_str, logmsg); + + if (fflush(stdout) != 0 && err == NULL) + err = got_error_from_errno("fflush"); +done: + free(id_str); + free(logmsg0); + return err; +} + +static const struct got_error * print_commit(struct got_commit_object *commit, struct got_object_id *id, struct got_repository *repo, const char *path, struct got_pathlist_head *changed_paths, int show_patch, @@ -3909,7 +3948,7 @@ print_commits(struct got_object_id *root_id, struct go struct got_repository *repo, const char *path, int show_changed_paths, int show_patch, const char *search_pattern, int diff_context, int limit, int log_branches, int reverse_display_order, - struct got_reflist_object_id_map *refs_idmap) + struct got_reflist_object_id_map *refs_idmap, int one_line) { const struct got_error *err; struct got_commit_graph *graph; @@ -3988,9 +4027,12 @@ print_commits(struct got_object_id *root_id, struct go STAILQ_INSERT_HEAD(&reversed_commits, qid, entry); got_object_commit_close(commit); } else { - err = print_commit(commit, id, repo, path, - show_changed_paths ? &changed_paths : NULL, - show_patch, diff_context, refs_idmap, NULL); + if (one_line) + err = print_commit_oneline(commit, id); + else + err = print_commit(commit, id, repo, path, + show_changed_paths ? &changed_paths : NULL, + show_patch, diff_context, refs_idmap, NULL); got_object_commit_close(commit); if (err) break; @@ -4017,9 +4059,12 @@ print_commits(struct got_object_id *root_id, struct go if (err) break; } - err = print_commit(commit, &qid->id, repo, path, - show_changed_paths ? &changed_paths : NULL, - show_patch, diff_context, refs_idmap, NULL); + if (one_line) + err = print_commit_oneline(commit, &qid->id); + else + err = print_commit(commit, &qid->id, repo, path, + show_changed_paths ? &changed_paths : NULL, + show_patch, diff_context, refs_idmap, NULL); got_object_commit_close(commit); if (err) break; @@ -4050,9 +4095,9 @@ done: __dead static void usage_log(void) { - fprintf(stderr, "usage: %s log [-b] [-c commit] [-C number] [ -l N ] " - "[-p] [-P] [-x commit] [-s search-pattern] [-r repository-path] " - "[-R] [path]\n", getprogname()); + fprintf(stderr, "usage: %s log [-1] [-b] [-c commit] [-C number] " + "[ -l N ] [-p] [-P] [-x commit] [-s search-pattern] " + "[-r repository-path] [-R] [path]\n", getprogname()); exit(1); } @@ -4084,7 +4129,7 @@ cmd_log(int argc, char *argv[]) const char *search_pattern = NULL; int diff_context = -1, ch; int show_changed_paths = 0, show_patch = 0, limit = 0, log_branches = 0; - int reverse_display_order = 0; + int reverse_display_order = 0, one_line = 0; const char *errstr; struct got_reflist_head refs; struct got_reflist_object_id_map *refs_idmap = NULL; @@ -4100,8 +4145,11 @@ cmd_log(int argc, char *argv[]) limit = get_default_log_limit(); - while ((ch = getopt(argc, argv, "bpPc:C:l:r:Rs:x:")) != -1) { + while ((ch = getopt(argc, argv, "1bpPc:C:l:r:Rs:x:")) != -1) { switch (ch) { + case '1': + one_line = 1; + break; case 'p': show_patch = 1; break; @@ -4275,7 +4323,7 @@ cmd_log(int argc, char *argv[]) error = print_commits(start_id, end_id, repo, path ? path : "", show_changed_paths, show_patch, search_pattern, diff_context, - limit, log_branches, reverse_display_order, refs_idmap); + limit, log_branches, reverse_display_order, refs_idmap, one_line); done: free(path); free(repo_path); blob - f13bd9029079658e7f658b35c11dc4ca7a6f70f7 blob + c27437508475e1f8235a04a0b8c5bacec5ed47e7 --- regress/cmdline/log.sh +++ regress/cmdline/log.sh @@ -297,6 +297,40 @@ test_log_limit() { test_done "$testroot" "0" } +test_log_oneline() { + local testroot=`test_init log_oneline` + local commit_id0=`git_show_head $testroot/repo` + got checkout $testroot/repo $testroot/wt > /dev/null + ret=$? + if [ $ret -ne 0 ]; then + test_done "$testroot" "$ret" + return 1 + fi + + echo "modified alpha" > $testroot/wt/alpha + (cd $testroot/wt && got commit -m "test oneline +no" > /dev/null) + local commit_id1=`git_show_head $testroot/repo` + + echo "modified beta" > $testroot/wt/beta + (cd $testroot/wt && got commit -m " test oneline +no" > /dev/null) + local commit_id2=`git_show_head $testroot/repo` + + printf "%.7s test oneline\n" $commit_id2 > $testroot/stdout.expected + printf "%.7s test oneline\n" $commit_id1 >> $testroot/stdout.expected + + (cd $testroot/repo && got log -1 | head -n 2 > $testroot/stdout) + cmp -s $testroot/stdout.expected $testroot/stdout + ret=$? + if [ $ret -ne 0 ]; then + diff -u $testroot/stdout.expected $testroot/stdout + test_done "$testroot" "$ret" + return 1 + fi + test_done "$testroot" "0" +} + test_log_patch_added_file() { local testroot=`test_init log_patch_added_file` local commit_id0=`git_show_head $testroot/repo` @@ -815,6 +849,7 @@ run_test test_log_in_worktree run_test test_log_in_worktree_with_path_prefix run_test test_log_tag run_test test_log_limit +run_test test_log_oneline run_test test_log_patch_added_file run_test test_log_nonexistent_path run_test test_log_end_at_commit