]>
git.proxmox.com Git - libgit2.git/blob - src/remote.c
2 * Copyright (C) 2009-2011 the libgit2 contributors
4 * This file is part of libgit2, distributed under the GNU GPL v2 with
5 * a Linking Exception. For full terms see the included COPYING file.
8 #include "git2/remote.h"
9 #include "git2/config.h"
10 #include "git2/types.h"
13 #include "repository.h"
18 static int refspec_parse(git_refspec
*refspec
, const char *str
)
22 memset(refspec
, 0x0, sizeof(git_refspec
));
29 delim
= strchr(str
, ':');
31 return git__throw(GIT_EOBJCORRUPTED
, "Failed to parse refspec. No ':'");
33 refspec
->src
= git__strndup(str
, delim
- str
);
34 if (refspec
->src
== NULL
)
37 refspec
->dst
= git__strdup(delim
+ 1);
38 if (refspec
->dst
== NULL
) {
47 static int parse_remote_refspec(git_config
*cfg
, git_refspec
*refspec
, const char *var
)
52 error
= git_config_get_string(cfg
, var
, &val
);
53 if (error
< GIT_SUCCESS
)
56 return refspec_parse(refspec
, val
);
59 int git_remote_new(git_remote
**out
, git_repository
*repo
, const char *url
)
63 remote
= git__malloc(sizeof(git_remote
));
67 memset(remote
, 0x0, sizeof(git_remote
));
69 remote
->url
= git__strdup(url
);
70 if (remote
->url
== NULL
) {
79 int git_remote_get(git_remote
**out
, git_config
*cfg
, const char *name
)
84 int ret
, error
, buf_len
;
86 remote
= git__malloc(sizeof(git_remote
));
90 memset(remote
, 0x0, sizeof(git_remote
));
91 remote
->name
= git__strdup(name
);
92 if (remote
->name
== NULL
) {
97 /* "fetch" is the longest var name we're interested in */
98 buf_len
= strlen("remote.") + strlen(".fetch") + strlen(name
) + 1;
99 buf
= git__malloc(buf_len
);
105 ret
= p_snprintf(buf
, buf_len
, "%s.%s.%s", "remote", name
, "url");
107 error
= git__throw(GIT_EOSERR
, "Failed to build config var name");
111 error
= git_config_get_string(cfg
, buf
, &val
);
112 if (error
< GIT_SUCCESS
) {
113 error
= git__rethrow(error
, "Remote's url doesn't exist");
117 remote
->repo
= cfg
->repo
;
118 remote
->url
= git__strdup(val
);
119 if (remote
->url
== NULL
) {
124 ret
= p_snprintf(buf
, buf_len
, "%s.%s.%s", "remote", name
, "fetch");
126 error
= git__throw(GIT_EOSERR
, "Failed to build config var name");
130 error
= parse_remote_refspec(cfg
, &remote
->fetch
, buf
);
131 if (error
< GIT_SUCCESS
) {
132 error
= git__rethrow(error
, "Failed to get fetch refspec");
136 ret
= p_snprintf(buf
, buf_len
, "%s.%s.%s", "remote", name
, "push");
138 error
= git__throw(GIT_EOSERR
, "Failed to build config var name");
142 error
= parse_remote_refspec(cfg
, &remote
->push
, buf
);
143 /* Not finding push is fine */
144 if (error
== GIT_ENOTFOUND
)
147 if (error
< GIT_SUCCESS
)
154 if (error
< GIT_SUCCESS
)
155 git_remote_free(remote
);
160 const char *git_remote_name(struct git_remote
*remote
)
165 const char *git_remote_url(struct git_remote
*remote
)
170 const git_refspec
*git_remote_fetchspec(struct git_remote
*remote
)
172 return &remote
->fetch
;
175 const git_refspec
*git_remote_pushspec(struct git_remote
*remote
)
177 return &remote
->push
;
180 int git_remote_connect(git_remote
*remote
, int direction
)
185 error
= git_transport_new(&t
, remote
->url
);
186 if (error
< GIT_SUCCESS
)
187 return git__rethrow(error
, "Failed to create transport");
189 error
= t
->connect(t
, direction
);
190 if (error
< GIT_SUCCESS
) {
191 error
= git__rethrow(error
, "Failed to connect the transport");
195 remote
->transport
= t
;
198 if (error
< GIT_SUCCESS
)
204 int git_remote_ls(git_remote
*remote
, git_headarray
*refs
)
206 return remote
->transport
->ls(remote
->transport
, refs
);
209 int git_remote_negotiate(git_remote
*remote
)
211 return git_fetch_negotiate(remote
);
214 int git_remote_download(char **filename
, git_remote
*remote
)
216 return git_fetch_download_pack(filename
, remote
);
219 git_headarray
*git_remote_tips(git_remote
*remote
)
221 return &remote
->refs
;
224 int git_remote_update_tips(struct git_remote
*remote
)
226 int error
= GIT_SUCCESS
;
228 char refname
[GIT_PATH_MAX
];
229 git_headarray
*refs
= &remote
->refs
;
230 git_remote_head
*head
;
232 struct git_refspec
*spec
= &remote
->fetch
;
234 memset(refname
, 0x0, sizeof(refname
));
236 for (i
= 0; i
< refs
->len
; ++i
) {
237 head
= refs
->heads
[i
];
238 error
= git_refspec_transform(refname
, sizeof(refname
), spec
, head
->name
);
239 if (error
< GIT_SUCCESS
)
242 error
= git_reference_create_oid(&ref
, remote
->repo
, refname
, &head
->oid
, 1);
243 if (error
< GIT_SUCCESS
)
250 void git_remote_free(git_remote
*remote
)
252 free(remote
->fetch
.src
);
253 free(remote
->fetch
.dst
);
254 free(remote
->push
.src
);
255 free(remote
->push
.dst
);
258 if (remote
->transport
!= NULL
) {
259 if (remote
->transport
->connected
)
260 remote
->transport
->close(remote
->transport
);
262 remote
->transport
->free(remote
->transport
);