Edited at
RStudioDay 10

RStudioではじめるGitによるバージョン管理

More than 1 year has passed since last update.

2017年12月時点での状況を振り返り、変更点や新しい機能等について更新、文章の見直しを行いました。差分はこちらからも確認できます。

先日、Tokyo.RでRStudioとGitの話をしてきましたが、尻切れトンボな感じで中途半端に終わってしまったので改めてまとめておきます。

この記事では、RStudioでのバージョン管理を行うために必要な準備編とバージョン管理の基本的な操作をまとめた基礎編、GitHubを例としたリモートリポジトリの活用方法、そしてこういう状況ではどう対応するかという実用編の3つに分けて説明します。

なお、すでに使用しているパソコンでGitのインストールやsshキーの発行およびGitHubのアカウント作成等が済んでいるものとして話を進めます。Gitの設定などは末尾に挙げる参考文献やIT苦手な人のためのWindows+gitでRStudioによるバージョン管理入門 - Analyze IT. が参考になります。

Gitにはさまざまな機能がありますが、ここではRStudio上で可能な操作を中心に扱います(背景... Gitの操作はターミナルでやるのが常だが、ゆとりなのでGUIを使いたい ref) gitって別にGUIから使ってもいいじゃん - 半空洞男女関係)。


準備編


ローカルリポジトリ(Rproject)を作成する

ここはいつもどおり。メニューバーのFile -> New Project... からRprojectフォルダを作成(または既存ファイルと紐付け)します。Rパッケージ用でも同様です。

この際、gitリポジトリを作成するか、というオプション項目があるのでチェックしてgitリポジトリ(.gitフォルダ... 不可視フォルダなので通常は見えない)を作成します。

新規プロジェクトの作成でgitバージョン管理を行う

既存フォルダに対してGit管理を始める場合はメニューバーのToolsからProject Optionsを選択、Git / SVNという項目のVersion Control SystemからGitを選びましょう。確認表示でYesを選択するとRStudioが再起動し、バージョン管理の準備が整います。

さて、新規Rprojectを立ち上げると次のような画面になっています。Gitリポジトリを作成するように指定しましたので、左上にGit用のタブがあり、いくつかのファイル名が挙げられています。Gitタブは3つの列からなる構造をしており、各列(カラム)はStagedStatusPathとなっています。RStudioではここのタブを通してGitの操作を行います

RStudioのgitタブ

もしもGitと表示されたタブが見つからない場合、メニューのPreferencesから、Pane LayoutにいてVCS(Version Control System)を有効にしてください。


基礎編

新規でRprojectを作成した段階だと、Gitタブには.gitignore<Rproject名>.Rprojという2つのファイルがあります。ファイル名の横にはチェックボックスと黄色のアイコンがあります。Gitタブでは、このように3つの列で各ファイルおよびフォルダのGit管理状態を表示します。

黄色のアイコンが2つ並んでいるStatusという列は、その名の通り、ファイルのバージョン管理状況を示します。現在はどちらも「?」となっています。これはこのファイルがGit管理の対象に置かれていないことを意味しています。Gitでは、このようにまず、管理対象とするファイルを選択できます(ファイルサイズの巨大なバイナリファイルやパスワードや環境変数などの個人に依存する情報をデフォルトで扱わないための処理です)。

また、GitタブのDiffというボタンを押すと次の画面が立ち上がります。ここでは背景が緑色の状態でファイルの中身が表示されています。緑色なのには意味があります。2つのファイルはGitで管理されていないファイルなので、ファイルの全てが記録対象になります。緑以外の状態にもなりますが、それは後述します。この画面でファイルの確認を行えますので、実際の作業では、ファイル名とともに変更点を見ていくことになります。

gitタブのDiffボタンを押すと表示される画面。ファイルの中身(変更点)が出力されている

今回、どちらのファイルもGitで管理したいファイルなのでStaged列のチェックボックスにチェックをつけましょう。するとStatusが「A」になりました。これは「新たに追加された(Added)」を意味します。新しくバージョン管理を行うファイルでは、すべてこのような手順をとります。

Staged列にチェックを付けたら現在のファイル状態を記録するよう、コミットしましょう。コミットとは、変更を記録することを意味します。

今の画面を開いた状態(あるいはGitタブのCommitというボタンを押す同じ画面が立ち上がります)で、そちらのCommit messageという箇所にコミット文を書きます。コミット文はユーザが任意でつけるもので「今日の作業」や「微調整」のようなものでも良いですが、なるべく具体的にどのような変更を行ったのかを書くと良いです(一行目は単純なメッセージ、二行目以降に詳細を書く)。

バージョン管理を行うファイルの確認からコミットまでの流れ

