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 @@ -5,6 +5,7 @@
* `pr_pull()`, `pr_push()` and friends now give more informative errors if usethis can't retrieve details about a remote (#1929, #2229).

* `use_readme_qmd()` creates a starter `README.qmd` with Quarto-flavored YAML frontmatter, analogous to `use_readme_rmd()` (#1671). Thanks @VisruthSK for getting the ball rolling.
* Functions that check for uncommitted changes (like `pr_init()`) now offer a menu with four options: stash changes (and re-apply after), cancel, retry, or proceed anyway. Previously, the only options were to proceed or cancel (#1300).

* `use_pipe()` is now deprecated (@math-mcshane, #2124).

Expand Down
64 changes: 53 additions & 11 deletions R/utils-git.R
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,11 @@ git_uncommitted <- function(untracked = FALSE) {
nrow(git_status(untracked)) > 0
}

challenge_uncommitted_changes <- function(untracked = FALSE, msg = NULL) {
challenge_uncommitted_changes <- function(
untracked = FALSE,
msg = NULL,
error_call = caller_env()
) {
if (!uses_git()) {
return(invisible())
}
Expand All @@ -199,22 +203,60 @@ challenge_uncommitted_changes <- function(untracked = FALSE, msg = NULL) {

default_msg <- "
There are uncommitted changes, which may cause problems or be lost when \\
we push, pull, switch, or compare branches"
we push, pull, switch, or compare branches."
msg <- glue(msg %||% default_msg)
if (git_uncommitted(untracked = untracked)) {
if (
ui_yep(c(
"!" = msg,
" " = "Do you want to proceed anyway?"
))
) {

while (git_uncommitted(untracked = untracked)) {
if (!is_interactive()) {
ui_abort(
"
There are uncommitted changes.
Please commit or stash before continuing.",
call = error_call
)
}

cli::cli_inform(c("!" = msg))
choice <- utils::menu(
title = "What do you want to do?",
choices = c(
"Cancel",
"Try again",
"Stash changes, re-try, then pop",
"Proceed anyway"
)
)

if (choice == 0 || choice == 1) {
ui_abort("Cancelling.", call = error_call)
} else if (choice == 2) {
# Loop will re-check git_uncommitted()
} else if (choice == 3) {
gert::git_stash_save(include_untracked = untracked, repo = git_repo())
ui_bullets(c("v" = "Changes stashed."))
withr::defer(git_stash_pop(), envir = parent.frame())
return(invisible())
} else if (choice == 4) {
return(invisible())
} else {
ui_abort("Uncommitted changes. Please commit before continuing.")
}
}
}

git_stash_pop <- function() {
tryCatch(
{
gert::git_stash_pop(repo = git_repo())
ui_bullets(c("v" = "Stashed changes re-applied."))
},
error = function(e) {
ui_bullets(c(
"!" = "Could not re-apply stashed changes automatically.",
"i" = "Use {.run gert::git_stash_pop()} to manually re-apply."
))
}
)
}

git_conflict_report <- function() {
st <- git_status(untracked = FALSE)
conflicted <- st$file[st$status == "conflicted"]
Expand Down
Loading