如何从 R 脚本中提交对 GitHub 的更改?

How can I commit changes to GitHub from within a R script?

我正在尝试从 R 脚本中自动执行一些基本的 git 操作。我在 Windows OS 上使用 Rstudio。例如,如果您希望在脚本完成执行某些自动化任务时更新 GitHub,这可能会有所帮助。

我写了一些简单的函数,利用 R 的 shell() 函数和 Window 的 & 管道运算符将命令链发送到 OS 终端:

# Git status.
gitstatus <- function(dir = getwd()){
  cmd_list <- list(
    cmd1 = tolower(substr(dir,1,2)),
    cmd2 = paste("cd",dir),
    cmd3 = "git status"
  )
  cmd <- paste(unlist(cmd_list),collapse = " & ")
  shell(cmd)
}

# Git add.
gitadd <- function(dir = getwd()){
  cmd_list <- list(
    cmd1 = tolower(substr(dir,1,2)),
    cmd2 = paste("cd",dir),
    cmd3 = "git add --all"
  )
  cmd <- paste(unlist(cmd_list),collapse = " & ")
  shell(cmd)
}

# Git commit.
gitcommit <- function(msg = "commit from Rstudio", dir = getwd()){
  cmd_list <- list(
    cmd1 = tolower(substr(dir,1,2)),
    cmd2 = paste("cd",dir),
    cmd3 = paste0("git commit -am ","'",msg,"'")
  )
  cmd <- paste(unlist(cmd_list),collapse = " & ")
  shell(cmd)
}

# Git push.
gitpush <- function(dir = getwd()){
  cmd_list <- list(
    cmd1 = tolower(substr(dir,1,2)),
    cmd2 = paste("cd",dir),
    cmd3 = "git push"
  )
  cmd <- paste(unlist(cmd_list),collapse = " & ")
  shell(cmd)
}

我的 gitstatusgitaddgitpush 功能有效。 gitcommit 函数不起作用。它会生成以下错误:

fatal: Paths with -a does not make sense.
Warning message:
In shell(cmd) : 'd: & cd D:/Documents/R/my_path & git commit -am 'commit from Rstudio'' execution failed with error code 128

gitpush 函数之所以起作用,是因为如果您切换到终端或在 Rstudio 中 git,您可以提交更改,然后成功调用 gitpush

关于如何解决这个问题有什么想法吗?

...

注意:我安装了Gitbash,在Windows命令终端可以成功使用git和 Rstudio。我还尝试了另一种策略,即让 R 编写一个临时 .bat 文件然后执行它,但该策略也会在提交步骤中挂起。

根据我在 this Ask Ubuntu question 中阅读的内容,您应该使用 && 而不是 & 来分隔 Git bash 中的多个命令.尝试这样做:

gitcommit <- function(msg = "commit from Rstudio", dir = getwd()) {
    cmd_list <- list(
        cmd1 = tolower(substr(dir, 1, 2)),
        cmd2 = paste("cd", dir),
        cmd3 = paste0("git commit -am ", "'", msg, "'")
    )
    cmd <- paste(unlist(cmd_list),collapse = " && ")
    shell(cmd)
}

请注意,您的 gitcommit 函数将输出如下内容:

/v & cd /var/www/service/usercode/255741827 & git commit -am 'first commit'"

我不知道 substr(dir, 1, 2) 部分的作用是什么,但如果我的建议仍然无效,请尝试将其删除,只留下 cdgit commit命令。

解决方案

答案在 Dirk Eddelbuettel's drat package function addrepo. It was also necessary to use git2r's config 函数中,以确保 git 识别 R。git2r 的函数可能为使用 [=39] 提供更强大的解决方案=] 来自未来的 R 脚本。同时,这是我解决问题的方法。

  • 安装 git2r。使用 git2r::config() 确保 git 识别 R。

  • 根据德克的代码,我修改了 gitcommit() 函数以利用 sprintf()system() 来执行系统命令:

# Git commit.
gitcommit <- function(msg = "commit from Rstudio", dir = getwd()){
  cmd = sprintf("git commit -m\"%s\"",msg)
  system(cmd)
}

Sprintf 的输出如下所示:

[1] "git commit -m\"commit from Rstudio\""

例子

#install.packages("git2r")
library(git2r)

# Insure you have navigated to a directory with a git repo.
dir <- "mypath"
setwd(dir)

# Configure git.
git2r::config(user.name = "myusername",user.email = "myemail")

# Check git status.
gitstatus()

# Download a file.
url <- "https://i.kym-cdn.com/entries/icons/original/000/002/232/bullet_cat.jpg"
destfile <- "bullet_cat.jpg"
download.file(url,destfile)

# Add and commit changes. 
gitadd()
gitcommit()

# Push changes to github.
gitpush()

好吧,这张照片看起来很奇怪,但我想你明白了。

我个人喜欢 rOpenSci 的 gert 包的语法和简单性。具体来说,要提交回购协议,您可以执行以下操作:

git_add("test.txt")
git_commit("Adding a file", author = "jerry <jerry@gmail.com>")

顶推到远程:

git_push(remote = "origin", repo = ".")

并使用这个简单的语法查看所有其他有用的函数。