管理するファイルを指定して、コミットする。これが基本的な流れになります。今回はGit管理の対象にするという操作でしたが、以降で説明する変更点を反映させたりするのも同様の操作となります。

2つのファイルをコミットしたことで、Gitタブは空になりました。この状態は、バージョン管理の対象ディレクトリには記録されていないファイルはないということを意味します。


変更を記録していく

ファイルをGit管理の対象に加えた後は、各ファイルの変更点のみを記録していくことになります。これにより、いつどのような変更を誰が行ったか、ということが記録に残り、必要に応じて参照したり過去の状態に遡ることが可能になるのです。

先程コミットした.gitignoreを対象に、修正を加えて変更点をコミットしましょう。. gitignoreの役割についても同時に説明します。


Git管理しないファイル、拡張子は.gitignoreに追加する

.gitignoreという不可視ファイルはGitバージョン管理において特別な役割を持っています。それは、バージョン管理を行わない(無視する ignore)ファイルを指定するためのファイルです。新規作成したRproject内の.gitignoreには次のファイル名が明記されています。いずれも不可視ファイルであり、特にバージョン管理する必要のないファイルです。

.Rproj.user

.Rhistory
.RData
.Ruserdata

特に.RhistoryはRStudioのコンソールで実行したスクリプトが記録されるので、それをコミットに含めると、もしもパスワード等の情報を扱っていた場合に閲覧できてしまうという危険性があります。こうしたファイルは.gitignoreに記録し、管理対象から外しましょう。

https://speakerdeck.com/yutannihilation/uebuapifalsetamefalserpatukezizuo-cheng-falsekan-suo

(リンク先のスライドの中でもセキリュティの面からのgitignoreの管理について触れられています)

ここではバージョン管理の練習として.htmlファイルを管理に含めない、という処理をおこないます。.gitignore.htmlを追加しましょう。.gitignoreを開くには、Filesタブから選択しても良いのですが、Gitタブでファイル名の書かれた行を選択した状態で右クリック、Open Fileでも可能です(コミットした状態なので表示されていないはずですが)。

.gitignoreは個別のファイル名でも指定可能ですが、今回は.html拡張子のファイル全てを管理の対象外としたいので、正規表現を利用し*.html.gitignoreに追加します。すると、このディレクトリに.htmlファイルを追加した際、Gitタブにはそれらのファイルは表示されなくなります。

Gitによるバージョン管理では、管理対象になるのは基本的にテキストファイルです。画像の差分を管理することもできますが、ワードやパワーポイントといったバイナリファイルは.gitignoreに追加しておくことをおすすめします。不必要なファイルを管理対象にしないことで、リポジトリが綺麗に保たれます。

さて本題に戻りましょう。変更点をコミットする、という話です。今、.gitignore*.htmlを追加したため、Gitタブでは.gitignoreの状態が青色の「M」になりました。Git管理の対象にあるファイルに変更が加えられるとこのようにModifiedを示すようになります。この状態でDiffボタンを押すと、前回のコミットからの変更点を確認することが可能です。緑色でハイライトされた部分が新たに追加された部分を示しており、きちんと*.htmlが追加されたことがわかります。

変更箇所が緑色でハイライトされる

htmlファイルをバージョン管理の対象から外したことをコミットしておきましょう。Staged列にチェックをつけてコミットメッセージを書いてコミットします。ここでは.gitignoreに新しいルールを追加したことと、htmlファイルを含めない理由について下記のようにしました。

add ignore file

HTMLは邪魔なので

個別にファイルをignoreしていく場合、Gitタブに表示されるファイル名を右クリックし、Ignoreを選択しても追加されるので便利です。


差分を確認しながらのコミット

一度コミットしたファイルは、その変更について管理されます。これは追加だけでなく削除についても同様です。今度は差分を確認しながらのコミットを行いましょう。

すでにhello_tidyverse.Rというファイルを作成して、新規コミットを行った状態とします。

library(tidyverse)

tidyverse_logo()

この状態のファイルを次のように変更します。

tidyverse::tidyverse_logo()

するとファイルが変更されたのでGitタブにhello_tidyverse.Rが表示されますが、Diffボタンで変更箇所を確認すると今度は赤くハイライトされた部分があります。またその下に緑のハイライトが続きます。

これは赤い部分のコードが緑色に変更されたことを意味します。左側に行番号も表示されており、どの部分を変更したのかが一目でわかるようになっています。この変更点(追加と削除)はコミットによって記録されますので、後から振り返るのに便利です。

変更箇所のハイライト。赤色は削除、緑色が追加


コミット履歴を見る

これまでにいくつかのコミットを行いました。次はこれらのコミット履歴を振り返り、変更点を検索したり、特定のファイルの変更履歴を表示するといったことをしてみます。詳細は次のgif画像をご覧ください。

