Commit b1ebc001df71bed2afcac6b0037bea21a988e1a7

Stefan Sperling 2019-08-13T23:54:01

add GOT_LOG_DEFAULT_LIMIT env var for setting a got log -l default

diff --git a/got/got.1 b/got/got.1
index 5051557..73aea3c 100644
--- a/got/got.1
+++ b/got/got.1
@@ -314,6 +314,11 @@ Merge commits which affected the current branch will be shown but
 individual commits which originated on other branches will be omitted.
 .It Fl l Ar N
 Limit history traversal to a given number of commits.
+If this option is not specified, a default limit value of zero is used,
+which is treated as an unbounded limit.
+The
+.Ev GOT_LOG_DEFAULT_LIMIT
+environment variable may be set to change this default value.
 .It Fl p
 Display the patch of modifications made in each commit.
 .It Fl r Ar repository-path
@@ -1099,6 +1104,11 @@ environment variables with a missing email address.
 .It Ev VISUAL , EDITOR
 The editor spawned by
 .Cm got commit .
+.It Ev GOT_LOG_DEFAULT_LIMIT
+The default limit on the number of commits traversed by
+.Cm got log .
+If set to zero, the limit is unbounded.
+This variable will be silently ignored if it is set to a non-numeric value.
 .El
 .Sh EXIT STATUS
 .Ex -std got
diff --git a/got/got.c b/got/got.c
index 0ebd0d6..5bac0ad 100644
--- a/got/got.c
+++ b/got/got.c
@@ -1551,6 +1551,22 @@ usage_log(void)
 	exit(1);
 }
 
+static int
+get_default_log_limit(void)
+{
+	const char *got_default_log_limit;
+	long long n;
+	const char *errstr;
+
+	got_default_log_limit = getenv("GOT_LOG_DEFAULT_LIMIT");
+	if (got_default_log_limit == NULL)
+		return 0;
+	n = strtonum(got_default_log_limit, 0, INT_MAX, &errstr);
+	if (errstr != NULL)
+		return 0;
+	return n;
+}
+
 static const struct got_error *
 cmd_log(int argc, char *argv[])
 {
@@ -1575,6 +1591,8 @@ cmd_log(int argc, char *argv[])
 		err(1, "pledge");
 #endif
 
+	limit = get_default_log_limit();
+
 	while ((ch = getopt(argc, argv, "b:pc:C:l:fr:")) != -1) {
 		switch (ch) {
 		case 'p':
@@ -1590,7 +1608,7 @@ cmd_log(int argc, char *argv[])
 				err(1, "-C option %s", errstr);
 			break;
 		case 'l':
-			limit = strtonum(optarg, 1, INT_MAX, &errstr);
+			limit = strtonum(optarg, 0, INT_MAX, &errstr);
 			if (errstr != NULL)
 				err(1, "-l option %s", errstr);
 			break;
diff --git a/regress/cmdline/common.sh b/regress/cmdline/common.sh
index e4dc12d..7554600 100644
--- a/regress/cmdline/common.sh
+++ b/regress/cmdline/common.sh
@@ -15,6 +15,7 @@
 # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 export GOT_AUTHOR="Flan Hacker <flan_hacker@openbsd.org>"
+export GOT_LOG_DEFAULT_LIMIT=0
 
 export MALLOC_OPTIONS=S
 
diff --git a/regress/cmdline/log.sh b/regress/cmdline/log.sh
index 470a29d..bfe52f0 100755
--- a/regress/cmdline/log.sh
+++ b/regress/cmdline/log.sh
@@ -151,8 +151,86 @@ function test_log_tag {
 	test_done "$testroot" "$ret"
 }
 
+function test_log_limit {
+	local testroot=`test_init log_limit`
+	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 'test log_limit' > /dev/null)
+	local commit_id1=`git_show_head $testroot/repo`
+
+	(cd $testroot/wt && got rm beta >/dev/null)
+	(cd $testroot/wt && got commit -m 'test log_limit' > /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 'test log_limit' > /dev/null)
+	local commit_id3=`git_show_head $testroot/repo`
+
+	# -l1 should print the first commit only
+	echo "commit $commit_id3 (master)" > $testroot/stdout.expected
+	(cd $testroot/wt && got log -l1 | 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
+
+	# env var can be used to set a log limit without -l option
+	echo "commit $commit_id3 (master)" > $testroot/stdout.expected
+	echo "commit $commit_id2" >> $testroot/stdout.expected
+	(cd $testroot/wt && env GOT_LOG_DEFAULT_LIMIT=2 got log | \
+		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
+
+	# non-numeric env var is ignored
+	(cd $testroot/wt && env GOT_LOG_DEFAULT_LIMIT=foobar got log | \
+		grep ^commit > $testroot/stdout)
+	echo "commit $commit_id3 (master)" > $testroot/stdout.expected
+	echo "commit $commit_id2" >> $testroot/stdout.expected
+	echo "commit $commit_id1" >> $testroot/stdout.expected
+	echo "commit $commit_id0" >> $testroot/stdout.expected
+	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
+
+	# -l option takes precedence over env var
+	echo "commit $commit_id3 (master)" > $testroot/stdout.expected
+	echo "commit $commit_id2" >> $testroot/stdout.expected
+	echo "commit $commit_id1" >> $testroot/stdout.expected
+	echo "commit $commit_id0" >> $testroot/stdout.expected
+	(cd $testroot/wt && env GOT_LOG_DEFAULT_LIMIT=1 got log -l0 | \
+		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" "0"
+}
 
 run_test test_log_in_repo
 run_test test_log_in_bare_repo
 run_test test_log_in_worktree
 run_test test_log_tag
+run_test test_log_limit