Skip to content

Commit

Permalink
refs: make rev-parse --quiet actually quiet
Browse files Browse the repository at this point in the history
When a reflog is deleted, e.g. when "git stash" clears its stashes,
"git rev-parse --verify --quiet" dies:

	fatal: Log for refs/stash is empty.

The reason is that the get_sha1() code path does not allow us
to suppress this message.

Pass the flags bitfield through get_sha1_with_context() so that
read_ref_at() can suppress the message.

Use get_sha1_with_context1() instead of get_sha1() in rev-parse
so that the --quiet flag is honored.

Signed-off-by: David Aguilar <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
  • Loading branch information
davvid authored and gitster committed Sep 19, 2014
1 parent 2892dfe commit c41a87d
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 16 deletions.
5 changes: 4 additions & 1 deletion builtin/rev-parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,9 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
int has_dashdash = 0;
int output_prefix = 0;
unsigned char sha1[20];
unsigned int flags = 0;
const char *name = NULL;
struct object_context unused;

if (argc > 1 && !strcmp("--parseopt", argv[1]))
return cmd_parseopt(argc - 1, argv + 1, prefix);
Expand Down Expand Up @@ -596,6 +598,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
}
if (!strcmp(arg, "--quiet") || !strcmp(arg, "-q")) {
quiet = 1;
flags |= GET_SHA1_QUIETLY;
continue;
}
if (!strcmp(arg, "--short") ||
Expand Down Expand Up @@ -818,7 +821,7 @@ int cmd_rev_parse(int argc, const char **argv, const char *prefix)
name++;
type = REVERSED;
}
if (!get_sha1(name, sha1)) {
if (!get_sha1_with_context(name, flags, sha1, &unused)) {
if (verify)
revs_count++;
else
Expand Down
5 changes: 3 additions & 2 deletions builtin/show-branch.c
Original file line number Diff line number Diff line change
Expand Up @@ -723,6 +723,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
char nth_desc[256];
char *ref;
int base = 0;
unsigned int flags = 0;

if (ac == 0) {
static const char *fake_av[2];
Expand All @@ -749,7 +750,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
/* Ah, that is a date spec... */
unsigned long at;
at = approxidate(reflog_base);
read_ref_at(ref, at, -1, sha1, NULL,
read_ref_at(ref, flags, at, -1, sha1, NULL,
NULL, NULL, &base);
}
}
Expand All @@ -760,7 +761,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix)
unsigned long timestamp;
int tz;

if (read_ref_at(ref, 0, base+i, sha1, &logmsg,
if (read_ref_at(ref, flags, 0, base+i, sha1, &logmsg,
&timestamp, &tz, NULL)) {
reflog = i;
break;
Expand Down
10 changes: 7 additions & 3 deletions refs.c
Original file line number Diff line number Diff line change
Expand Up @@ -3108,7 +3108,7 @@ static int read_ref_at_ent_oldest(unsigned char *osha1, unsigned char *nsha1,
return 1;
}

int read_ref_at(const char *refname, unsigned long at_time, int cnt,
int read_ref_at(const char *refname, unsigned int flags, unsigned long at_time, int cnt,
unsigned char *sha1, char **msg,
unsigned long *cutoff_time, int *cutoff_tz, int *cutoff_cnt)
{
Expand All @@ -3126,8 +3126,12 @@ int read_ref_at(const char *refname, unsigned long at_time, int cnt,

for_each_reflog_ent_reverse(refname, read_ref_at_ent, &cb);

if (!cb.reccnt)
die("Log for %s is empty.", refname);
if (!cb.reccnt) {
if (flags & GET_SHA1_QUIETLY)
exit(128);
else
die("Log for %s is empty.", refname);
}
if (cb.found_it)
return 0;

Expand Down
3 changes: 2 additions & 1 deletion refs.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,8 @@ extern int write_ref_sha1(struct ref_lock *lock, const unsigned char *sha1, cons
int log_ref_setup(const char *refname, char *logfile, int bufsize);

/** Reads log for the value of ref during at_time. **/
extern int read_ref_at(const char *refname, unsigned long at_time, int cnt,
extern int read_ref_at(const char *refname, unsigned int flags,
unsigned long at_time, int cnt,
unsigned char *sha1, char **msg,
unsigned long *cutoff_time, int *cutoff_tz, int *cutoff_cnt);

Expand Down
24 changes: 15 additions & 9 deletions sha1_name.c
Original file line number Diff line number Diff line change
Expand Up @@ -432,7 +432,8 @@ static inline int upstream_mark(const char *string, int len)
static int get_sha1_1(const char *name, int len, unsigned char *sha1, unsigned lookup_flags);
static int interpret_nth_prior_checkout(const char *name, int namelen, struct strbuf *buf);

static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
static int get_sha1_basic(const char *str, int len, unsigned char *sha1,
unsigned int flags)
{
static const char *warn_msg = "refname '%.*s' is ambiguous.";
static const char *object_name_msg = N_(
Expand Down Expand Up @@ -511,7 +512,7 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
if (!refs_found)
return -1;

if (warn_ambiguous_refs &&
if (warn_ambiguous_refs && !(flags & GET_SHA1_QUIETLY) &&
(refs_found > 1 ||
!get_short_sha1(str, len, tmp_sha1, GET_SHA1_QUIETLY)))
warning(warn_msg, len, str);
Expand Down Expand Up @@ -545,7 +546,7 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
return -1;
}
}
if (read_ref_at(real_ref, at_time, nth, sha1, NULL,
if (read_ref_at(real_ref, flags, at_time, nth, sha1, NULL,
&co_time, &co_tz, &co_cnt)) {
if (!len) {
if (starts_with(real_ref, "refs/heads/")) {
Expand All @@ -557,11 +558,16 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
len = 4;
}
}
if (at_time)
warning("Log for '%.*s' only goes "
"back to %s.", len, str,
show_date(co_time, co_tz, DATE_RFC2822));
else {
if (at_time) {
if (!(flags & GET_SHA1_QUIETLY)) {
warning("Log for '%.*s' only goes "
"back to %s.", len, str,
show_date(co_time, co_tz, DATE_RFC2822));
}
} else {
if (flags & GET_SHA1_QUIETLY) {
exit(128);
}
die("Log for '%.*s' only has %d entries.",
len, str, co_cnt);
}
Expand Down Expand Up @@ -801,7 +807,7 @@ static int get_sha1_1(const char *name, int len, unsigned char *sha1, unsigned l
if (!ret)
return 0;

ret = get_sha1_basic(name, len, sha1);
ret = get_sha1_basic(name, len, sha1, lookup_flags);
if (!ret)
return 0;

Expand Down
27 changes: 27 additions & 0 deletions t/t1503-rev-parse-verify.sh
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,33 @@ test_expect_success 'fails silently when using -q' '
test_must_be_empty error
'

test_expect_success 'fails silently when using -q with deleted reflogs' '
ref=$(git rev-parse HEAD) &&
: >.git/logs/refs/test &&
git update-ref -m "message for refs/test" refs/test "$ref" &&
git reflog delete --updateref --rewrite refs/test@{0} &&
test_must_fail git rev-parse -q --verify refs/test@{0} >error 2>&1 &&
test_must_be_empty error
'

test_expect_success 'fails silently when using -q with not enough reflogs' '
ref=$(git rev-parse HEAD) &&
: >.git/logs/refs/test2 &&
git update-ref -m "message for refs/test2" refs/test2 "$ref" &&
test_must_fail git rev-parse -q --verify refs/test2@{999} >error 2>&1 &&
test_must_be_empty error
'

test_expect_success 'succeeds silently with -q and reflogs that do not go far back enough in time' '
ref=$(git rev-parse HEAD) &&
: >.git/logs/refs/test3 &&
git update-ref -m "message for refs/test3" refs/test3 "$ref" &&
git rev-parse -q --verify refs/test3@{1.year.ago} >actual 2>error &&
test_must_be_empty error &&
echo "$ref" >expect &&
test_cmp expect actual
'

test_expect_success 'no stdout output on error' '
test -z "$(git rev-parse --verify)" &&
test -z "$(git rev-parse --verify foo)" &&
Expand Down

0 comments on commit c41a87d

Please sign in to comment.