diff options
| -rw-r--r-- | src/revparse.c | 24 | ||||
| -rw-r--r-- | tests-clar/refs/revparse.c | 4 | ||||
| -rw-r--r-- | tests-clar/resources/testrepo.git/config | 4 | ||||
| -rw-r--r-- | tests/resources/testrepo.git/refs/remotes/test/master | 1 |
4 files changed, 30 insertions, 3 deletions
diff --git a/src/revparse.c b/src/revparse.c index 9719093f6..13778eb11 100644 --- a/src/revparse.c +++ b/src/revparse.c @@ -18,6 +18,8 @@ #include "git2/commit.h" #include "git2/reflog.h" #include "git2/refs.h" +#include "git2/repository.h" +#include "git2/config.h" GIT_BEGIN_DECL @@ -173,7 +175,27 @@ static int walk_ref_history(git_object **out, git_repository *repo, const char * /* @{u} or @{upstream} -> upstream branch, for a tracking branch. This is stored in the config. */ if (!strcmp(reflogspec, "@{u}") || !strcmp(reflogspec, "@{upstream}")) { - /* TODO */ + git_config *cfg; + if (!git_repository_config(&cfg, repo)) { + /* Is the ref a tracking branch? */ + const char *remote; + git_buf_clear(&buf); + git_buf_printf(&buf, "branch.%s.remote", refspec); + if (!git_config_get_string(cfg, git_buf_cstr(&buf), &remote)) { + /* Yes. Find the first merge target name. */ + const char *mergetarget; + git_buf_clear(&buf); + git_buf_printf(&buf, "branch.%s.merge", refspec); + if (!git_config_get_string(cfg, git_buf_cstr(&buf), &mergetarget) && + !git__prefixcmp(mergetarget, "refs/heads/")) { + /* Success. Look up the target and fetch the object. */ + git_buf_clear(&buf); + git_buf_printf(&buf, "refs/remotes/%s/%s", remote, mergetarget+11); + retcode = revparse_lookup_fully_qualifed_ref(out, repo, git_buf_cstr(&buf)); + } + } + git_config_free(cfg); + } } /* @{N} -> Nth prior value for the ref (from reflog) */ diff --git a/tests-clar/refs/revparse.c b/tests-clar/refs/revparse.c index c5cbb8745..944a18b9c 100644 --- a/tests-clar/refs/revparse.c +++ b/tests-clar/refs/revparse.c @@ -120,10 +120,10 @@ void test_refs_revparse__reflog(void) test_object("master@{1}", "be3563ae3f795b2b4353bcce3a527ad0a4f7f644"); test_object("@{0}", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750"); test_object("@{1}", "be3563ae3f795b2b4353bcce3a527ad0a4f7f644"); + test_object("master@{upstream}", "be3563ae3f795b2b4353bcce3a527ad0a4f7f644"); + test_object("master@{u}", "be3563ae3f795b2b4353bcce3a527ad0a4f7f644"); /* Not ready yet test_object("HEAD@{100 years ago}", "a65fedf39aefe402d3bb6e24df4d4f5fe4547750"); test_object("master@{2012-4-30 10:23:20}", "be3563ae3f795b2b4353bcce3a527ad0a4f7f644"); - test_object("master@{upstream}", "???"); - test_object("master@{u}", "???"); */ } diff --git a/tests-clar/resources/testrepo.git/config b/tests-clar/resources/testrepo.git/config index 1a5aacdfa..b4fdac6c2 100644 --- a/tests-clar/resources/testrepo.git/config +++ b/tests-clar/resources/testrepo.git/config @@ -6,3 +6,7 @@ [remote "test"] url = git://github.com/libgit2/libgit2 fetch = +refs/heads/*:refs/remotes/test/* + +[branch "master"] + remote = test + merge = refs/heads/master diff --git a/tests/resources/testrepo.git/refs/remotes/test/master b/tests/resources/testrepo.git/refs/remotes/test/master new file mode 100644 index 000000000..9536ad89c --- /dev/null +++ b/tests/resources/testrepo.git/refs/remotes/test/master @@ -0,0 +1 @@ +be3563ae3f795b2b4353bcce3a527ad0a4f7f644 |
