commit cbd1af7a5ac90edbfeec7507187896b76710c60e from: Stefan Sperling date: Mon Mar 18 15:41:10 2019 UTC make 'got log PATH' work consistently from inside a work tree commit - c2ac94566e2a939475a82ccfde0d509ea8508c7e commit + cbd1af7a5ac90edbfeec7507187896b76710c60e blob - bae036809c6294a731832bedff5d12763eda61d3 blob + fd0fb74b2c6a1723f8aca3e8c9c832e065f1d6d1 --- got/got.c +++ got/got.c @@ -200,6 +200,47 @@ apply_unveil(const char *repo_path, int repo_read_only return NULL; } +static const struct got_error * +resolve_path_in_worktree(char **wt_path, struct got_worktree *worktree, + const char *arg) +{ + const struct got_error *err = NULL; + char *resolved, *path = NULL; + size_t len; + + *wt_path = NULL; + + resolved = realpath(arg, NULL); + if (resolved == NULL) + return got_error_from_errno(); + + if (strncmp(got_worktree_get_root_path(worktree), resolved, + strlen(got_worktree_get_root_path(worktree)))) { + err = got_error(GOT_ERR_BAD_PATH); + goto done; + } + + path = strdup(resolved + strlen(got_worktree_get_root_path(worktree))); + if (path == NULL) { + err = got_error_from_errno(); + goto done; + } + + /* XXX status walk can't deal with trailing slash! */ + len = strlen(path); + while (path[len - 1] == '/') { + path[len - 1] = '\0'; + len--; + } +done: + free(resolved); + if (err == NULL) + *wt_path = path; + else + free(path); + return err; +} + __dead static void usage_checkout(void) { @@ -823,15 +864,6 @@ cmd_log(int argc, char *argv[]) argc -= optind; argv += optind; - - if (argc == 0) - path = strdup(""); - else if (argc == 1) - path = strdup(argv[0]); - else - usage_log(); - if (path == NULL) - return got_error_from_errno(); cwd = getcwd(NULL, 0); if (cwd == NULL) { @@ -844,6 +876,17 @@ cmd_log(int argc, char *argv[]) goto done; error = NULL; + if (argc == 0) + path = strdup(""); + else if (argc == 1) { + error = resolve_path_in_worktree(&path, worktree, argv[0]); + if (error) + goto done; + } else + usage_log(); + if (path == NULL) + goto done; + repo_path = worktree ? strdup(got_worktree_get_repo_path(worktree)) : strdup(cwd); if (repo_path == NULL) { @@ -1019,47 +1062,6 @@ done: } static const struct got_error * -get_status_path(char **status_path, struct got_worktree *worktree, - const char *arg) -{ - const struct got_error *err = NULL; - char *resolved, *path = NULL; - size_t len; - - *status_path = NULL; - - resolved = realpath(arg, NULL); - if (resolved == NULL) - return got_error_from_errno(); - - if (strncmp(got_worktree_get_root_path(worktree), resolved, - strlen(got_worktree_get_root_path(worktree)))) { - err = got_error(GOT_ERR_BAD_PATH); - goto done; - } - - path = strdup(resolved + strlen(got_worktree_get_root_path(worktree))); - if (path == NULL) { - err = got_error_from_errno(); - goto done; - } - - /* XXX status walk can't deal with trailing slash! */ - len = strlen(path); - while (path[len - 1] == '/') { - path[len - 1] = '\0'; - len--; - } -done: - free(resolved); - if (err == NULL) - *status_path = path; - else - free(path); - return err; -} - -static const struct got_error * cmd_diff(int argc, char *argv[]) { const struct got_error *error; @@ -1122,7 +1124,8 @@ cmd_diff(int argc, char *argv[]) goto done; } if (argc == 1) { - error = get_status_path(&path, worktree, argv[0]); + error = resolve_path_in_worktree(&path, worktree, + argv[0]); if (error) goto done; } else { @@ -1654,7 +1657,7 @@ cmd_status(int argc, char *argv[]) goto done; } } else if (argc == 1) { - error = get_status_path(&path, worktree, argv[0]); + error = resolve_path_in_worktree(&path, worktree, argv[0]); if (error) goto done; } else blob - 53654f5fbd9e0f82eb6ed8d9de43129689a6bf99 blob + d26e99387b67e0166e2150169d1ae7771aa42301 --- regress/cmdline/Makefile +++ regress/cmdline/Makefile @@ -10,4 +10,7 @@ update: status: ./status.sh +log: + ./log.sh + .include blob - /dev/null blob + 1e0c31ab493c7eb86539cf585e80f33a4be1e856 (mode 755) --- /dev/null +++ regress/cmdline/log.sh @@ -0,0 +1,59 @@ +#!/bin/sh +# +# Copyright (c) 2019 Stefan Sperling +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +. ./common.sh + +function test_log_in_worktree { + local testroot=`test_init log_in_worktree` + local head_rev=`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 "commit $head_rev (master)" > $testroot/stdout.expected + + for p in "" "." alpha epsilon; do + (cd $testroot/wt && got log $p | \ + grep ^commit > $testroot/stdout) + cmp $testroot/stdout.expected $testroot/stdout + ret="$?" + if [ "$ret" != "0" ]; then + diff -u $testroot/stdout.expected $testroot/stdout + test_done "$testroot" "$ret" + return 1 + fi + done + + for p in "" "." zeta; do + (cd $testroot/wt/epsilon && got log $p | \ + grep ^commit > $testroot/stdout) + cmp $testroot/stdout.expected $testroot/stdout + ret="$?" + if [ "$ret" != "0" ]; then + diff -u $testroot/stdout.expected $testroot/stdout + test_done "$testroot" "$ret" + return 1 + fi + done + + test_done "$testroot" "0" +} + +run_test test_log_in_worktree