Skip to content

Latest commit

 

History

History
233 lines (190 loc) · 7.31 KB

README.md

File metadata and controls

233 lines (190 loc) · 7.31 KB

RとGitおよびGitHubを結びつけるパッケージ

Rパッケージ

  • {git2r}... Rを通じて主要なGit操作を可能にするパッケージ。内部ではC言語で実装されたlibgit2を利用している。
  • {github}... GitHub APIラッパーパッケージその1
  • {gistr}... gist管理
  • {gh}... GitHub APIラッパーパッケージその2。Hadleyが **{devtools}**と相互性を持たせようとしていて、未来が明るい感じがある (r-lib/gh#30)

作業の流れ

gitリポジトリを作成

  1. {git2r}あるいはRStudioの新規プロジェクト作成機能でローカルに作成
  2. GitHubからクローン
library(git2r)
(getwd())
#> [1] "/Users/uri/git/test_git2r"
cred <- cred_user_pass("EMAIL", Sys.getenv("GITHUB_PAT"))
# 既存のディレクトリ内にリポジトリを新規作成
init(path = getwd(), bare = FALSE)
r <- git2r::repository(getwd())
library(github)
# リモートリポジトリをGitHub上に作成
res <- github::create.repository(name = "test_git2r", 
                          description = "test R and Git, GitHub integration", 
                          private = FALSE)
# $ok
# [1] TRUE
# 
# $content
# $content$id
# [1] 49580376
# 
# $content$name
# [1] "test_git2r"
# 
# $content$full_name
# [1] "uribo/test_git2r"
# リモートリポジトリに指定
remotes(r)
# character(0)

remote_add(repo = r, name = "origin", url = res$content$clone_url)
remotes(r)
# [1] "origin"

一旦RStudioを再起動してgitパネルを有効化する。

コミットからプッシュまで

# .gitignore ファイルの編集
devtools::source_gist(id = "b9cf68217c596369721a")
add_ignore()
status(r)
# Untracked files:
#   Untracked:  .gitignore
#   Untracked:  README.Rmd
#   Untracked:  README.md
#   Untracked:  test_git2r.Rproj

add(r, list.files(all.files = TRUE, recursive = TRUE))
status(r)
# Staged changes:
#   New:        .gitignore
#   New:        README.Rmd
#   New:        README.md
#   New:        test_git2r.Rproj
git2r::commit(r, message = "Initial commit :hatching_chick:")
# [e1a31ce] 2016-01-14: Initial commit :hatching_chick:

# リモートリポジトリにpush
push(r, "origin", "refs/heads/master", credentials = cred)
status(r)

以降は、ファイルに変更や管理対象のファイルに操作を加えた場合にコミットをしていく。例えば、README.Rmdを編集した場合、ステータスが変化するのでコミットする。

status(r)
# Unstaged changes:
#   Modified:   README.Rmd
#   Modified:   README.md
add(r, path = list.files(pattern = "^README"))
status(r)
# Staged changes:
#   Modified:   README.Rmd
#   Modified:   README.md
git2r::commit(r, message = "Upgrade commit example")
push(r, "origin", "refs/heads/master", credentials = cred)

ブランチの作成

# 現在のブランチ一覧

# $master
# [ac0ece] (Local) (HEAD) master
# 
# $`origin/master`
# [ac0ece] (origin @ https://github.com/uribo/test_git2r.git) master

# test/create_branchというブランチへcheckout。create引数をTRUEにして作成も同時に行う
git2r::checkout(r, branch = "test/create_branch", create = TRUE)
#   HEADが先ほど作成したブランチにきていることを確認
git2r::branches(r, flags = "local")
# $master
# [ac0ece] (Local) master
# 
# $`test/create_branch`
# [ac0ece] (Local) (HEAD) test/create_branch

# ファイルをコミットする
git2r::add(r, list.files(pattern = "^README"))
git2r::commit(r, message = "Upgrade README\nCreate branch")
git2r::push(r, "origin", "refs/heads/test/create_branch", credentials = cred)

プルリクエストの発行

# ref) https://developer.github.com/v3/pulls/#create-a-pull-request
gh::gh("POST /repos/uribo/test_git2r/pulls",
       title = "ブランチの作成について追加",
       head  = "uribo:test/create_branch",
       base = "master",
       body = "このプルリクエストは{gh}パッケージを使ってAPI経由で発行したもの")

ブランチのマージ

# ref) https://developer.github.com/v3/pulls/#merge-a-pull-request-merge-button
gh::gh("PUT /repos/:owner/:repo/pulls/:number/merge",
       owner = "uribo",
       repo  = "test_git2r",
       number = 2,
       commit_message = "{gh}パッケージからmerge! :muscle:")

ブランチの削除

git branch -d

git2r::branches(r, flags = "local")
# $master
# [dbd077] (Local) (HEAD) master
# 
# $`test/create_branch`
# [f4607c] (Local) test/create_branch
# うまくいかない?
git2r::branch_delete("test/create_branch")

リモートリポジトリの変更を反映させる

プルリクエストにより、リモートリポジトリに変更が加えられた場合、ローカルリポジトリとの間に差が生じる。そのため更新情報をリモートリポジトリに反映させる必要がある。

git pull origin master

# うまくいかない?
# masterブランチに切り替え。変更が加えられていて、未コミットのファイルがあるとcheckoutできないので注意
git2r::checkout(r, "master")
git2r::fetch(r, name = "origin", credentials = cred)
# [new]     7a071fde0521bed4d6e7 refs/remotes/origin/master
pull(r, credentials = cred)

GitHub issuesの活用

ref) Cucurbitaceae/cucumber-flesh#1

**{github}あるいは{gh}パッケージとGitHub APIを使って行う。{github}**ではAPIの種類に応じて関数が用意されており、 **{gh}**ではgh()関数内のendpoint引数でAPIを指定する。

library(github)
create.issue(owner = "uribo", repo = "cucumber_flesh",
             content = list(title = "Create issue from {github} package", 
                            body = ":package: {github}パッケージを使ってGithub issuesの作成\n改行はどうなるか :smile_cat:"))
library(gh)
# Sys.setenv("GITHUB_TOKEN") でtokenを与えていない場合、.token引数で指定する。
gh("POST /repos/Cucurbitaceae/cucumber-flesh/issues", 
   title = "Create issue to employ {gh} package",
   body = ":package: {github}パッケージからもissuesを作成可能。\n参考#1",
   labels = array("sandbox"),
   .token = "<Personal Access Token>")

gh("PATCH /repos/:owner/:repo/issues/:number",
   owner = "Cucurbitaceae",
   repo  = "cucumber-flesh",
   number = "3",
   state = "closed")

gh(endpoint = "GET /users/:username/repos", username = "uribo")
headers <- httr::add_headers(Accept = "application/vnd.github.v3+json",
                  Authorization = paste("token", Sys.getenv("GITHUB_TOKEN")))

GET("https://api.github.com/users/uribo",
    config = headers)

# POST("https://api.github.com/repos/Cucurbitaceae/cucumber-flesh/issues",
#      body = list(title = "Create issue from R using {httr}",
#                  body = ":package: {httr}パッケージだけでissueをPOSTするテスト"),
#      config = headers,
#      encode = "json")