@@ -391,3 +391,78 @@ SEXP git2r_remote_url(SEXP repo, SEXP remote)
391391
392392 return url ;
393393}
394+
395+ /**
396+ * Get the remote's url
397+ *
398+ * Based on https://github.com/libgit2/libgit2/blob/babdc376c7/examples/network/ls-remote.c
399+ * @param repo S4 class git_repository
400+ * @param name Character vector with URL of remote.
401+ * @return Character vector for each reference with the associated commit IDs.
402+ */
403+ SEXP git2r_remote_ls (SEXP name , SEXP repo , SEXP credentials )
404+ {
405+ const char * name_ = CHAR (STRING_ELT (name , 0 ));
406+ SEXP result = R_NilValue ;
407+ SEXP names = R_NilValue ;
408+ git_remote * remote = NULL ;
409+ int err ;
410+ const git_remote_head * * refs ;
411+ size_t refs_len , i ;
412+ git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT ;
413+ git2r_transfer_data payload = GIT2R_TRANSFER_DATA_INIT ;
414+ git_repository * repository = NULL ;
415+
416+ if (git2r_arg_check_string (name ))
417+ git2r_error (__func__ , NULL , "'name'" , git2r_err_string_arg );
418+
419+ if (git2r_arg_check_credentials (credentials ))
420+ git2r_error (__func__ , NULL , "'credentials'" , git2r_err_credentials_arg );
421+
422+ repository = git2r_repository_open (repo );
423+
424+ if (!repository )
425+ git2r_error (__func__ , NULL , git2r_err_invalid_repository , NULL );
426+
427+ err = git_remote_lookup (& remote , repository , name_ );
428+ if (err < 0 ) {
429+ err = git_remote_create_anonymous (& remote , repository , name_ );
430+ if (err < 0 ) {
431+ goto cleanup ;
432+ }
433+ }
434+
435+ payload .credentials = credentials ;
436+ callbacks .payload = & payload ;
437+ callbacks .credentials = & git2r_cred_acquire_cb ;
438+
439+ err = git_remote_connect (remote , GIT_DIRECTION_FETCH , & callbacks );
440+ if (err < 0 )
441+ goto cleanup ;
442+
443+ err = git_remote_ls (& refs , & refs_len , remote );
444+ if (err < 0 )
445+ goto cleanup ;
446+
447+ PROTECT (result = allocVector (STRSXP , refs_len ));
448+ setAttrib (result , R_NamesSymbol , names = allocVector (STRSXP , refs_len ));
449+
450+ for (i = 0 ; i < refs_len ; i ++ ) {
451+ char oid [GIT_OID_HEXSZ + 1 ] = {0 };
452+ git_oid_fmt (oid , & refs [i ]-> oid );
453+ SET_STRING_ELT (result , i , mkChar (oid ));
454+ SET_STRING_ELT (names , i , mkChar (refs [i ]-> name ));
455+ }
456+
457+ cleanup :
458+ if (repository )
459+ git_repository_free (repository );
460+
461+ if (result != R_NilValue )
462+ UNPROTECT (1 );
463+
464+ if (err )
465+ git2r_error (__func__ , giterr_last (), NULL , NULL );
466+
467+ return (result );
468+ }
0 commit comments