Skip to content

Commit

Permalink
get_sha1: warn about full or short object names that look like refs
Browse files Browse the repository at this point in the history
When we get 40 hex digits, we immediately assume it's an SHA-1. This
is the right thing to do because we have no way else to specify an
object. If there is a ref with the same object name, it will be
ignored. Warn the user about this case because the ref with full
object name is likely a mistake, for example

    git checkout -b $empty_var $(git rev-parse something)

advice.object_name_warning is not documented because frankly people
should not be aware about it until they encounter this situation.

While at there, warn about ambiguation with abbreviated SHA-1 too.

Signed-off-by: Nguyễn Thái Ngọc Duy <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
  • Loading branch information
pclouds authored and gitster committed May 29, 2013
1 parent 239222f commit 798c35f
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 2 deletions.
2 changes: 2 additions & 0 deletions advice.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ int advice_commit_before_merge = 1;
int advice_resolve_conflict = 1;
int advice_implicit_identity = 1;
int advice_detached_head = 1;
int advice_object_name_warning = 1;

static struct {
const char *name;
Expand All @@ -29,6 +30,7 @@ static struct {
{ "resolveconflict", &advice_resolve_conflict },
{ "implicitidentity", &advice_implicit_identity },
{ "detachedhead", &advice_detached_head },
{ "object_name_warning", &advice_object_name_warning },

/* make this an alias for backward compatibility */
{ "pushnonfastforward", &advice_push_update_rejected }
Expand Down
1 change: 1 addition & 0 deletions advice.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ extern int advice_commit_before_merge;
extern int advice_resolve_conflict;
extern int advice_implicit_identity;
extern int advice_detached_head;
extern int advice_object_name_warning;

int git_default_advice_config(const char *var, const char *value);
void advise(const char *advice, ...);
Expand Down
25 changes: 23 additions & 2 deletions sha1_name.c
Original file line number Diff line number Diff line change
Expand Up @@ -435,12 +435,31 @@ static int get_sha1_1(const char *name, int len, unsigned char *sha1, unsigned l
static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
{
static const char *warn_msg = "refname '%.*s' is ambiguous.";
static const char *object_name_msg = N_(
"Git normally never creates a ref that ends with 40 hex characters\n"
"because it will be ignored when you just specify 40-hex. These refs\n"
"may be created by mistake. For example,\n"
"\n"
" git checkout -b $br $(git rev-parse ...)\n"
"\n"
"where \"$br\" is somehow empty and a 40-hex ref is created. Please\n"
"examine these refs and maybe delete them. Turn this message off by\n"
"running \"git config advice.object_name_warning false\"");
unsigned char tmp_sha1[20];
char *real_ref = NULL;
int refs_found = 0;
int at, reflog_len;

if (len == 40 && !get_sha1_hex(str, sha1))
if (len == 40 && !get_sha1_hex(str, sha1)) {
refs_found = dwim_ref(str, len, tmp_sha1, &real_ref);
if (refs_found > 0 && warn_ambiguous_refs) {
warning(warn_msg, len, str);
if (advice_object_name_warning)
fprintf(stderr, "%s\n", _(object_name_msg));
}
free(real_ref);
return 0;
}

/* basic@{time or number or -number} format to query ref-log */
reflog_len = at = 0;
Expand Down Expand Up @@ -481,7 +500,9 @@ static int get_sha1_basic(const char *str, int len, unsigned char *sha1)
if (!refs_found)
return -1;

if (warn_ambiguous_refs && refs_found > 1)
if (warn_ambiguous_refs &&
(refs_found > 1 ||
!get_short_sha1(str, len, tmp_sha1, GET_SHA1_QUIETLY)))
warning(warn_msg, len, str);

if (reflog_len) {
Expand Down
18 changes: 18 additions & 0 deletions t/t1512-rev-parse-disambiguation.sh
Original file line number Diff line number Diff line change
Expand Up @@ -261,4 +261,22 @@ test_expect_success 'rev-parse --disambiguate' '
test "$(sed -e "s/^\(.........\).*/\1/" actual | sort -u)" = 000000000
'

test_expect_success 'ambiguous 40-hex ref' '
TREE=$(git mktree </dev/null) &&
REF=`git rev-parse HEAD` &&
VAL=$(git commit-tree $TREE </dev/null) &&
git update-ref refs/heads/$REF $VAL &&
test `git rev-parse $REF 2>err` = $REF &&
grep "refname.*${REF}.*ambiguous" err
'

test_expect_success 'ambiguous short sha1 ref' '
TREE=$(git mktree </dev/null) &&
REF=`git rev-parse --short HEAD` &&
VAL=$(git commit-tree $TREE </dev/null) &&
git update-ref refs/heads/$REF $VAL &&
test `git rev-parse $REF 2>err` = $VAL &&
grep "refname.*${REF}.*ambiguous" err
'

test_done

0 comments on commit 798c35f

Please sign in to comment.