Merge pull request #676 from carlosmn/remotes Add git_remote_add() and change signature for _new()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198
diff --git a/examples/network/fetch.c b/examples/network/fetch.c
index 23046bd..f4a0449 100644
--- a/examples/network/fetch.c
+++ b/examples/network/fetch.c
@@ -69,7 +69,7 @@ int fetch(git_repository *repo, int argc, char **argv)
// Figure out whether it's a named remote or a URL
printf("Fetching %s\n", argv[1]);
if (git_remote_load(&remote, repo, argv[1]) < 0) {
- if (git_remote_new(&remote, repo, argv[1], NULL) < 0)
+ if (git_remote_new(&remote, repo, NULL, argv[1], NULL) < 0)
return -1;
}
diff --git a/examples/network/ls-remote.c b/examples/network/ls-remote.c
index 02d432e..958a886 100644
--- a/examples/network/ls-remote.c
+++ b/examples/network/ls-remote.c
@@ -19,7 +19,7 @@ int use_unnamed(git_repository *repo, const char *url)
// Create an instance of a remote from the URL. The transport to use
// is detected from the URL
- error = git_remote_new(&remote, repo, url, NULL);
+ error = git_remote_new(&remote, repo, NULL, url, NULL);
if (error < GIT_SUCCESS)
goto cleanup;
diff --git a/include/git2/remote.h b/include/git2/remote.h
index e81e25f..6550cd2 100644
--- a/include/git2/remote.h
+++ b/include/git2/remote.h
@@ -38,11 +38,12 @@ GIT_BEGIN_DECL
*
* @param out pointer to the new remote object
* @param repo the associtated repository
- * @param url the remote repository's URL
* @param name the remote's name
+ * @param url the remote repository's URL
+ * @param fetch the fetch refspec to use for this remote
* @return GIT_SUCCESS or an error code
*/
-GIT_EXTERN(int) git_remote_new(git_remote **out, git_repository *repo, const char *url, const char *name);
+GIT_EXTERN(int) git_remote_new(git_remote **out, git_repository *repo, const char *name, const char *url, const char *fetch);
/**
* Get the information for a particular remote
@@ -218,6 +219,16 @@ GIT_EXTERN(int) git_remote_supported_url(const char* url);
*/
GIT_EXTERN(int) git_remote_list(git_strarray *remotes_list, git_repository *repo);
+/**
+ * Add a remote with the default fetch refspec to the repository's configuration
+ *
+ * @param out the resulting remote
+ * @param repo the repository in which to create the remote
+ * @param name the remote's name
+ * @param url the remote's url
+ */
+GIT_EXTERN(int) git_remote_add(git_remote **out, git_repository *repo, const char *name, const char *url);
+
/** @} */
GIT_END_DECL
#endif
diff --git a/src/config_file.c b/src/config_file.c
index 746d965..4ccec2b 100644
--- a/src/config_file.c
+++ b/src/config_file.c
@@ -258,18 +258,17 @@ static int config_set(git_config_file *cfg, const char *name, const char *value)
GITERR_CHECK_ALLOC(var->value);
}
+ if (config_write(b, key, NULL, value) < 0) {
+ cvar_free(var);
+ return -1;
+ }
+
git_strmap_insert2(b->values, key, var, old_var, rval);
if (rval < 0)
return -1;
if (old_var != NULL)
cvar_free(old_var);
- if (config_write(b, key, NULL, value) < 0) {
- git_strmap_delete(b->values, var->key);
- cvar_free(var);
- return -1;
- }
-
return 0;
}
@@ -1018,6 +1017,7 @@ static int config_write(diskfile_backend *cfg, const char *key, const regex_t *p
pre_end = post_start = cfg->reader.read_ptr;
git__free(current_section);
+ current_section = NULL;
if (parse_section_header(cfg, ¤t_section) < 0)
goto rewrite_fail;
diff --git a/src/remote.c b/src/remote.c
index 6a1390d..a5cfc82 100644
--- a/src/remote.c
+++ b/src/remote.c
@@ -54,7 +54,7 @@ static int parse_remote_refspec(git_config *cfg, git_refspec *refspec, const cha
return refspec_parse(refspec, val);
}
-int git_remote_new(git_remote **out, git_repository *repo, const char *url, const char *name)
+int git_remote_new(git_remote **out, git_repository *repo, const char *name, const char *url, const char *fetch)
{
git_remote *remote;
@@ -78,8 +78,17 @@ int git_remote_new(git_remote **out, git_repository *repo, const char *url, cons
GITERR_CHECK_ALLOC(remote->name);
}
+ if (fetch != NULL) {
+ if (refspec_parse(&remote->fetch, fetch) < 0)
+ goto on_error;
+ }
+
*out = remote;
return 0;
+
+on_error:
+ git_remote_free(remote);
+ return -1;
}
int git_remote_load(git_remote **out, git_repository *repo, const char *name)
@@ -476,3 +485,26 @@ int git_remote_list(git_strarray *remotes_list, git_repository *repo)
return 0;
}
+
+int git_remote_add(git_remote **out, git_repository *repo, const char *name, const char *url)
+{
+ git_buf buf = GIT_BUF_INIT;
+
+ if (git_buf_printf(&buf, "refs/heads/*:refs/remotes/%s/*", name) < 0)
+ return -1;
+
+ if (git_remote_new(out, repo, name, url, git_buf_cstr(&buf)) < 0)
+ goto on_error;
+
+ git_buf_free(&buf);
+
+ if (git_remote_save(*out) < 0)
+ goto on_error;
+
+ return 0;
+
+on_error:
+ git_buf_free(&buf);
+ git_remote_free(*out);
+ return -1;
+}
diff --git a/tests-clar/network/remotelocal.c b/tests-clar/network/remotelocal.c
index e154226..35fa072 100644
--- a/tests-clar/network/remotelocal.c
+++ b/tests-clar/network/remotelocal.c
@@ -85,7 +85,7 @@ static void connect_to_local_repository(const char *local_repository)
{
build_local_file_url(&file_path_buf, local_repository);
- cl_git_pass(git_remote_new(&remote, repo, git_buf_cstr(&file_path_buf), NULL));
+ cl_git_pass(git_remote_new(&remote, repo, NULL, git_buf_cstr(&file_path_buf), NULL));
cl_git_pass(git_remote_connect(remote, GIT_DIR_FETCH));
}
diff --git a/tests-clar/network/remotes.c b/tests-clar/network/remotes.c
index f03d983..0649c86 100644
--- a/tests-clar/network/remotes.c
+++ b/tests-clar/network/remotes.c
@@ -78,7 +78,7 @@ void test_network_remotes__save(void)
git_remote_free(_remote);
/* Set up the remote and save it to config */
- cl_git_pass(git_remote_new(&_remote, _repo, "git://github.com/libgit2/libgit2", "upstream"));
+ cl_git_pass(git_remote_new(&_remote, _repo, "upstream", "git://github.com/libgit2/libgit2", NULL));
cl_git_pass(git_remote_set_fetchspec(_remote, "refs/heads/*:refs/remotes/upstream/*"));
cl_git_pass(git_remote_set_pushspec(_remote, "refs/heads/*:refs/heads/*"));
cl_git_pass(git_remote_save(_remote));
@@ -158,3 +158,15 @@ void test_network_remotes__loading_a_missing_remote_returns_ENOTFOUND(void)
{
cl_assert_equal_i(GIT_ENOTFOUND, git_remote_load(&_remote, _repo, "just-left-few-minutes-ago"));
}
+
+void test_network_remotes__add(void)
+{
+ git_remote_free(_remote);
+ cl_git_pass(git_remote_add(&_remote, _repo, "addtest", "http://github.com/libgit2/libgit2"));
+ git_remote_free(_remote);
+
+ cl_git_pass(git_remote_load(&_remote, _repo, "addtest"));
+ _refspec = git_remote_fetchspec(_remote);
+ cl_assert(!strcmp(git_refspec_src(_refspec), "refs/heads/*"));
+ cl_assert(!strcmp(git_refspec_dst(_refspec), "refs/remotes/addtest/*"));
+}