Skip to content

Commit 4a3187d

Browse files
committed
remote_ls changes from @stewid's review
- Rename to remote_ls - Check result of git2r_repository_open - Use err for error codes - Explicitly assign to err so it can be used for printing error messages - Allocate, assign and set names in one statement - Move statements after all variable definitions - Add optional credentials parameter - Fix documentation typo
1 parent 916aa33 commit 4a3187d

File tree

8 files changed

+74
-105
lines changed

8 files changed

+74
-105
lines changed

NAMESPACE

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ export(is_commit)
99
export(libgit2_features)
1010
export(libgit2_sha)
1111
export(libgit2_version)
12-
export(ls_remote)
1312
export(punch_card)
13+
export(remote_ls)
1414
exportClasses(cred_env)
1515
exportClasses(cred_ssh_key)
1616
exportClasses(cred_token)
@@ -81,7 +81,6 @@ exportMethods(is_merge)
8181
exportMethods(is_shallow)
8282
exportMethods(length)
8383
exportMethods(lookup)
84-
exportMethods(ls_remote)
8584
exportMethods(merge)
8685
exportMethods(merge_base)
8786
exportMethods(note_create)
@@ -98,6 +97,7 @@ exportMethods(push)
9897
exportMethods(references)
9998
exportMethods(reflog)
10099
exportMethods(remote_add)
100+
exportMethods(remote_ls)
101101
exportMethods(remote_remove)
102102
exportMethods(remote_rename)
103103
exportMethods(remote_set_url)

NEWS

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ git2r 0.11.0.9000
33

44
NEW FEATURES
55

6-
* Add 'ls_remote' method to list references in a remote repository.
6+
* Add 'remote_ls' method to list references in a remote repository akin to the
7+
`git ls-remote` command.
78

89
* Add 'remote_set_url' method to set the remote's url in the
910
configuration.

R/remote.r

Lines changed: 20 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -354,40 +354,34 @@ setMethod("remote_url",
354354

355355
##' List references in a remote repository
356356
##'
357-
##' Displays references available in a remote repository along with the associated commit IDs.
358-
##' @rdname ls_remote-methods
357+
##' Displays references available in a remote repository along with the
358+
##' associated commit IDs. Akin to the 'git ls-remote' command.
359+
##' @rdname remote_ls-methods
359360
##' @docType methods
360-
##' @param name Character vector with the with "remote" repository URL to query.
361-
##' @return Character vector for each reference with the associated commit IDs.
362-
##' @param repo an optional repository object used to store data temporarily.
361+
##' @param name Character vector with the "remote" repository URL to query or
362+
##the name of the remote if a \code{repo} argument is given.
363+
##' @param repo an optional repository object used if remotes are specified by name.
364+
##' @param credentials The credentials for the remote repository.
363365
##' @keywords methods
366+
##' @return Character vector for each reference with the associated commit IDs.
364367
##' @examples
365368
##' \dontrun{
366-
##' ls_remote("https://github.com/ropensci/git2r")
369+
##' remote_ls("https://github.com/ropensci/git2r")
367370
##' }
368371
##' @export
369-
setGeneric("ls_remote",
370-
signature = c("name", "repo"),
371-
function(name, repo)
372-
standardGeneric("ls_remote"))
372+
setGeneric("remote_ls",
373+
signature = c("name"),
374+
function(name,
375+
repo = git2r::init(tempdir()),
376+
credentials = NULL)
377+
standardGeneric("remote_ls"))
373378

374-
##' @rdname ls_remote-methods
375-
##' @export
376-
setMethod("ls_remote",
377-
signature(name = "character",
378-
repo = "missing"),
379-
function(name)
380-
{
381-
.Call(git2r_ls_remote, git2r::init(tempdir()), name)
382-
}
383-
)
384-
##' @rdname ls_remote-methods
379+
##' @rdname remote_ls-methods
385380
##' @export
386-
setMethod("ls_remote",
387-
signature(name = "character",
388-
repo = "git_repository"),
389-
function(name, repo)
381+
setMethod("remote_ls",
382+
signature(name = "character"),
383+
function(name, repo, credentials)
390384
{
391-
.Call(git2r_ls_remote, repo, name)
385+
.Call(git2r_remote_ls, name, repo, credentials)
392386
}
393387
)

man/ls_remote-methods.Rd

Lines changed: 0 additions & 33 deletions
This file was deleted.

src/git2r.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ static const R_CallMethodDef callMethods[] =
119119
{"git2r_remote_rename", (DL_FUNC)&git2r_remote_rename, 3},
120120
{"git2r_remote_set_url", (DL_FUNC)&git2r_remote_set_url, 3},
121121
{"git2r_remote_url", (DL_FUNC)&git2r_remote_url, 2},
122-
{"git2r_ls_remote", (DL_FUNC)&git2r_ls_remote, 2},
122+
{"git2r_remote_ls", (DL_FUNC)&git2r_remote_ls, 3},
123123
{"git2r_repository_can_open", (DL_FUNC)&git2r_repository_can_open, 1},
124124
{"git2r_repository_discover", (DL_FUNC)&git2r_repository_discover, 1},
125125
{"git2r_repository_fetch_heads", (DL_FUNC)&git2r_repository_fetch_heads, 1},

src/git2r_remote.c

Lines changed: 46 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -392,69 +392,76 @@ SEXP git2r_remote_url(SEXP repo, SEXP remote)
392392
return url;
393393
}
394394

395-
SEXP git2r_ls_remote(SEXP repo, SEXP name)
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)
396404
{
397-
if (git2r_arg_check_string(name))
398-
git2r_error(__func__, NULL, "'name'", git2r_err_string_arg);
399-
400405
const char *name_ = CHAR(STRING_ELT(name, 0));
401406
SEXP result = R_NilValue;
402407
SEXP names = R_NilValue;
403408
git_remote *remote = NULL;
404-
int error;
409+
int err;
405410
const git_remote_head **refs;
406411
size_t refs_len, i;
407412
git_remote_callbacks callbacks = GIT_REMOTE_CALLBACKS_INIT;
408-
git_repository *repo_ = NULL;
413+
git2r_transfer_data payload = GIT2R_TRANSFER_DATA_INIT;
414+
git_repository *repository = NULL;
409415

410-
repo_ = git2r_repository_open(repo);
416+
if (git2r_arg_check_string(name))
417+
git2r_error(__func__, NULL, "'name'", git2r_err_string_arg);
411418

412-
error = git_remote_lookup(&remote, repo_, name_);
413-
if (error < 0) {
414-
error = git_remote_create_anonymous(&remote, repo_, name_);
415-
if (error < 0) {
416-
goto cleanup;
417-
}
418-
}
419+
if (git2r_arg_check_credentials(credentials))
420+
git2r_error(__func__, NULL, "'credentials'", git2r_err_credentials_arg);
419421

420-
/**
421-
* Connect to the remote and call the printing function for
422-
* each of the remote references.
423-
*/
424-
callbacks.credentials = git2r_cred_acquire_cb;
422+
repository = git2r_repository_open(repo);
425423

426-
error = git_remote_connect(remote, GIT_DIRECTION_FETCH, &callbacks);
427-
if (error < 0) {
428-
goto cleanup;
429-
}
424+
if (!repository)
425+
git2r_error(__func__, NULL, git2r_err_invalid_repository, NULL);
430426

431-
/**
432-
* Get the list of references on the remote and print out
433-
* their name next to what they point to.
434-
*/
435-
if (git_remote_ls(&refs, &refs_len, remote) < 0) {
436-
goto cleanup;
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+
}
437433
}
438434

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+
439447
PROTECT(result = allocVector(STRSXP, refs_len));
440-
PROTECT(names = allocVector(STRSXP, refs_len));
448+
setAttrib(result, R_NamesSymbol, names = allocVector(STRSXP, refs_len));
441449

