summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarlos Martín Nieto <cmn@dwim.me>2015-05-18 14:42:35 +0200
committerCarlos Martín Nieto <cmn@dwim.me>2015-05-28 15:32:20 +0200
commit9566ce430fde97d5e610bb2796d27d47e1e81ab5 (patch)
treefea7d88cf62666d53dd5c68cc630d0d434979346 /src
parentc6e942fb3d10d9f8f2e22833ddddbd945c0d6604 (diff)
downloadlibgit2-9566ce430fde97d5e610bb2796d27d47e1e81ab5.tar.gz
remote: call the update_tips callback for opportunisitc updates
These are updates, same as the rest, we should call this callback. As we are using the callback, let's make sure to skip unnecessary updates.
Diffstat (limited to 'src')
-rw-r--r--src/remote.c40
1 files changed, 31 insertions, 9 deletions
diff --git a/src/remote.c b/src/remote.c
index 99b5bacc0..43b34561d 100644
--- a/src/remote.c
+++ b/src/remote.c
@@ -1453,18 +1453,20 @@ static int next_head(const git_remote *remote, git_vector *refs,
return GIT_ITEROVER;
}
-static int opportunistic_updates(const git_remote *remote, git_vector *refs, const char *msg)
+static int opportunistic_updates(const git_remote *remote, const git_remote_callbacks *callbacks,
+ git_vector *refs, const char *msg)
{
size_t i, j, k;
git_refspec *spec;
git_remote_head *head;
git_reference *ref;
git_buf refname = GIT_BUF_INIT;
- int error;
+ int error = 0;
i = j = k = 0;
while ((error = next_head(remote, refs, &spec, &head, &i, &j, &k)) == 0) {
+ git_oid old = {{ 0 }};
/*
* If we got here, there is a refspec which was used
* for fetching which matches the source of one of the
@@ -1473,18 +1475,38 @@ static int opportunistic_updates(const git_remote *remote, git_vector *refs, con
* FETCH_HEAD
*/
+ git_buf_clear(&refname);
if ((error = git_refspec_transform(&refname, spec, head->name)) < 0)
- return error;
+ goto cleanup;
- error = git_reference_create(&ref, remote->repo, refname.ptr, &head->oid, true, msg);
- git_buf_free(&refname);
- git_reference_free(ref);
+ error = git_reference_name_to_id(&old, remote->repo, refname.ptr);
+ if (error < 0 && error != GIT_ENOTFOUND)
+ goto cleanup;
+
+ if (!git_oid_cmp(&old, &head->oid))
+ continue;
+ /* If we did find a current reference, make sure we haven't lost a race */
+ if (error)
+ error = git_reference_create(&ref, remote->repo, refname.ptr, &head->oid, true, msg);
+ else
+ error = git_reference_create_matching(&ref, remote->repo, refname.ptr, &head->oid, true, &old, msg);
+ git_reference_free(ref);
if (error < 0)
- return error;
+ goto cleanup;
+
+ if (callbacks && callbacks->update_tips != NULL) {
+ if (callbacks->update_tips(refname.ptr, &old, &head->oid, callbacks->payload) < 0)
+ goto cleanup;
+ }
}
- return 0;
+ if (error == GIT_ITEROVER)
+ error = 0;
+
+cleanup:
+ git_buf_free(&refname);
+ return error;
}
int git_remote_update_tips(
@@ -1532,7 +1554,7 @@ int git_remote_update_tips(
/* only try to do opportunisitic updates if the refpec lists differ */
if (remote->passed_refspecs)
- error = opportunistic_updates(remote, &refs, reflog_message);
+ error = opportunistic_updates(remote, callbacks, &refs, reflog_message);
out:
git_vector_free(&refs);