@@ -217,57 +217,79 @@ static int ensure_remote_doesnot_exist(git_repository *repo, const char *name)
217217 return GIT_EEXISTS ;
218218}
219219
220- static int create_internal ( git_remote * * out , git_repository * repo , const char * name , const char * url , const char * fetch )
220+ int git_remote_create_init_options ( git_remote_create_options * opts , unsigned int version )
221221{
222- git_remote * remote ;
222+ GIT_INIT_STRUCTURE_FROM_TEMPLATE (
223+ opts , version , git_remote_create_options , GIT_REMOTE_CREATE_OPTIONS_INIT );
224+ return 0 ;
225+ }
226+
227+ static int create_internal (git_remote * * out , const char * url , const git_remote_create_options * opts )
228+ {
229+ git_remote * remote = NULL ;
223230 git_config * config_ro = NULL , * config_rw ;
224231 git_buf canonical_url = GIT_BUF_INIT ;
225232 git_buf var = GIT_BUF_INIT ;
233+ const git_remote_create_options dummy_opts = GIT_REMOTE_CREATE_OPTIONS_INIT ;
226234 int error = -1 ;
227235
228- /* repo, name, and fetch are optional */
229236 assert (out && url );
230237
231- if (repo && (error = git_repository_config_snapshot (& config_ro , repo )) < 0 )
232- return error ;
238+ if (!opts ) {
239+ opts = & dummy_opts ;
240+ }
241+
242+ GITERR_CHECK_VERSION (opts , GIT_REMOTE_CREATE_OPTIONS_VERSION , "git_remote_create_options" );
243+
244+ if (opts -> name != NULL ) {
245+ if ((error = ensure_remote_name_is_valid (opts -> name )) < 0 )
246+ return error ;
247+
248+ if (opts -> repository &&
249+ (error = ensure_remote_doesnot_exist (opts -> repository , opts -> name )) < 0 )
250+ return error ;
251+ }
252+
253+ if (opts -> repository ) {
254+ if ((error = git_repository_config_snapshot (& config_ro , opts -> repository )) < 0 )
255+ goto on_error ;
256+ }
233257
234258 remote = git__calloc (1 , sizeof (git_remote ));
235259 GITERR_CHECK_ALLOC (remote );
236260
237- remote -> repo = repo ;
261+ remote -> repo = opts -> repository ;
238262
239263 if ((error = git_vector_init (& remote -> refs , 32 , NULL )) < 0 ||
240264 (error = canonicalize_url (& canonical_url , url )) < 0 )
241265 goto on_error ;
242266
243- if (repo ) {
267+ if (opts -> repository ) {
244268 remote -> url = apply_insteadof (config_ro , canonical_url .ptr , GIT_DIRECTION_FETCH );
245269 } else {
246270 remote -> url = git__strdup (canonical_url .ptr );
247271 }
248272 GITERR_CHECK_ALLOC (remote -> url );
249273
250- if (name != NULL ) {
251- remote -> name = git__strdup (name );
274+ if (opts -> name != NULL ) {
275+ remote -> name = git__strdup (opts -> name );
252276 GITERR_CHECK_ALLOC (remote -> name );
253277
254- if ((error = git_buf_printf (& var , CONFIG_URL_FMT , name )) < 0 )
255- goto on_error ;
256-
257- if (repo &&
258- ((error = git_repository_config__weakptr (& config_rw , repo )) < 0 ||
259- (error = git_config_set_string (config_rw , var .ptr , canonical_url .ptr )) < 0 ))
278+ if (opts -> repository &&
279+ ((error = git_buf_printf (& var , CONFIG_URL_FMT , opts -> name )) < 0 ||
280+ (error = git_repository_config__weakptr (& config_rw , opts -> repository )) < 0 ||
281+ (error = git_config_set_string (config_rw , var .ptr , canonical_url .ptr )) < 0 ))
260282 goto on_error ;
261283 }
262284
263- if (fetch != NULL ) {
264- if ((error = add_refspec (remote , fetch , true)) < 0 )
285+ if (opts -> fetchspec != NULL ) {
286+ if ((error = add_refspec (remote , opts -> fetchspec , true)) < 0 )
265287 goto on_error ;
266288
267289 /* only write for named remotes with a repository */
268- if (repo && name &&
269- ((error = write_add_refspec (repo , name , fetch , true)) < 0 ||
270- (error = lookup_remote_prune_config (remote , config_ro , name )) < 0 ))
290+ if (opts -> repository && opts -> name &&
291+ ((error = write_add_refspec (opts -> repository , opts -> name , opts -> fetchspec , true)) < 0 ||
292+ (error = lookup_remote_prune_config (remote , config_ro , opts -> name )) < 0 ))
271293 goto on_error ;
272294
273295 /* Move the data over to where the matching functions can find them */
@@ -276,7 +298,7 @@ static int create_internal(git_remote **out, git_repository *repo, const char *n
276298 }
277299
278300 /* A remote without a name doesn't download tags */
279- if (!name )
301+ if (!opts -> name )
280302 remote -> download_tags = GIT_REMOTE_DOWNLOAD_TAGS_NONE ;
281303 else
282304 remote -> download_tags = GIT_REMOTE_DOWNLOAD_TAGS_AUTO ;
@@ -301,47 +323,60 @@ int git_remote_create(git_remote **out, git_repository *repo, const char *name,
301323{
302324 git_buf buf = GIT_BUF_INIT ;
303325 int error ;
326+ git_remote_create_options opts = GIT_REMOTE_CREATE_OPTIONS_INIT ;
304327
305- if (default_fetchspec_for_name (& buf , name ) < 0 )
306- return -1 ;
328+ /* Those 2 tests are duplicated here because of backward-compatibility */
329+ if ((error = ensure_remote_name_is_valid (name )) < 0 )
330+ return error ;
331+
332+ if (canonicalize_url (& buf , url ) < 0 )
333+ return GIT_ERROR ;
334+
335+ git_buf_clear (& buf );
336+
337+ opts .repository = repo ;
338+ opts .name = name ;
339+ opts .fetchspec = git_buf_cstr (& buf );
340+
341+ error = create_internal (out , url , & opts );
307342
308- error = git_remote_create_with_fetchspec (out , repo , name , url , git_buf_cstr (& buf ));
309343 git_buf_dispose (& buf );
310344
311345 return error ;
312346}
313347
348+ int git_remote_create_with_opts (git_remote * * out , const char * url , const git_remote_create_options * opts )
349+ {
350+ return create_internal (out , url , opts );
351+ }
352+
314353int git_remote_create_with_fetchspec (git_remote * * out , git_repository * repo , const char * name , const char * url , const char * fetch )
315354{
316- git_remote * remote = NULL ;
317355 int error ;
356+ git_remote_create_options opts = GIT_REMOTE_CREATE_OPTIONS_INIT ;
318357
319358 if ((error = ensure_remote_name_is_valid (name )) < 0 )
320359 return error ;
321360
322- if ((error = ensure_remote_doesnot_exist (repo , name )) < 0 )
323- return error ;
324-
325- if (create_internal (& remote , repo , name , url , fetch ) < 0 )
326- goto on_error ;
327-
328- * out = remote ;
329-
330- return 0 ;
361+ opts .repository = repo ;
362+ opts .name = name ;
363+ opts .fetchspec = fetch ;
331364
332- on_error :
333- git_remote_free (remote );
334- return -1 ;
365+ return create_internal (out , url , & opts );
335366}
336367
337368int git_remote_create_anonymous (git_remote * * out , git_repository * repo , const char * url )
338369{
339- return create_internal (out , repo , NULL , url , NULL );
370+ git_remote_create_options opts = GIT_REMOTE_CREATE_OPTIONS_INIT ;
371+
372+ opts .repository = repo ;
373+
374+ return create_internal (out , url , & opts );
340375}
341376
342377int git_remote_create_detached (git_remote * * out , const char * url )
343378{
344- return create_internal (out , NULL , NULL , url , NULL );
379+ return create_internal (out , url , NULL );
345380}
346381
347382int git_remote_dup (git_remote * * dest , git_remote * source )
0 commit comments