commit - 52ab795804a3c40a55a009fd869496a305611276
commit + dbec59df9a61e9cea9251851a5c649ab8981e91b
blob - 39ad76b02f24d006741407cf89f9df33a179c54b
blob + f0afe089450e16d23c8021535652e8be9cc16f0a
--- got/got.1
+++ got/got.1
.It Cm st
Short alias for
.Cm status .
-.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 s Ar search-pattern Oc Oo Fl r Ar repository-path Oc Oo Fl x Ar commit Oc Op Ar path
+.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 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
If this directory is a
.Nm
work tree, use the repository path associated with this work tree.
+.It Fl R
+Determine a set of commits to display as usual, but display these commits
+in reverse order.
.It Fl x Ar commit
Stop traversing commit history as soon as the specified
.Ar commit
blob - a6905d4ca6eaa4217742da3a792e0337f1bc62d4
blob + 7163d538700ed481c6a158c6820bc7c4b7e8eaa6
--- got/got.c
+++ got/got.c
print_commits(struct got_object_id *root_id, struct got_object_id *end_id,
struct got_repository *repo, const char *path, int show_patch,
const char *search_pattern, int diff_context, int limit, int log_branches,
- struct got_reflist_head *refs)
+ int reverse_display_order, struct got_reflist_head *refs)
{
const struct got_error *err;
struct got_commit_graph *graph;
regex_t regex;
int have_match;
+ struct got_object_id_queue reversed_commits;
+ struct got_object_qid *qid;
+ struct got_commit_object *commit;
+
+ SIMPLEQ_INIT(&reversed_commits);
if (search_pattern && regcomp(®ex, search_pattern,
REG_EXTENDED | REG_NOSUB | REG_NEWLINE))
if (err)
goto done;
for (;;) {
- struct got_commit_object *commit;
struct got_object_id *id;
if (sigint_received || sigpipe_received)
}
}
- err = print_commit(commit, id, repo, path, show_patch,
- diff_context, refs);
- got_object_commit_close(commit);
- if (err || (limit && --limit == 0) ||
- (end_id != NULL && got_object_id_cmp(id, end_id) == 0))
+ if (reverse_display_order) {
+ err = got_object_qid_alloc(&qid, id);
+ if (err)
+ break;
+ SIMPLEQ_INSERT_HEAD(&reversed_commits, qid, entry);
+ got_object_commit_close(commit);
+ } else {
+ err = print_commit(commit, id, repo, path, show_patch,
+ diff_context, refs);
+ got_object_commit_close(commit);
+ if (err)
+ break;
+ }
+ if ((limit && --limit == 0) ||
+ (end_id && got_object_id_cmp(id, end_id) == 0))
break;
}
+ if (reverse_display_order) {
+ SIMPLEQ_FOREACH(qid, &reversed_commits, entry) {
+ err = got_object_open_as_commit(&commit, repo, qid->id);
+ if (err)
+ break;
+ err = print_commit(commit, qid->id, repo, path,
+ show_patch, diff_context, refs);
+ got_object_commit_close(commit);
+ if (err)
+ break;
+ }
+ }
done:
+ while (!SIMPLEQ_EMPTY(&reversed_commits)) {
+ qid = SIMPLEQ_FIRST(&reversed_commits);
+ SIMPLEQ_REMOVE_HEAD(&reversed_commits, entry);
+ got_object_qid_free(qid);
+ }
if (search_pattern)
regfree(®ex);
got_commit_graph_close(graph);
usage_log(void)
{
fprintf(stderr, "usage: %s log [-b] [-c commit] [-C number] [ -l N ] "
- "[-p] [-x commit] [-s search-pattern] [-r repository-path] "
+ "[-p] [-x commit] [-s search-pattern] [-r repository-path] [-R] "
"[path]\n", getprogname());
exit(1);
}
const char *search_pattern = NULL;
int diff_context = -1, ch;
int show_patch = 0, limit = 0, log_branches = 0;
+ int reverse_display_order = 0;
const char *errstr;
struct got_reflist_head refs;
limit = get_default_log_limit();
- while ((ch = getopt(argc, argv, "bpc:C:l:r:s:x:")) != -1) {
+ while ((ch = getopt(argc, argv, "bpc:C:l:r:Rs:x:")) != -1) {
switch (ch) {
case 'p':
show_patch = 1;
optarg);
got_path_strip_trailing_slashes(repo_path);
break;
+ case 'R':
+ reverse_display_order = 1;
+ break;
case 's':
search_pattern = optarg;
break;
goto done;
error = print_commits(start_id, end_id, repo, path, show_patch,
- search_pattern, diff_context, limit, log_branches, &refs);
+ search_pattern, diff_context, limit, log_branches,
+ reverse_display_order, &refs);
done:
free(path);
free(repo_path);
blob - 3f4c9bd9cc92924eee23f9724c484d587cab4334
blob + 6bde801a304c1c49f7f91d334825b18215ee684e
--- regress/cmdline/log.sh
+++ regress/cmdline/log.sh
test_done "$testroot" "0"
}
+
+function test_log_reverse_display {
+ local testroot=`test_init log_reverse_display`
+ local commit_id0=`git_show_head $testroot/repo`
+
+ got checkout $testroot/repo $testroot/wt > /dev/null
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ echo "modified alpha" > $testroot/wt/alpha
+ (cd $testroot/wt && got commit -m 'commit1' > /dev/null)
+ local commit_id1=`git_show_head $testroot/repo`
+
+ (cd $testroot/wt && got rm beta >/dev/null)
+ (cd $testroot/wt && got commit -m 'commit2' > /dev/null)
+ local commit_id2=`git_show_head $testroot/repo`
+
+ echo "new file" > $testroot/wt/new
+ (cd $testroot/wt && got add new >/dev/null)
+ (cd $testroot/wt && got commit -m 'commit3' > /dev/null)
+ local commit_id3=`git_show_head $testroot/repo`
+ # -R alone should display all commits in reverse
+ echo "commit $commit_id0" > $testroot/stdout.expected
+ echo "commit $commit_id1" >> $testroot/stdout.expected
+ echo "commit $commit_id2" >> $testroot/stdout.expected
+ echo "commit $commit_id3 (master)" >> $testroot/stdout.expected
+ (cd $testroot/wt && got log -R | grep ^commit > $testroot/stdout)
+ cmp -s $testroot/stdout.expected $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ # -R takes effect after the -l commit traversal limit
+ echo "commit $commit_id2" > $testroot/stdout.expected
+ echo "commit $commit_id3 (master)" >> $testroot/stdout.expected
+ (cd $testroot/wt && got log -R -l2 | grep ^commit > $testroot/stdout)
+ cmp -s $testroot/stdout.expected $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ test_done "$testroot" "$ret"
+ return 1
+ fi
+
+ # -R works with commit ranges specified via -c and -x
+ echo "commit $commit_id1" > $testroot/stdout.expected
+ echo "commit $commit_id2" >> $testroot/stdout.expected
+ echo "commit $commit_id3 (master)" >> $testroot/stdout.expected
+ (cd $testroot/wt && got log -R -c $commit_id3 -x $commit_id1 | \
+ grep ^commit > $testroot/stdout)
+ cmp -s $testroot/stdout.expected $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ test_done "$testroot" "$ret"
+ fi
+
+ # commit matching with -s applies before -R
+ echo "commit $commit_id1" > $testroot/stdout.expected
+ echo "commit $commit_id2" >> $testroot/stdout.expected
+ (cd $testroot/wt && got log -R -s 'commit[12]' | \
+ grep ^commit > $testroot/stdout)
+ cmp -s $testroot/stdout.expected $testroot/stdout
+ ret="$?"
+ if [ "$ret" != "0" ]; then
+ diff -u $testroot/stdout.expected $testroot/stdout
+ fi
+ test_done "$testroot" "$ret"
+}
+
run_test test_log_in_repo
run_test test_log_in_bare_repo
run_test test_log_in_worktree
run_test test_log_limit
run_test test_log_nonexistent_path
run_test test_log_end_at_commit
+run_test test_log_reverse_display