Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
- Use `NEWS.md` instead of `NEWS` (@olivroy, #209)
- Add git_revert() function (#206)
- new function `git_branch_switch()`, an alias to `git_branch_checkout()` (#254)
- Add argument `depth` in `git_clone()` (#281, @etiennebacher).

# 2.3.1

Expand Down
12 changes: 12 additions & 0 deletions R/fetch.R
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,10 @@ git_push <- function(
#' @param password a string or a callback function to get passwords for authentication
#' or password protected ssh keys. Defaults to [askpass][askpass::askpass()] which
#' checks `getOption('askpass')`.
#' @param depth number of commits to fetch when creating a shallow clone. The
#' default `0` clones the entire history. A positive value truncates the history
#' to the given number of commits from the tip of each branch. Requires
#' libgit2 >= 1.7.0.
#' @param verbose display some progress info while downloading
#' @examples {# Clone a small repository
#' git_dir <- file.path(tempdir(), 'antiword')
Expand Down Expand Up @@ -220,6 +224,7 @@ git_clone <- function(
ssh_key = NULL,
bare = FALSE,
mirror = FALSE,
depth = 0,
verbose = interactive()
) {
stopifnot(is.character(url))
Expand All @@ -233,6 +238,12 @@ git_clone <- function(
}
stopifnot(is.character(path))
stopifnot(is.null(branch) || is.character(branch))
stopifnot(
"`depth` must be an integer >= 0" = is.numeric(depth) &&
length(depth) == 1 &&
depth >= 0
)
depth <- as.integer(depth)
verbose <- as.logical(verbose)
path <- normalizePath(path.expand(path), mustWork = FALSE)
host <- url_to_host(url)
Expand All @@ -247,6 +258,7 @@ git_clone <- function(
cred_cb,
bare,
mirror,
depth,
verbose
)
git_repo_path(repo)
Expand Down
6 changes: 6 additions & 0 deletions man/git_fetch.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 11 additions & 1 deletion src/clone.c
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ static int repository_enable_cache(git_repository **out, const char *path, int b
}

SEXP R_git_repository_clone(SEXP url, SEXP path, SEXP branch, SEXP getkey, SEXP getcred,
SEXP bare, SEXP mirror, SEXP verbose){
SEXP bare, SEXP mirror, SEXP depth, SEXP verbose){
git_repository *repo = NULL;
git_clone_options clone_opts = GIT_CLONE_OPTIONS_INIT;
clone_opts.checkout_opts.checkout_strategy = GIT_CHECKOUT_SAFE;
Expand All @@ -331,6 +331,16 @@ SEXP R_git_repository_clone(SEXP url, SEXP path, SEXP branch, SEXP getkey, SEXP

set_verify_handler(&clone_opts.fetch_opts.callbacks);

/* shallow clone: fetch only the last 'depth' commits (libgit2 >= 1.7) */
int clone_depth = Rf_asInteger(depth);
if(clone_depth > 0){
#if AT_LEAST_LIBGIT2(1, 7)
clone_opts.fetch_opts.depth = clone_depth;
#else
Rf_warning("Shallow clone (depth) requires libgit2 >= 1.7.0. Ignoring the depth parameter.");
#endif
}

/* Also enables download progress and user interrupt */
if(Rf_asLogical(verbose)){
clone_opts.checkout_opts.progress_cb = checkout_progress;
Expand Down
4 changes: 2 additions & 2 deletions src/init.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ extern SEXP R_git_remote_set_url(SEXP, SEXP, SEXP);
extern SEXP R_git_restore(SEXP, SEXP, SEXP);
extern SEXP R_git_revert(SEXP, SEXP);
extern SEXP R_git_repository_add(SEXP, SEXP, SEXP);
extern SEXP R_git_repository_clone(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP);
extern SEXP R_git_repository_clone(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP, SEXP);
extern SEXP R_git_repository_find(SEXP);
extern SEXP R_git_repository_info(SEXP);
extern SEXP R_git_repository_init(SEXP, SEXP);
Expand Down Expand Up @@ -140,7 +140,7 @@ static const R_CallMethodDef CallEntries[] = {
{"R_git_remote_remove", (DL_FUNC) &R_git_remote_remove, 2},
{"R_git_remote_set_url", (DL_FUNC) &R_git_remote_set_url, 3},
{"R_git_repository_add", (DL_FUNC) &R_git_repository_add, 3},
{"R_git_repository_clone", (DL_FUNC) &R_git_repository_clone, 8},
{"R_git_repository_clone", (DL_FUNC) &R_git_repository_clone, 9},
{"R_git_repository_find", (DL_FUNC) &R_git_repository_find, 1},
{"R_git_repository_info", (DL_FUNC) &R_git_repository_info, 1},
{"R_git_repository_init", (DL_FUNC) &R_git_repository_init, 2},
Expand Down
29 changes: 29 additions & 0 deletions tests/testthat/test-clone.R
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,32 @@ test_that("cloning repositories works, no path", {
repo <- git_clone('https://github.com/r-lib/gert.git')
expect_true(file.exists(file.path(path, "gert", 'DESCRIPTION')))
})

test_that("shallow cloning with depth works", {
skip_if_offline('github.com')
skip_if_not(libgit2_config()$version >= "1.7.0")
path <- file.path(tempdir(), 'gert-shallow')
on.exit(unlink(path, recursive = TRUE))
repo <- git_clone('https://github.com/r-lib/gert', path = path, depth = 1)
expect_true(file.exists(file.path(path, 'DESCRIPTION')))
expect_equal(nrow(git_log(repo = repo)), 1L)
})

test_that("git_clone() validates depth argument", {
expect_error(
git_clone('https://github.com/r-lib/gert', depth = -1),
"`depth` must be an integer >= 0"
)
expect_error(
git_clone('https://github.com/r-lib/gert', depth = NA),
"`depth` must be an integer >= 0"
)
expect_error(
git_clone('https://github.com/r-lib/gert', depth = "a"),
"`depth` must be an integer >= 0"
)
expect_error(
git_clone('https://github.com/r-lib/gert', depth = c(1, 2)),
"`depth` must be an integer >= 0"
)
})
Loading