RStudioのGitタブにある時計のアイコンをクリックすると、これまでのコミットおよびマージした記録が表示されます。ブランチや特定のファイル・ディレクトリを対象にした履歴の表示が可能です。また、コミット文をもとにした検索も可能です。


ステータスを理解する

Status列のアイコンと色は次の状態を示しています。

アイコン

状態

? git-unknown.png


untracked git管理の対象になっていない

Modified git-modified.png


リポジトリの状態から変更された

Delete git-deleted.png


リポジトリにあったファイルが削除された

Added git-added.png


新たにgit管理状態になった

git-commit-conflict.png

リポジトリ間で差分が衝突している


ステージングについて

わかりやすいので参考にしてください。

gitのステージングって何?必要なの? - Qiita


実用編

ローカルに作成したGitリポジトリを、GitHub等のGitのホスティングを行うウェブサービスと連携し、リモートリポジトリとして扱う方法やRStudioでのバージョン管理におけるtips等をまとめます。


リモートリポジトリを設定する

今作成したgitリポジトリは、あくまでもローカルPCで管理されているものです。これを共同編集者と共有するには、別途Gitサーバが必要になります。Gitサーバを立ち上げても良いのですが、これにはGitHub等のGitホスティングサービスを活用するのが手軽です。

GitHubでは基本的に作成するリポジトリはすべて公開されますので、非公開にしたいGitリポジトリについては、有料サービスのプライベートリポジトリを利用するか、BitbucketやGitLabといった別のシステムを使ってください。教育機関に所属する場合、GitHubの教育機関向けプログラムが適用可能です。

まず https://github.com/new にアクセスし、適当なリポジトリ名を打ちます(ローカルに作成したRprojectと対応していたほうが都合が良いです)。リポジトリ作成のボタンを押すとローカルリポジトリ上にリモートリポジトリを追加する方法を説明するページに飛ぶので、「git remote add origin https://github.com/<ユーザー名>/<作成したリポジトリ名>.git 」の部分をコピーしてRStudioに戻ります。

RStudioのGitタブにあります、歯車ボタンを押すと、Shell...という項目、あるいはメニューバーのTools、Terminal、New Terminalを押すとMacではターミナル、後者の場合はRStudio上でターミナル画面が立ち上がるので、そちらに先程コピーしたgit remote add ~を貼り付けまたは打ち込んでリモートリポジトリを紐付けます。これでGitHubのリポジトリをリモートリポジトリとして設定する用意が完了しました。

RStudioに戻ると、新たにGitタブ上にmasterという項目が追加されています。これは現在のブランチを示しており、masterがローカルリポジトリ、origin/masterというのがGitHubに作成したリモートリポジトリを指しています。ブランチについては後述します。

あるいは、GitタブのNew Branchというボタンを押し、さらにAdd RemoteからRemote Nameを"origin"、Remote URLにhttps://github.com/<ユーザー名>/<作成したリポジトリ名>.git としても同様の処理が実行されます。

数あるGitホスティングサービスの中でGitHubをオススメする点は、現在多くのRパッケージが管理されているという実績があったり、ユーザインタフェースが良く、操作しやすい、RStudioから直接GitHubのページを開けるという点があります。


ブランチの操作とpushとpull

Gitでは、複数人が同時にリポジトリを変更したり、部分的なコードの修正が作業として想定されており、ブランチが大きな意味を持ちます。基本的に一人で作業する際はmasterのみで特に意識する必要はないと思いますが、ブランチとブランチからの変更を操作するgitコマンドについても触れておきます。

リポジトリには、ローカルリポジトリとGitHubのようなサービスを利用したリモートリポジトリの2種類があり、それぞれにmasterと呼ばれるブランチが存在します。ローカルリポジトリは自分の作業環境、リモートリポジトリはみんなが参照する環境と考えると良い気がします。masterブランチは、その名の通り各リポジトリでの基盤となるブランチです。注意すべきなのはリモートリポジトリは自分のローカルからも参照しますので、リモートで変更があった場合、ローカルにもその変更が適用される、という点です。

ただそれだと、リモートで誰かが勝手にファイルを変更してしまった場合、みんなが困ることになります。なので、ブランチという作業環境を作り、そこで作業してもらうようにします。作業が終わり、全体に対して悪い影響がないことが確認されたら、masterへマージする、ということが繰り返されます。

ブランチを適切に作っておくと、作業の競合を防ぐだけでなく、作業内容もわかりやす苦なります。


ブランチの作成と切り替え