442450
for (i = 0; i < refs_len; i++) {
443-
char oid[GIT_OID_HEXSZ + 1] = {0};
444-
git_oid_fmt(oid, &refs[i]->oid);
445-
SET_STRING_ELT(result, i, mkChar(oid));
446-
SET_STRING_ELT(names, i, mkChar(refs[i]->name));
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));
447455
}
448-
setAttrib(result, R_NamesSymbol, names);
449456

450457
cleanup:
451-
if (repo_)
452-
git_repository_free(repo_);
458+
if (repository)
459+
git_repository_free(repository);
453460

454461
if (result != R_NilValue)
455-
UNPROTECT(2);
462+
UNPROTECT(1);
456463

457-
if (error)
464+
if (err)
458465
git2r_error(__func__, giterr_last(), NULL, NULL);
459466

460467
return(result);

src/git2r_remote.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,6 @@ SEXP git2r_remote_remove(SEXP repo, SEXP remote);
3333
SEXP git2r_remote_rename(SEXP repo, SEXP oldname, SEXP newname);
3434
SEXP git2r_remote_set_url(SEXP repo, SEXP name, SEXP url);
3535
SEXP git2r_remote_url(SEXP repo, SEXP remote);
36-
SEXP git2r_ls_remote(SEXP repo, SEXP name);
36+
SEXP git2r_remote_ls(SEXP name, SEXP repo, SEXP credentials);
3737

3838
#endif

tests/remotes.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,13 +56,13 @@ remote_remove(repo, "foobar")
5656

5757
stopifnot(identical(remotes(repo), character(0)))
5858

59-
refs <- ls_remote("https://github.com/ropensci/git2r")
59+
refs <- remote_ls("https://github.com/ropensci/git2r")
6060
stopifnot(length(refs) > 0)
6161
stopifnot(names(refs) > 0)
6262
stopifnot(any(names(refs) == "HEAD"))
6363

6464
# an invalid URL should throw an error
65-
tools::assertError(ls_remote("bad"))
65+
tools::assertError(remote_ls("bad"))
6666

6767
## Cleanup
6868
unlink(path, recursive=TRUE)

0 commit comments

Comments
 (0)