Unverified Commit ab5b3f37 by Edward Thomson Committed by GitHub

Merge pull request #6095 from yoichi/better-compatiblity-for-at-time-notation

Better revparse compatibility for at time notation
parents 4b27009c 7bb206a7
...@@ -853,7 +853,7 @@ static git_time_t approxidate_str(const char *date, ...@@ -853,7 +853,7 @@ static git_time_t approxidate_str(const char *date,
} }
pending_number(&tm, &number); pending_number(&tm, &number);
if (!touched) if (!touched)
*error_ret = 1; *error_ret = -1;
return update_tm(&tm, &now, 0); return update_tm(&tm, &now, 0);
} }
...@@ -872,7 +872,7 @@ int git_date_parse(git_time_t *out, const char *date) ...@@ -872,7 +872,7 @@ int git_date_parse(git_time_t *out, const char *date)
return -1; return -1;
*out = approxidate_str(date, time_sec, &error_ret); *out = approxidate_str(date, time_sec, &error_ret);
return error_ret; return error_ret;
} }
int git_date_rfc2822_fmt(git_str *out, git_time_t time, int offset) int git_date_rfc2822_fmt(git_str *out, git_time_t time, int offset)
......
...@@ -208,7 +208,7 @@ static int retrieve_oid_from_reflog(git_oid *oid, git_reference *ref, size_t ide ...@@ -208,7 +208,7 @@ static int retrieve_oid_from_reflog(git_oid *oid, git_reference *ref, size_t ide
{ {
git_reflog *reflog; git_reflog *reflog;
size_t numentries; size_t numentries;
const git_reflog_entry *entry; const git_reflog_entry *entry = NULL;
bool search_by_pos = (identifier <= 100000000); bool search_by_pos = (identifier <= 100000000);
if (git_reflog_read(&reflog, git_reference_owner(ref), git_reference_name(ref)) < 0) if (git_reflog_read(&reflog, git_reference_owner(ref), git_reference_name(ref)) < 0)
...@@ -237,8 +237,15 @@ static int retrieve_oid_from_reflog(git_oid *oid, git_reference *ref, size_t ide ...@@ -237,8 +237,15 @@ static int retrieve_oid_from_reflog(git_oid *oid, git_reference *ref, size_t ide
break; break;
} }
if (i == numentries) if (i == numentries) {
goto notfound; if (entry == NULL)
goto notfound;
/*
* TODO: emit a warning (log for 'branch' only goes back to ...)
*/
git_oid_cpy(oid, git_reflog_entry_id_new(entry));
}
} }
git_reflog_free(reflog); git_reflog_free(reflog);
...@@ -345,8 +352,10 @@ static int handle_at_syntax(git_object **out, git_reference **ref, const char *s ...@@ -345,8 +352,10 @@ static int handle_at_syntax(git_object **out, git_reference **ref, const char *s
goto cleanup; goto cleanup;
} }
if (git_date_parse(&timestamp, curly_braces_content) < 0) if (git_date_parse(&timestamp, curly_braces_content) < 0) {
error = GIT_EINVALIDSPEC;
goto cleanup; goto cleanup;
}
error = retrieve_revobject_from_reflog(out, ref, repo, git_str_cstr(&identifier), (size_t)timestamp); error = retrieve_revobject_from_reflog(out, ref, repo, git_str_cstr(&identifier), (size_t)timestamp);
......
...@@ -13,3 +13,10 @@ void test_date_date__overflow(void) ...@@ -13,3 +13,10 @@ void test_date_date__overflow(void)
cl_assert(d2038 < d2039); cl_assert(d2038 < d2039);
#endif #endif
} }
void test_date_date__invalid_date(void)
{
git_time_t d;
cl_git_fail(git_date_parse(&d, ""));
cl_git_fail(git_date_parse(&d, "NEITHER_INTEGER_NOR_DATETIME"));
}
...@@ -508,7 +508,7 @@ void test_fetchhead_nonetwork__create_with_multiple_refspecs(void) ...@@ -508,7 +508,7 @@ void test_fetchhead_nonetwork__create_with_multiple_refspecs(void)
int i; int i;
struct prefix_count prefix_counts[] = { struct prefix_count prefix_counts[] = {
{"refs/notes/", 0, 1}, {"refs/notes/", 0, 1},
{"refs/heads/", 0, 12}, {"refs/heads/", 0, 13},
{"refs/tags/", 0, 7}, {"refs/tags/", 0, 7},
{NULL, 0, 0}, {NULL, 0, 0},
}; };
......
...@@ -45,7 +45,7 @@ void test_network_fetchlocal__complete(void) ...@@ -45,7 +45,7 @@ void test_network_fetchlocal__complete(void)
cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL)); cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL));
cl_git_pass(git_reference_list(&refnames, repo)); cl_git_pass(git_reference_list(&refnames, repo));
cl_assert_equal_i(19, (int)refnames.count); cl_assert_equal_i(20, (int)refnames.count);
cl_assert(callcount > 0); cl_assert(callcount > 0);
git_strarray_dispose(&refnames); git_strarray_dispose(&refnames);
...@@ -74,7 +74,7 @@ void test_network_fetchlocal__prune(void) ...@@ -74,7 +74,7 @@ void test_network_fetchlocal__prune(void)
cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL)); cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL));
cl_git_pass(git_reference_list(&refnames, repo)); cl_git_pass(git_reference_list(&refnames, repo));
cl_assert_equal_i(19, (int)refnames.count); cl_assert_equal_i(20, (int)refnames.count);
cl_assert(callcount > 0); cl_assert(callcount > 0);
git_strarray_dispose(&refnames); git_strarray_dispose(&refnames);
git_remote_free(origin); git_remote_free(origin);
...@@ -88,7 +88,7 @@ void test_network_fetchlocal__prune(void) ...@@ -88,7 +88,7 @@ void test_network_fetchlocal__prune(void)
cl_git_pass(git_remote_prune(origin, &options.callbacks)); cl_git_pass(git_remote_prune(origin, &options.callbacks));
cl_git_pass(git_reference_list(&refnames, repo)); cl_git_pass(git_reference_list(&refnames, repo));
cl_assert_equal_i(18, (int)refnames.count); cl_assert_equal_i(19, (int)refnames.count);
git_strarray_dispose(&refnames); git_strarray_dispose(&refnames);
git_remote_free(origin); git_remote_free(origin);
...@@ -101,7 +101,7 @@ void test_network_fetchlocal__prune(void) ...@@ -101,7 +101,7 @@ void test_network_fetchlocal__prune(void)
cl_git_pass(git_remote_prune(origin, &options.callbacks)); cl_git_pass(git_remote_prune(origin, &options.callbacks));
cl_git_pass(git_reference_list(&refnames, repo)); cl_git_pass(git_reference_list(&refnames, repo));
cl_assert_equal_i(17, (int)refnames.count); cl_assert_equal_i(18, (int)refnames.count);
git_strarray_dispose(&refnames); git_strarray_dispose(&refnames);
git_remote_free(origin); git_remote_free(origin);
...@@ -166,7 +166,7 @@ void test_network_fetchlocal__prune_overlapping(void) ...@@ -166,7 +166,7 @@ void test_network_fetchlocal__prune_overlapping(void)
assert_ref_exists(repo, "refs/remotes/origin/master"); assert_ref_exists(repo, "refs/remotes/origin/master");
assert_ref_exists(repo, "refs/remotes/origin/pr/42"); assert_ref_exists(repo, "refs/remotes/origin/pr/42");
cl_git_pass(git_reference_list(&refnames, repo)); cl_git_pass(git_reference_list(&refnames, repo));
cl_assert_equal_i(20, (int)refnames.count); cl_assert_equal_i(21, (int)refnames.count);
git_strarray_dispose(&refnames); git_strarray_dispose(&refnames);
cl_git_pass(git_config_delete_multivar(config, "remote.origin.fetch", "refs")); cl_git_pass(git_config_delete_multivar(config, "remote.origin.fetch", "refs"));
...@@ -181,7 +181,7 @@ void test_network_fetchlocal__prune_overlapping(void) ...@@ -181,7 +181,7 @@ void test_network_fetchlocal__prune_overlapping(void)
assert_ref_exists(repo, "refs/remotes/origin/master"); assert_ref_exists(repo, "refs/remotes/origin/master");
assert_ref_exists(repo, "refs/remotes/origin/pr/42"); assert_ref_exists(repo, "refs/remotes/origin/pr/42");
cl_git_pass(git_reference_list(&refnames, repo)); cl_git_pass(git_reference_list(&refnames, repo));
cl_assert_equal_i(20, (int)refnames.count); cl_assert_equal_i(21, (int)refnames.count);
git_strarray_dispose(&refnames); git_strarray_dispose(&refnames);
cl_git_pass(git_config_delete_multivar(config, "remote.origin.fetch", "refs")); cl_git_pass(git_config_delete_multivar(config, "remote.origin.fetch", "refs"));
...@@ -221,7 +221,7 @@ void test_network_fetchlocal__fetchprune(void) ...@@ -221,7 +221,7 @@ void test_network_fetchlocal__fetchprune(void)
cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL)); cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL));
cl_git_pass(git_reference_list(&refnames, repo)); cl_git_pass(git_reference_list(&refnames, repo));
cl_assert_equal_i(19, (int)refnames.count); cl_assert_equal_i(20, (int)refnames.count);
cl_assert(callcount > 0); cl_assert(callcount > 0);
git_strarray_dispose(&refnames); git_strarray_dispose(&refnames);
git_remote_free(origin); git_remote_free(origin);
...@@ -235,7 +235,7 @@ void test_network_fetchlocal__fetchprune(void) ...@@ -235,7 +235,7 @@ void test_network_fetchlocal__fetchprune(void)
cl_git_pass(git_remote_prune(origin, &options.callbacks)); cl_git_pass(git_remote_prune(origin, &options.callbacks));
cl_git_pass(git_reference_list(&refnames, repo)); cl_git_pass(git_reference_list(&refnames, repo));
cl_assert_equal_i(18, (int)refnames.count); cl_assert_equal_i(19, (int)refnames.count);
git_strarray_dispose(&refnames); git_strarray_dispose(&refnames);
git_remote_free(origin); git_remote_free(origin);
...@@ -251,7 +251,7 @@ void test_network_fetchlocal__fetchprune(void) ...@@ -251,7 +251,7 @@ void test_network_fetchlocal__fetchprune(void)
cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL)); cl_git_pass(git_remote_fetch(origin, NULL, &options, NULL));
cl_git_pass(git_reference_list(&refnames, repo)); cl_git_pass(git_reference_list(&refnames, repo));
cl_assert_equal_i(17, (int)refnames.count); cl_assert_equal_i(18, (int)refnames.count);
git_strarray_dispose(&refnames); git_strarray_dispose(&refnames);
git_remote_free(origin); git_remote_free(origin);
...@@ -335,7 +335,7 @@ void test_network_fetchlocal__partial(void) ...@@ -335,7 +335,7 @@ void test_network_fetchlocal__partial(void)
git_strarray_dispose(&refnames); git_strarray_dispose(&refnames);
cl_git_pass(git_reference_list(&refnames, repo)); cl_git_pass(git_reference_list(&refnames, repo));
cl_assert_equal_i(20, (int)refnames.count); /* 18 remote + 1 local */ cl_assert_equal_i(21, (int)refnames.count); /* 18 remote + 1 local */
cl_assert(callcount > 0); cl_assert(callcount > 0);
git_strarray_dispose(&refnames); git_strarray_dispose(&refnames);
...@@ -418,7 +418,7 @@ void test_network_fetchlocal__multi_remotes(void) ...@@ -418,7 +418,7 @@ void test_network_fetchlocal__multi_remotes(void)
cl_git_pass(git_remote_fetch(test, NULL, &options, NULL)); cl_git_pass(git_remote_fetch(test, NULL, &options, NULL));
cl_git_pass(git_reference_list(&refnames, repo)); cl_git_pass(git_reference_list(&refnames, repo));
cl_assert_equal_i(33, (int)refnames.count); cl_assert_equal_i(35, (int)refnames.count);
git_strarray_dispose(&refnames); git_strarray_dispose(&refnames);
cl_git_pass(git_remote_set_url(repo, "test_with_pushurl", cl_git_fixture_url("testrepo.git"))); cl_git_pass(git_remote_set_url(repo, "test_with_pushurl", cl_git_fixture_url("testrepo.git")));
...@@ -426,7 +426,7 @@ void test_network_fetchlocal__multi_remotes(void) ...@@ -426,7 +426,7 @@ void test_network_fetchlocal__multi_remotes(void)
cl_git_pass(git_remote_fetch(test2, NULL, &options, NULL)); cl_git_pass(git_remote_fetch(test2, NULL, &options, NULL));
cl_git_pass(git_reference_list(&refnames, repo)); cl_git_pass(git_reference_list(&refnames, repo));
cl_assert_equal_i(45, (int)refnames.count); cl_assert_equal_i(48, (int)refnames.count);
git_strarray_dispose(&refnames); git_strarray_dispose(&refnames);
git_remote_free(test); git_remote_free(test);
......
...@@ -61,7 +61,7 @@ void test_network_remote_local__retrieve_advertised_references(void) ...@@ -61,7 +61,7 @@ void test_network_remote_local__retrieve_advertised_references(void)
cl_git_pass(git_remote_ls(&refs, &refs_len, remote)); cl_git_pass(git_remote_ls(&refs, &refs_len, remote));
cl_assert_equal_i(refs_len, 29); cl_assert_equal_i(refs_len, 30);
} }
void test_network_remote_local__retrieve_advertised_before_connect(void) void test_network_remote_local__retrieve_advertised_before_connect(void)
...@@ -85,7 +85,7 @@ void test_network_remote_local__retrieve_advertised_references_after_disconnect( ...@@ -85,7 +85,7 @@ void test_network_remote_local__retrieve_advertised_references_after_disconnect(
cl_git_pass(git_remote_ls(&refs, &refs_len, remote)); cl_git_pass(git_remote_ls(&refs, &refs_len, remote));
cl_assert_equal_i(refs_len, 29); cl_assert_equal_i(refs_len, 30);
} }
void test_network_remote_local__retrieve_advertised_references_from_spaced_repository(void) void test_network_remote_local__retrieve_advertised_references_from_spaced_repository(void)
...@@ -100,7 +100,7 @@ void test_network_remote_local__retrieve_advertised_references_from_spaced_repos ...@@ -100,7 +100,7 @@ void test_network_remote_local__retrieve_advertised_references_from_spaced_repos
cl_git_pass(git_remote_ls(&refs, &refs_len, remote)); cl_git_pass(git_remote_ls(&refs, &refs_len, remote));
cl_assert_equal_i(refs_len, 29); cl_assert_equal_i(refs_len, 30);
git_remote_free(remote); /* Disconnect from the "spaced repo" before the cleanup */ git_remote_free(remote); /* Disconnect from the "spaced repo" before the cleanup */
remote = NULL; remote = NULL;
......
...@@ -48,7 +48,7 @@ static void assert_retrieval(unsigned int flags, unsigned int expected_count) ...@@ -48,7 +48,7 @@ static void assert_retrieval(unsigned int flags, unsigned int expected_count)
void test_refs_branches_iterator__retrieve_all_branches(void) void test_refs_branches_iterator__retrieve_all_branches(void)
{ {
assert_retrieval(GIT_BRANCH_ALL, 14); assert_retrieval(GIT_BRANCH_ALL, 15);
} }
void test_refs_branches_iterator__retrieve_remote_branches(void) void test_refs_branches_iterator__retrieve_remote_branches(void)
...@@ -58,7 +58,7 @@ void test_refs_branches_iterator__retrieve_remote_branches(void) ...@@ -58,7 +58,7 @@ void test_refs_branches_iterator__retrieve_remote_branches(void)
void test_refs_branches_iterator__retrieve_local_branches(void) void test_refs_branches_iterator__retrieve_local_branches(void)
{ {
assert_retrieval(GIT_BRANCH_LOCAL, 12); assert_retrieval(GIT_BRANCH_LOCAL, 13);
} }
struct expectations { struct expectations {
......
...@@ -48,8 +48,8 @@ static void assert_retrieval(const char *glob, int expected_count) ...@@ -48,8 +48,8 @@ static void assert_retrieval(const char *glob, int expected_count)
void test_refs_foreachglob__retrieve_all_refs(void) void test_refs_foreachglob__retrieve_all_refs(void)
{ {
/* 12 heads (including one packed head) + 1 note + 2 remotes + 7 tags + 1 blob */ /* 13 heads (including one packed head) + 1 note + 2 remotes + 7 tags + 1 blob */
assert_retrieval("*", 23); assert_retrieval("*", 24);
} }
void test_refs_foreachglob__retrieve_remote_branches(void) void test_refs_foreachglob__retrieve_remote_branches(void)
...@@ -59,7 +59,7 @@ void test_refs_foreachglob__retrieve_remote_branches(void) ...@@ -59,7 +59,7 @@ void test_refs_foreachglob__retrieve_remote_branches(void)
void test_refs_foreachglob__retrieve_local_branches(void) void test_refs_foreachglob__retrieve_local_branches(void)
{ {
assert_retrieval("refs/heads/*", 12); assert_retrieval("refs/heads/*", 13);
} }
void test_refs_foreachglob__retrieve_nonexistant(void) void test_refs_foreachglob__retrieve_nonexistant(void)
......
...@@ -28,6 +28,7 @@ static const char *refnames[] = { ...@@ -28,6 +28,7 @@ static const char *refnames[] = {
"refs/heads/test", "refs/heads/test",
"refs/heads/track-local", "refs/heads/track-local",
"refs/heads/trailing", "refs/heads/trailing",
"refs/heads/with-empty-log",
"refs/notes/fanout", "refs/notes/fanout",
"refs/remotes/test/master", "refs/remotes/test/master",
"refs/tags/annotated_tag_to_blob", "refs/tags/annotated_tag_to_blob",
...@@ -58,6 +59,7 @@ static const char *refnames_with_symlink[] = { ...@@ -58,6 +59,7 @@ static const char *refnames_with_symlink[] = {
"refs/heads/test", "refs/heads/test",
"refs/heads/track-local", "refs/heads/track-local",
"refs/heads/trailing", "refs/heads/trailing",
"refs/heads/with-empty-log",
"refs/notes/fanout", "refs/notes/fanout",
"refs/remotes/test/master", "refs/remotes/test/master",
"refs/tags/annotated_tag_to_blob", "refs/tags/annotated_tag_to_blob",
......
...@@ -399,7 +399,7 @@ void test_refs_revparse__date(void) ...@@ -399,7 +399,7 @@ void test_refs_revparse__date(void)
* a65fedf HEAD@{1335806603 -0900}: commit: * a65fedf HEAD@{1335806603 -0900}: commit:
* be3563a HEAD@{1335806563 -0700}: clone: from /Users/ben/src/libgit2/tests/resour * be3563a HEAD@{1335806563 -0700}: clone: from /Users/ben/src/libgit2/tests/resour
*/ */
test_object("HEAD@{10 years ago}", NULL); test_object("HEAD@{10 years ago}", "be3563ae3f795b2b4353bcce3a527ad0a4f7f644");
test_object("HEAD@{1 second}", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750"); test_object("HEAD@{1 second}", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
test_object("HEAD@{1 second ago}", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750"); test_object("HEAD@{1 second ago}", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
...@@ -417,11 +417,12 @@ void test_refs_revparse__date(void) ...@@ -417,11 +417,12 @@ void test_refs_revparse__date(void)
/* /*
* $ git reflog -1 "master@{2012-04-30 17:22:42 +0000}" * $ git rev-parse "master@{2012-04-30 17:22:42 +0000}"
* warning: Log for 'master' only goes back to Mon, 30 Apr 2012 09:22:43 -0800. * warning: log for 'master' only goes back to Mon, 30 Apr 2012 09:22:43 -0800
* be3563ae3f795b2b4353bcce3a527ad0a4f7f644
*/ */
test_object("master@{2012-04-30 17:22:42 +0000}", NULL); test_object("master@{2012-04-30 17:22:42 +0000}", "be3563ae3f795b2b4353bcce3a527ad0a4f7f644");
test_object("master@{2012-04-30 09:22:42 -0800}", NULL); test_object("master@{2012-04-30 09:22:42 -0800}", "be3563ae3f795b2b4353bcce3a527ad0a4f7f644");
/* /*
* $ git reflog -1 "master@{2012-04-30 17:22:43 +0000}" * $ git reflog -1 "master@{2012-04-30 17:22:43 +0000}"
...@@ -451,6 +452,25 @@ void test_refs_revparse__date(void) ...@@ -451,6 +452,25 @@ void test_refs_revparse__date(void)
*/ */
test_object("master@{1335806603}", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750"); test_object("master@{1335806603}", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750");
test_object("master@{1335806602}", "be3563ae3f795b2b4353bcce3a527ad0a4f7f644"); test_object("master@{1335806602}", "be3563ae3f795b2b4353bcce3a527ad0a4f7f644");
/*
* $ git rev-parse "with-empty-log@{2 days ago}" --
* fatal: log for refs/heads/with-empty-log is empty
*/
test_object("with-empty-log@{2 days ago}", NULL);
}
void test_refs_revparse__invalid_date(void)
{
/*
* $ git rev-parse HEAD@{} --
* fatal: bad revision 'HEAD@{}'
*
* $ git rev-parse HEAD@{NEITHER_INTEGER_NOR_DATETIME} --
* fatal: bad revision 'HEAD@{NEITHER_INTEGER_NOR_DATETIME}'
*/
test_object("HEAD@{}", NULL);
test_object("HEAD@{NEITHER_INTEGER_NOR_DATETIME}", NULL);
} }
void test_refs_revparse__colon(void) void test_refs_revparse__colon(void)
......
8496071c1b46c854b31185ea97743be6a8774479
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment