Nothing
#' @title Snapshot the data repository (Git).
#' @export
#' @family git
#' @description Snapshot the Git data repository of a `targets` project.
#' @details A Git-backed `gittargets` data snapshot is a special kind of
#' Git commit. Every data commit is part of a branch specific to
#' the current code commit.
#' That way, when you switch branches or commits in the code,
#' `tar_git_checkout()` checks out the latest data snapshot
#' that matches the code in your workspace.
#' That way, your targets can stay up to date even as you
#' transition among multiple branches.
#' @inheritSection tar_git_init Stashing .gitignore
#' @inheritParams tar_git_status
#' @param message Optional Git commit message of the data snapshot.
#' If `NULL`, then the message is the Git commit message of the
#' matching code commit.
#' @param ref Character of length 1, reference
#' (branch name, Git SHA1 hash, etc.) of the code commit
#' that will map to the new data snapshot. Defaults to the commit
#' checked out right now.
#' @param status Logical of length 1, whether to print the project status
#' with [tar_git_status()] and ask whether a snapshot should be created.
#' @param verbose Logical of length 1, whether to print R console messages
#' confirming that a snapshot was created.
#' @param force Logical of length 1. Force checkout the data branch
#' of an existing data snapshot of the current code commit?
#' @param pack_refs Logical of length 1, whether to run `git pack-refs --all`
#' in the data store after taking the snapshot. Packing references
#' improves efficiency when the number of snapshots is large.
#' Learn more at <https://git-scm.com/docs/git-pack-refs>.
#' @examples
#' if (Sys.getenv("TAR_EXAMPLES") == "true" && tar_git_ok(verbose = FALSE)) {
#' targets::tar_dir({ # Containing code does not modify the user's filespace.
#' targets::tar_script(tar_target(data, 1))
#' targets::tar_make()
#' gert::git_init()
#' gert::git_add("_targets.R")
#' gert::git_commit("First commit")
#' tar_git_init()
#' tar_git_snapshot(status = FALSE)
#' })
#' }
tar_git_snapshot <- function(
message = NULL,
ref = "HEAD",
code = getwd(),
script = targets::tar_config_get("script"),
store = targets::tar_config_get("store"),
stash_gitignore = TRUE,
reporter = targets::tar_config_get("reporter_outdated"),
envir = parent.frame(),
callr_function = callr::r,
callr_arguments = NULL,
status = interactive(),
force = FALSE,
pack_refs = TRUE,
verbose = TRUE
) {
callr_arguments <- callr_arguments %|||% callr_args_default(
callr_function = callr_function,
reporter = reporter
)
tar_assert_file(code)
tar_assert_file(store)
targets::tar_assert_lgl(status)
targets::tar_assert_scalar(status)
targets::tar_assert_lgl(force)
targets::tar_assert_scalar(force)
targets::tar_assert_lgl(pack_refs)
targets::tar_assert_scalar(pack_refs)
targets::tar_assert_lgl(verbose)
targets::tar_assert_scalar(verbose)
tar_git_assert_repo_code(code)
tar_git_assert_commits_code(code)
tar_git_assert_repo_data(store)
log <- gert::git_log(repo = code, max = 1L)
commit <- gert::git_commit_info(repo = code, ref = ref)$id
branch <- tar_git_branch_snapshot(commit)
code_message <- gert::git_commit_info(repo = code, ref = ref)$message
# Covered in tests/interactive/test-tar_git_snapshot.R
# nocov start
if (status) {
choice <- tar_git_snapshot_menu(
commit = commit,
message = code_message,
code = code,
script = script,
store = store,
stash_gitignore = stash_gitignore,
reporter = reporter,
envir = envir,
callr_function = callr_function,
callr_arguments = callr_arguments
)
if (!identical(as.integer(choice), 1L)) {
cli_info("Snapshot skipped.", verbose = verbose)
return(invisible())
}
}
# nocov end
if (stash_gitignore) {
tar_git_gitignore_restore(repo = store)
tar_git_gitignore_stash(repo = store)
on.exit(tar_git_gitignore_unstash(repo = store))
}
tar_git_stub_write(repo = store)
if_any(
gert::git_branch_exists(branch = branch, repo = store),
tar_git_snapshot_branch_exists(branch = branch, verbose = verbose),
tar_git_snapshot_branch_create(
branch = branch,
repo = store,
verbose = verbose
)
)
tar_git_branch_checkout(branch = branch, repo = store, force = force)
cli_info("Staging data files.", verbose = verbose)
tar_git_add(files = "*", repo = store)
staged <- gert::git_status(staged = TRUE, repo = store)
staged$staged <- NULL
cli_success(
sprintf("Staged %s files in the data store.", nrow(staged)),
verbose = verbose
)
cli_info("Committing data changes.", verbose = verbose)
tar_git_commit_all(message = message %|||% code_message, repo = store)
commit <- gert::git_commit_info(repo = store)$id
cli_success(
sprintf("Created new data snapshot %s.", commit),
verbose = verbose
)
if (pack_refs) {
cli_info("Packing references.", verbose = verbose)
tar_git_pack_refs(repo = store, spinner = verbose)
}
invisible()
}
tar_git_snapshot_branch_create <- function(branch, repo, verbose) {
cli_info(sprintf("Creating data branch %s.", branch), verbose = verbose)
tar_git_branch_create(branch = branch, repo = repo)
}
tar_git_snapshot_branch_exists <- function(branch, verbose) {
cli_info(
"Data snapshot already exists for the current code commit.",
verbose = verbose
)
cli_info(
"The new data snapshot will supersede the old one in data branch:",
verbose = verbose
)
cli_indent("{.field ", branch, "}", verbose = verbose)
}
# Covered in tests/interactive/test-tar_git_snapshot.R
# nocov start
#' @title Data snapshot menu (Git)
#' @keywords internal
#' @description Check the project status and show an interactive menu
#' for [tar_git_snapshot()].
#' @return Integer of length 1: `2L` if the user agrees to snapshot,
#' `1L` if the user declines.
#' @inheritParams tar_git_snapshot
#' @param commit Character of length 1, Git SHA1 hash of the code commit
#' that will correspond to the data snapshot (if created).
#' @examples
#' # See the examples of tar_git_snapshot().
tar_git_snapshot_menu <- function(
commit,
message,
code,
script,
store,
stash_gitignore,
reporter,
envir,
callr_function,
callr_arguments
) {
tar_git_status(
code = code,
script = script,
store = store,
stash_gitignore = stash_gitignore,
reporter = reporter,
envir = envir,
callr_function = callr_function,
callr_arguments = callr_arguments
)
cli::cli_h1("Snapshot the data?")
line <- paste(
"The new snapshot will be a data commit",
"that maps to the following code commit:"
)
cli_info(line)
cli_indent(commit)
cli_indent(first_line(message))
line <- paste(
"Please make sure the code repo and",
"{.pkg targets} pipeline are clean and up to date."
)
cli_info(line)
utils::menu(c("yes", "no"))
}
# nocov end
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.