RStudioでブランチを作成するにはGitタブのNew Branchというボタンを押します。するとランチの名前の入力を促す小さな画面が起動します。ブランチ名を入力したらCreateボタンを押しましょう。ここでSync Branch with Remoteにチェックがついた状態でCreateすると、GitHubのリモートリポジトリにも同名のブランチが作成されます。つけておきましょう。

ブランチが作成されると、自動的にブランチが切り替わります。ここで編集したファイルはmasterからは独立しています。現在のブランチ名はGitタブの右端に表示されています。ブランチを手動で切り替えるにはブランチ名をクリックし、目的のブランチを選択します。

作成したブランチでファイルに変更を加えていた場合、masterブランチにはその変更が適用されていないことがわかるはずです。


push: リモートリポジトリに変更点を反映させる

いくつかのコミットがたまり、問題がないことを確認したら頃合いを見計らってGitHub上にあるリモートリポジトリに変更点を反映しましょう。リモートリポジトリにローカルリモートリポジトリの変更履歴を反映させることをpushといいます。RStudioのGitタブにある↑ボタンがgit pushと同じ働きをします。このボタンを押すと、登録されているGitHubリモートリポジトリとローカルリポジトリが同期されます。


pull: リモートリポジトリからの変更を取り入れる

今度はリモートリポジトリからの変更をローカルリモートリポジトリに反映させてみます。これは、リモートリポジトリを使うことの利点でもあり、GitHubによる共有リポジトリの特徴でもあります。プルリクエストを取り込み、masterブランチにマージしたときなどにこの操作を行います(GitHubのリモートリポジトリでマージした状態をローカルリポジトリにも適用させる)。

先程の矢印とは逆向きの↓がpullを示します。


そのほかのtips


ショートカットキーの活用


  • 差分の表示 control + option + D... 現在編集中のファイルの差分を表示

  • コミット control + option + M... コミット画面の起動


コミットの操作


revert: 以前のコミット状態を復元する

Git管理しているファイルでは、現在編集したファイルをすでにコミットしている状態に戻すことが容易です。いろいろ書いたけど、やっぱりこれはダメだ、という場合にはこうした復元が役立ちます。RStudioのGitタブに表示されているファイル名を右クリックすると、Revert... という文字列が表示されるので、それをクリックすると、確認のための画面が立ち上がります。確認のボタンを押すとファイルが以前のコミット状態に戻ります。

この操作はコミットされていない部分のコードを消してしまいますので、注意して行いましょう。


amend: コミットを修正する

pushしていない直前のコミットであれば、コミットを取り消すことができます。commitアイコンを押し、Amend previous commitにチェックをつけると、直前のコミットに追加で変更を適用することができます。ファイルに取りこぼしがあった場合や別途追加ファイルがあった場合に役立ちます。

画像の例は少しわかりにくいかもしれませんが、ggplot2での作図を行ったコミットに対して、もう一つの作図スクリプトを追加して一つのコミットとしてまとめた、という処理です。

RStudioからは直前のコミットに対してのみamendが適用可能ですが、Gitコマンドを使うことでより柔軟な修正が可能です。


ファイル内の一部分だけコミット

ファイル全体ではなく、ファイル内の変更点の一部のみをコミットすることも可能です。対象ファイルをstageに上げた状態でDiff画面を立ち上げ、コミットに含めない部分を行単位で選択します。するとUnstaged selectionというボタンが表示されるので、それを押します。するとその部分は今回のコミットからは外されます。コードには残ったままなので、とりあえずここだけ変更しておく、というときに有効です。逆に、ここだけ追加するというときにはStageにのせる前の状態で、箇所を選択し、Stage selectionを押します。

w89merVthV.gif


RからGitを操作するパッケージ

git2rパッケージの使い方については以前に少しだけ書いたのですが情報が古いし、扱っている量そのものがわずかしかないです。

時間があったらまた書きます。


参考文献

RStudioおよびGit連携機能について書かれている本は相変わらず少ないですが、次にあげる書籍では取り扱われています。


  • 石田基広 Rで学ぶデータ・プログラミング入門: R Studioを活用する (2012). 共立出版

  • 石田基広 改訂2版 R言語逆引きハンドブック (2014). C&R研究所

  • 荒引健ほか R言語上級ハンドブック (2013). C&R研究所

  • Jared P. Lander. R for Everyone: Advanced Analytics and Graphics (2013). Addison-Wesley Professional


    • Jared P. Lander. 高柳慎一ら訳 みんなのR -データ分析と統計解析の新しい教科書 (2015). マイナビ



  • Hadley Wickham. R Packages (2015). O'Reilly... Chapter 12を読むと良い。

ですが、共立出版から出るWonderfulRシリーズの「RStudioによるReproducible Research(仮題)」という本は期待値が高いです。皆さん是非!!

Enjoy!