Skip to content

Commit 860ff25

Browse files
authored
Merge branch 'main' into restore
2 parents bce1d24 + 739d655 commit 860ff25

11 files changed

Lines changed: 99 additions & 51 deletions

File tree

NAMESPACE

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,6 @@ useDynLib(gert,R_git_remote_ls)
145145
useDynLib(gert,R_git_remote_push)
146146
useDynLib(gert,R_git_remote_refspecs)
147147
useDynLib(gert,R_git_remote_remove)
148-
useDynLib(gert,R_git_remote_set_pushurl)
149148
useDynLib(gert,R_git_remote_set_url)
150149
useDynLib(gert,R_git_repository_add)
151150
useDynLib(gert,R_git_repository_clone)

NEWS.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# gert (development version)
22

33
- Add `git_restore()` function (#259)
4+
- `git_remote_set_pushurl()` gains an `add` argument to append push URLs instead of replacing them. (@robitalec, #128)
45
- Fix `git_info()` for the case when no upstream is configured (@mpage, #263)
56
- `git_branch_create()`: `force` now also applies to the checkout step, allowing branch creation even when local changes would be overwritten (@MichaelChirico, #177).
67
- Improve manual pages (@olivroy, #227)

R/config.R

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
#' option is determined from global or local config.
2222
#' * `git_config_global()`: a `data.frame`, as for `git_config()`, except only
2323
#' for global Git options.
24-
#' * `git_config_set()`, `git_config_global_set()`: The previous value of
24+
#' * `git_config_set()`, `git_config_global_set()`: The previous value(s) of
2525
#' `name` in local or global config, respectively. If this option was
2626
#' previously unset, returns `NULL`. Returns invisibly.
2727
#'
@@ -76,12 +76,18 @@ git_config_global <- function() {
7676
#' @param name Name of the option to set
7777
#' @param value Value to set. Must be a string, logical, number or `NULL` (to
7878
#' unset).
79-
git_config_set <- function(name, value, repo = '.') {
79+
#' @param add if `TRUE`, append a new entry for `name` instead of replacing
80+
#' existing one(s). Equivalent to `git config --add`. Only supported for
81+
#' string values.
82+
git_config_set <- function(name, value, add = FALSE, repo = '.') {
83+
if (!is.logical(add) || length(add) != 1) {
84+
stop("Argument add must be a logical of length 1.", call. = FALSE)
85+
}
8086
repo <- git_open(repo)
8187
name <- as.character(name)
8288
orig_cfg <- git_config(repo = repo)
8389
out <- orig_cfg$value[orig_cfg$name == name & orig_cfg$level == "local"]
84-
.Call(R_git_config_set, repo, name, value)
90+
.Call(R_git_config_set, repo, name, value, add)
8591
if (length(out) > 0) {
8692
invisible(out)
8793
} else {
@@ -91,10 +97,10 @@ git_config_set <- function(name, value, repo = '.') {
9197

9298
#' @export
9399
#' @rdname git_config
94-
git_config_global_set <- function(name, value) {
100+
git_config_global_set <- function(name, value, add = FALSE) {
95101
orig_cfg <- git_config_global()
96102
out <- orig_cfg$value[orig_cfg$name == name]
97-
.Call(R_git_config_set, NULL, name, value)
103+
.Call(R_git_config_set, NULL, name, value, add)
98104
if (length(out) > 0) {
99105
invisible(out)
100106
} else {

R/remotes.R

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -68,16 +68,27 @@ git_remote_set_url <- function(url, remote = NULL, repo = '.') {
6868

6969
#' @export
7070
#' @rdname git_remote
71-
#' @useDynLib gert R_git_remote_set_pushurl
72-
git_remote_set_pushurl <- function(url, remote = NULL, repo = '.') {
71+
#' @param add if `TRUE`, append the push URL instead of replacing it.
72+
#' Equivalent to `git remote set-url --push --add`.
73+
git_remote_set_pushurl <- function(
74+
url,
75+
remote = NULL,
76+
add = FALSE,
77+
repo = '.'
78+
) {
7379
repo <- git_open(repo)
7480
remote <- as.character(remote)
7581
if (!length(remote)) {
7682
remote <- git_info(repo = repo)$remote
7783
}
7884
url <- as.character(url)
79-
.Call(R_git_remote_set_pushurl, repo, remote, url)
80-
invisible()
85+
86+
git_config_set(
87+
paste0("remote.", remote, ".pushurl"),
88+
url,
89+
repo = repo,
90+
add = add
91+
)
8192
}
8293

8394
#' @export

man/git_config.Rd

Lines changed: 7 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/git_remote.Rd

Lines changed: 4 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/branch.c

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -236,17 +236,7 @@ SEXP R_git_remote_set_url(SEXP ptr, SEXP name, SEXP url){
236236
return out;
237237
}
238238

239-
SEXP R_git_remote_set_pushurl(SEXP ptr, SEXP name, SEXP url){
240-
git_remote * remote = NULL;
241-
const char *curl = Rf_length(url) ? CHAR(STRING_ELT(url, 0)) : NULL;
242-
const char *cname = CHAR(STRING_ELT(name, 0));
243-
git_repository *repo = get_git_repository(ptr);
244-
bail_if(git_remote_lookup(&remote, repo, cname), "git_remote_lookup");
245-
bail_if(git_remote_set_pushurl(repo, cname, curl), "git_remote_set_url");
246-
SEXP out = safe_string(git_remote_pushurl(remote));
247-
git_remote_free(remote);
248-
return out;
249-
}
239+
250240

251241
SEXP R_git_remote_remove(SEXP ptr, SEXP name){
252242
const char *cname = CHAR(STRING_ELT(name, 0));

src/config.c

Lines changed: 26 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -67,33 +67,39 @@ SEXP R_git_config_list(SEXP ptr){
6767
return out;
6868
}
6969

70-
SEXP R_git_config_set(SEXP ptr, SEXP name, SEXP value){
70+
SEXP R_git_config_set(SEXP ptr, SEXP name, SEXP value, SEXP add){
7171
git_config *cfg = NULL;
7272
const char *cname = CHAR(STRING_ELT(name, 0));
7373
if(Rf_isNull(ptr)) {
7474
bail_if(git_config_open_default(&cfg), "git_config_open_default");
7575
} else {
7676
bail_if(git_repository_config(&cfg, get_git_repository(ptr)),"git_repository_config");
7777
}
78-
switch(TYPEOF(value)){
79-
case STRSXP:
80-
bail_if(git_config_set_string(cfg, cname, CHAR(STRING_ELT(value, 0))), "git_config_set_string");
81-
break;
82-
case LGLSXP:
83-
bail_if(git_config_set_bool(cfg, cname, Rf_asLogical(value)), "git_config_set_bool");
84-
break;
85-
case INTSXP:
86-
bail_if(git_config_set_int32(cfg, cname, Rf_asInteger(value)), "git_config_set_int32");
87-
break;
88-
case REALSXP:
89-
//NB: gets stored as string anyway
90-
bail_if(git_config_set_int64(cfg, cname, (int64_t) Rf_asReal(value)), "git_config_set_int64");
91-
break;
92-
case NILSXP:
93-
bail_if(git_config_delete_entry(cfg, cname), "git_config_delete_entry");
94-
break;
95-
default:
96-
Rf_error("Option value must be string, boolean, number, or NULL");
78+
if(Rf_asLogical(add)) {
79+
if(TYPEOF(value) != STRSXP)
80+
Rf_error("add = TRUE only supported for string values");
81+
bail_if(git_config_set_multivar(cfg, cname, "^$", CHAR(STRING_ELT(value, 0))), "git_config_set_multivar");
82+
} else {
83+
switch(TYPEOF(value)){
84+
case STRSXP:
85+
bail_if(git_config_set_string(cfg, cname, CHAR(STRING_ELT(value, 0))), "git_config_set_string");
86+
break;
87+
case LGLSXP:
88+
bail_if(git_config_set_bool(cfg, cname, Rf_asLogical(value)), "git_config_set_bool");
89+
break;
90+
case INTSXP:
91+
bail_if(git_config_set_int32(cfg, cname, Rf_asInteger(value)), "git_config_set_int32");
92+
break;
93+
case REALSXP:
94+
//NB: gets stored as string anyway
95+
bail_if(git_config_set_int64(cfg, cname, (int64_t) Rf_asReal(value)), "git_config_set_int64");
96+
break;
97+
case NILSXP:
98+
bail_if(git_config_delete_entry(cfg, cname), "git_config_delete_entry");
99+
break;
100+
default:
101+
Rf_error("Option value must be string, boolean, number, or NULL");
102+
}
97103
}
98104
git_config_free(cfg);
99105
return R_NilValue;

src/init.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ extern SEXP R_git_commit_info(SEXP, SEXP);
3030
extern SEXP R_git_commit_log(SEXP, SEXP, SEXP, SEXP, SEXP);
3131
extern SEXP R_git_commit_stats(SEXP, SEXP);
3232
extern SEXP R_git_config_list(SEXP);
33-
extern SEXP R_git_config_set(SEXP, SEXP, SEXP);
33+
extern SEXP R_git_config_set(SEXP, SEXP, SEXP, SEXP);
3434
extern SEXP R_git_conflict_list(SEXP);
3535
extern SEXP R_git_create_branch(SEXP, SEXP, SEXP, SEXP, SEXP);
3636
extern SEXP R_git_delete_branch(SEXP, SEXP);
@@ -51,7 +51,6 @@ extern SEXP R_git_remote_ls(SEXP, SEXP, SEXP, SEXP, SEXP);
5151
extern SEXP R_git_remote_push(SEXP, SEXP, SEXP, SEXP, SEXP, SEXP);
5252
extern SEXP R_git_remote_refspecs(SEXP, SEXP);
5353
extern SEXP R_git_remote_remove(SEXP, SEXP);
54-
extern SEXP R_git_remote_set_pushurl(SEXP, SEXP, SEXP);
5554
extern SEXP R_git_remote_set_url(SEXP, SEXP, SEXP);
5655
extern SEXP R_git_restore(SEXP, SEXP, SEXP);
5756
extern SEXP R_git_revert(SEXP, SEXP);
@@ -116,7 +115,7 @@ static const R_CallMethodDef CallEntries[] = {
116115
{"R_git_commit_log", (DL_FUNC) &R_git_commit_log, 5},
117116
{"R_git_commit_stats", (DL_FUNC) &R_git_commit_stats, 2},
118117
{"R_git_config_list", (DL_FUNC) &R_git_config_list, 1},
119-
{"R_git_config_set", (DL_FUNC) &R_git_config_set, 3},
118+
{"R_git_config_set", (DL_FUNC) &R_git_config_set, 4},
120119
{"R_git_conflict_list", (DL_FUNC) &R_git_conflict_list, 1},
121120
{"R_git_create_branch", (DL_FUNC) &R_git_create_branch, 5},
122121
{"R_git_delete_branch", (DL_FUNC) &R_git_delete_branch, 2},
@@ -137,7 +136,6 @@ static const R_CallMethodDef CallEntries[] = {
137136
{"R_git_remote_push", (DL_FUNC) &R_git_remote_push, 6},
138137
{"R_git_remote_refspecs", (DL_FUNC) &R_git_remote_refspecs, 2},
139138
{"R_git_remote_remove", (DL_FUNC) &R_git_remote_remove, 2},
140-
{"R_git_remote_set_pushurl", (DL_FUNC) &R_git_remote_set_pushurl, 3},
141139
{"R_git_remote_set_url", (DL_FUNC) &R_git_remote_set_url, 3},
142140
{"R_git_repository_add", (DL_FUNC) &R_git_repository_add, 3},
143141
{"R_git_repository_clone", (DL_FUNC) &R_git_repository_clone, 8},

tests/testthat/test-config.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ test_that("local, custom config roundtrip", {
22
repo <- git_init(tempfile("gert-tests-config"))
33
on.exit(unlink(repo, recursive = TRUE))
44

5-
orig <- git_config_set("aaa.bbb", "ccc", repo)
5+
orig <- git_config_set("aaa.bbb", "ccc", repo = repo)
66
expect_null(orig)
77
cfg <- git_config(repo)
88
expect_equal(cfg$value[cfg$name == "aaa.bbb"], "ccc")
99

10-
orig <- git_config_set("aaa.bbb", NULL, repo)
10+
orig <- git_config_set("aaa.bbb", NULL, repo = repo)
1111
expect_equal(orig, "ccc")
1212
cfg <- git_config(repo)
1313
expect_equal(cfg$value[cfg$name == "aaa.bbb"], character())

0 commit comments

Comments
 (0)