イントロ
プログラムでもドキュメントでも、なにか書き物をしていると、ある時点の状態を保存しておいたり、そもそもバックアップをとっておきたくなったりしますよね。またプログラムのソースコードだと修正方針1と2をそれぞれ別にとっておきたいとか、このコード改修は次のリリースに入れないから別で保存しておきたい 、なんてこともあります。
こういったいわゆる書き物をバージョン管理したいニーズにこたえるシステムとして、Git (とそのWEB上のサービスGitHub ) という仕組みがあるので、その使い方を紹介します。
また、Git/GitHubは通常コマンドを使って操作するのですが、初見の方にはなかなか敷居も高いですよね。なので今回は、GUIでGitを操作できる SourceTreeというアプリケーションを使っていきます。
操作説明はSourceTreeを前提としていますが、すでにGitを扱う環境がある方は「やってみる」から操作していただければとおもいます。
本記事をハンズオンするには、受信可能な E-mail アドレスが必要なので、準備しておきましょう。
本ハンズオンの概要
- GitHubのアカウントを作成して、GitHubをつかえる状態にします
- SourceTreeというアプリケーションをインストールして、つかえる状態にします
- GitHubでリポジトリを作成し、**SourceTreeから操作(クローン、コミット、プッシュ、フェッチ、プル)**してみます
- ブランチをつくって、プルリクエストでマージしてみます
Gitって
さてGitって具体的にどんなモノ?リポジトリってなに?などいろいろあると思いますが、そういった説明はすでにたくさんの情報がネットにあるので、説明はここでは割愛します。(ハンズオン中心ですゴメンナサイ)
初めてGitを触るヒトは「サル先生のGit入門」このサイトがわかりやすくてとてもオススメです。特にはじめの
-
Gitを使ったバージョン管理
https://backlog.com/ja/git-tutorial/intro/01/ -
履歴を管理するリポジトリ
https://backlog.com/ja/git-tutorial/intro/02/ -
変更を記録するコミット
https://backlog.com/ja/git-tutorial/intro/03/ -
ワークツリーとインデックス
https://backlog.com/ja/git-tutorial/intro/04/
あたりは、とてもわかりやすいです。
操作するための準備
GitHubへのサインアップ
GitHubはGitのサーバをホスティングするWEBのサービスです。アカウントが必要なのでまずはアカウント作成から。
https://github.com/ 右上のリンクより、サインアップを開始します。
適当(適切) に ユーザ名やアドレス/パスワードなどを入力して「Create account」をクリック。
うまくいったようです。アンケートにこたえて、「Complete setup」をクリックします。
メールの所有者であることを確認するためのVerification mailが飛ぶので、それを処理すれば、セットアップ完了です。
WEB画面でリポジトリ作成
つづいてWEB画面からリポジトリを作成します。ログイン状態で、右上の「New repository」を選択。
リポジトリの名前はここでは「hello2020
」としました。はじめからREADMEは作っておきましょう1。
「hello2020
」というリポジトリが作成できたようですね。
リポジトリはこのように
- WEB上で新規作成して、それをローカル(PC上)にCloneしてつかう
- ローカル上いろいろ作成したコード群があるとして、ローカル側でリポジトリを作成して、それをリモート(WEB)に公開する
などいくつかやり方があります。今回は前者を用いました。
SourceTreeのインストール(とAtlassianアカウント作成)
https://www.sourcetreeapp.com/ よりインストーラをダウンロードし、起動します。
SourceTreeをつかうためにAtlassianのアカウントを作る必要があるようなので、まずはアカウント作成。
Atlassianにサインアップするためのアドレスなのでこの際なんでも良いんですが、用意したGitHubで使うアドレスを使うことにします。
あとはユーザ名を指定して、続行 をクリックで、サインアップ完了です。
さてインストーラに戻って「Bitbucket」を選択して次へ2。
ブラウザ画面での操作待ちになっています。ブラウザも起動したと思うので、、
こちらでログイン後、下記の認可画面でOK(アクセスを許可する) をクリック。
先ほどの情報が入っているので、そのまま次へ(チェックボックスはどちらでも)。
SSH用のキーの取り込みをするか、を聞かれるのですがとりあえず「いいえ」で。
長かったですが、ようやくSourceTreeの起動ができました。
普通にSourceTreeを起動したいだけなんですけどね。めんどくさいです。
またまた、環境によってはスタートメニューに「SourceTree」が登録されないようなので、今のうちに、タスクバーを右クリックして「タスクバーにピン留めする」をしておいた方がよさそうです。
ココまでで、
- GItHubへのサインアップ
- SourceTreeツールのインストール
が完了しました。おつかれさまでした。
SourceTreeとGitHubアカウントの紐付け
SourceTreeが起動したので、GitHubを操作するために先ほど作成したGitHubアカウントをSourceTreeに登録していきます。
サービスを「GitHub」プロトコルを「HTTPS」、認証は「OAuth」で「トークン再読み込み」をクリック
SourceTreeのアプリに戻ってみると、トークンが取れていることが分かります。OKをクリック。
SourceTree上でGitHubアカウントが確認できました。先ほど作成したリポジトリも表示されていますね。
ようやく準備が完了です。おつかれさまでした。
やってみる
リポジトリをクローン
SourceTreeをつかってクローンをおこないます。「hello2020」の右下の Clone をクリック
リポジトリはすでに選択された状態(赤枠内)なので、Clone先のPCのフォルダなどを確認しつつ「クローン」をクリック。
クローン完了です。先ほどWEB画面で作成していたREAME.mdなどが確認できると思います。
はじめてのコミットとプッシュ
右上の「Explorer」アイコンをクリックすると、クローンしたディレクトリがエクスプローラで表示されるので、適宜操作してコミットするファイルを作成してください。下記画面は「sample.txt
」を作成した図です(まちがってsample.txt.txt になっちゃってますけど、、)。
さて、このファイルをコミットしたのち、サーバリポジトリへプッシュしていきます。
まずは該当ファイルを選んで「+」をクリックして、Indexへステージさせます。わかりにくい言い回しですが、ようするに「コミットしたいファイル(たち)を選んでいる」だけですね。
ステージされました。つづいて、それらのファイル(今回は1つですが) をコミットする際のメモ「コミットログ」を記載して「コミット」をクリック。
ローカルのリポジトリへコミットされました。サーバのリポジトリにはまだ反映前なのでツールバーのアイコンや左部のmasterの右に「差分があるよ」というマークが付いているのが分かります。
さて、差分をサーバに反映させるために、ツールバーの「プッシュ」をクリック。
masterブランチが選択されています(ブランチについては後述)。そのまま「プッシュ」をクリック。
環境によってはなにやら下記のダイアログが表示されるようなので、credential helperを「wincred」にして「Always use this from now on」のボックスにチェックを入れて「Select」を選択。
認証を求められる場合もあるようで、その場合はGitHubのアカウント情報を入力します。今後は表示されなくなる(と思う!)のでご安心ください。
プッシュが正常に終了すると「完了しました」と表示されます。このダイアログは閉じてしまいましょう。
サーバにプッシュが完了したようなので、ブラウザで先ほどのリポジトリを見てみると、sample.txt がサーバのリポジトリ上にもコミットされているのが分かります。
ここまでの作業を整理すると、Gitの仕組みは
- サーバ上のリポジトリを「クローン」してローカルにリポジトリをコピーしてくる
- ローカル上で対象ファイルを修正して、**ローカルのリポジトリに「コミット」**する
- ローカルのリポジトリの更新内容を**サーバ上のリポジトリへ「プッシュ」**することで、サーバへ情報を反映させる
となっていることが分かります。このローカルのリポジトリで更新(コミット)をしているあいだは、サーバとの通信が発生しないところが、他のバージョン管理ツールたとえば Subversion とかとの大きな違いです。分散型バージョン管理ツールとよばれるゆえんですね。
修正、コミット、再度プッシュ
つづいて、PC上でファイルを修正し、コミット/再度プッシュを行ってみましょう。
テキストファイルを修正した後、SourceTreeの「ファイルステータス」をクリックしてみると、修正を検知して差分ファイルが表示されます。右上部にはファイルの変更点(削除箇所が赤、追加箇所が緑、など) が表示されているので、修正内容を確認しておきましょう。
さてコメントを入れてコミットですが、今回はためしに「変更をすぐに origin/masterにプッシュする」をチェック入れてコミットしてみましょう。コミットからプッシュまでを一度に行ってくれて便利です。自分はコミットとプッシュは丁寧にやりたい派なので、使いませんけど :-)
コミットとプッシュが正常に終了したようです。一応WEB画面も確認しておいてください。
サーバ上の変更の取り込みのフェッチ、プル
さて、他のPCとかからプッシュされたコミットの情報3は、ローカルに取り込まなければいけませんよね。
そのとき使う機能が「フェッチとプル」です。フェッチはサーバ上のリポジトリ情報の変更をチェックする機能、プルは実際に変更点をローカルリポジトリに反映させる機能です。厳密には微妙に違うんですが、だいたいそんな意味と覚えておけばOKです。
参考: GitHub/ローカル・リモートブランチとoriginのはなし
フェッチとプルをやってみます。別PCからコミット&プッシュしたいところですが、PCが一つしかない場合もあるでしょうから代替案をとります。
実はGitHubは、サーバ上のリポジトリをWEB画面上でそのまま修正してコミット&プッシュできるので、それを代替案とします。
つまり流れは
- WEB画面上で修正・コミットしてサーバ上でリポジトリを更新します。
- PC上のSourceTreeでサーバ上の変更をフェッチとプルで取り込みます。
となります。
GitHubの画面で、編集するsample.txt
をクリック。
編集したことが分かるように適当に文字列を追加するのと、あとはコミットログを記載して「Commit changes」をクリック。
コミットされたので、リポジトリ名のリンクで始めのページに戻ります。
画面のログを見ると、コミットされていることがわかりますね。
つづいてPC上のSourceTreeで、サーバリポジトリの変更内容をフェッチ&プルします。
まず初期状態は、「ローカルのmaster」の状態を表すmasterブランチと 「リモートのmaster」の状態を表す origin/master ブランチが、おなじコミット(図中 のcea341e
)を指しています。
サーバ上の更新をチェックするため「フェッチ」をクリックします。
正常終了したようですね。先ほどはmasterブランチと origin/masterブランチがおなじコミットを指していましたが 、今見てみるとorigin/masterが一つ次のコミットを指していて、サーバのリポジトリだけがひとつ進んでいることが分かります。というわけで、ローカルのリポジトリに取り込むためにツールバーの「プル」をクリックします。
ダイアログが出てくるので、そのまま「プル」をクリックします。
正常終了したようです。ふたたびmasterとorigin/masterがおなじコミットを指している状態になりました。
サーバリポジトリで更新されたファイルをPC上で開いてみても、更新が反映されているようですね。
うまくいきました。
フェッチとプルで、自分のローカルリポジトリの更新するほうほうは以上です。
ブランチを作って、複数バージョンを管理する
ブランチ機能は、はじめの説明にも書いた 修正方針1と2をそれぞれ別にとっておきたい みたいなケースで使います。ブランチという枝分かれ機能をつかうことで、複数の修正方針を同時にバージョン管理できるってことです4。
このハンズオンはブランチをあまり意識・説明しないでここまでやってきましたが、じつはずっと「masterブランチ」に対して更新を行っていました。プッシュする先の指定に「masterブランチ」ってのが出てきたり、フェッチとプルのときもmaster, origin/masterなどが出てきましたね。
さて、やってみます。流れは
- masterブランチから、develop1ブランチ、develop2ブランチを作成します
- develop1ブランチに切り替えます。develop1ブランチで
sample.txt
を修正し、コミットします - develop2ブランチに切り替えます。
sample.txt
が「develop1でのコミット前に戻っている」事を確認します -
develop2ブランチで、
sample.txt
を修正し、コミットします。 - develop1/develop2ブランチを切り替えて、コードが複数バージョン管理できていることを確認します。
- それぞれのブランチをプッシュすることで、サーバのリポジトリ上でも複数バージョン管理できていることを確認します。
- masterブランチに切り替えて、どちらのバージョンも反映されていないことを確認します。
まずは別のブランチの作成です。SourceTreeで、ツールバーの「ブランチ」をクリック。
ダイアログが表示されます。masterブランチから枝分かれするブランチを作成するので、
- 現在のブランチが「master」
- 新規のブランチは「develop1」
- コミットが「作業コピーの親」
- 新規ブランチを作成して、チェックアウトは「チェックはずす」
ブランチが作成されたとおもいます。
ちなみに「develop1をmasterからブランチさせる」の意味は「masterが指しているコミット番号f45b88d
に、別名のブランチ名develop1をつける」という意味です。なので上記の画面でコミットを「指定のコミット」を選んで、その右部でコミット番号f45b88d
を指定してブランチしてもOKです。
また「新規ブランチを作成してチェックアウト」のチェックアウトの意味は、新規作成したブランチを選択状態にするか、です。
さておなじ操作で develop2も作成します。結果、下記のようにmasterブランチとおなじコミットにdevelop1/develop2という名前がつけられました。
さて、develop1へ選択しているブランチを切り替えます。切り替えることを「チェックアウト」といいましたがSourceTreeの左部のブランチ名をダブルクリックすることで、チェックアウトができます。
さて、sample.txt
を修正しコミット&プッシュします(サーバリポジトリ上にはdevelop1がまだないので、プッシュ時に、リモートブランチの表示が空のままになってたりしますが、適宜チェックを入れてください)。
下記の通り、develop1(やサーバのorigin/develop1)のコミットが、ひとつ進んだ状態になります。
つづいてdevelop2をクリックしてブランチをチェックアウト(切替)します。この時点でsample.txt
がdevelop1のコミット前に戻っていることを確認しつつ、
sample.txt
を修正してコミットしてプッシュすると、、下記の通りdevelop1とは別に枝分かれしながら、develop2がひとつ進んだ状態になりました。
以上で、master(が指しているコミットf45b88d
)を分岐点として、develop1 と develop2が枝分かれして並行にバージョン管理された状態になっていることが分かりました。ブランチを master/develop1/develop2にパチパチ切り替えてみてsample.txt
がそれぞれバージョン管理されていることを確認してみてください。
ブランチからマージする
さて、develop1/develop2 のうちの一つを、masterブランチに反映させます。ある**ブランチの修正内容を他のブランチに反映させる機能が「マージ」**です。
マージ機能は
- ローカルリポジトリ間でコマンドやSourceTreeをつかってマージする「マージ」機能
- サーバのリポジトリ間で「マージしてください」というリクエストを投げることでサーバ上でマージする「プルリクエスト」機能
があります。後者はGitの標準機能ではなくGitHubなどWEB上のホスティングサービスが持つ機能5なのですが「マージの依頼」と「マージの承認」という役割分担がソースコードの品質管理上とても便利なので、今回はこちらを使ってみます。
やってみます。
先ほどのdevelop2ブランチの修正を、masterブランチにマージしてみます。流れは以下の通り:
- WEB上で、develop2ブランチからmasterブランチへ、プルリクエストを投げてみます
- WEB上で、そのプルリクエストを承認します。
- サーバ上でdevelop2ブランチの内容がmasterブランチに反映されたことを確認します
- SourceTree上でフェッチして、更新があることを確認し、プルで取り込みます。
- ローカルリポジトリのmasterブランチに、develop2での修正が取り込まれていることを確認します。
WEBを開いて、上部の「Pull Requests」をクリックします。
プルリクエストの一覧画面が(0件ですが)表示されるので「New pull request」をクリック。
プルリクエストですが、今回は「develop2 "から" master "へ" マージ」したいので、下記のように「base: master」「compare: develop2」と設定します。
画面の下部にコードの比較画面が現れました。master と develop2の差分がずらっと表示されています(といっても今回はsample.txt
だけですが。)。またプルダウン右に「Able to merge」と出ていますが、競合が発生しなかったので自動でマージできますよ、といった意味ですね。
Create pull request をクリックすると、下記の通りコメントを記載する画面が表示されるので、コメントを入力し「Create pull request」をクリックします。
このまま「Merge pull request」をクリックして承認するので構わないのですが、せっかくなので最初から。
上部の Pull request リンクに小さく「1」と付いて、プルリクエストが出ていることが分かります。それをクリックします。
プルリクエストの一覧が表示されるので、該当するリクエストをクリック。
先ほどとおなじ画面が表示されるので 「Merge pull request」 をクリック。
マージを承認する場合は「Confirm merge」、拒否する場合は下にコメントを入れて「Close pull request」とします。今回は「Confirm merge」をクリックします。
マージが完了しました。develop2ブランチはマージされたので、もう削除してもOKです。「Delete branch」をクリックすることでブランチの削除ができます(今回はそのままにしておきました)。
さて、サーバリポジトリ上でのマージが完了しました。マージは「マージするコミットが行われた」ということなので、マージされたmasterブランチは、そのぶんのコミットがされているはずです。ローカルのリポジトリに**サーバリポジトリの更新分を取り込むのは「フェッチ&プル」**でした。フェッチ&プルで、masterブランチのコミットが進んでいることを確認しましょう。
サーバリポジトリのmasterブランチの状態をあらわす origin/master が「Merge pull request ... from develop2」というコメントが付いたコミットが行われて、他のブランチよりも進んでいます。またそのコミットには、develop2 が取り込まれた線(?)が付いているのが分かります。develop2の内容が取り込まれているってことですね。
最後に**「チェックアウト(左のmasterのダブルクリックでしたね)」でmasterブランチに切り替え**た後「プル」で取り込んで、下記の通りローカルのmasterブランチへの反映が完了です。
プルリクエストによる他のブランチのマージが完了しました。おつかれさまでした。
まとめ
- GitHubをつかえる状態にしました。
- SourceTree上で、GitHubを操作してクローン、コミット、プッシュ、フェッチ、プルできることを学びました。
- masterとは別のブランチを作成して、複数バージョンのコードを管理できることを学びました
- 別のブランチの修正をプルリクエストによってmasterにマージできることを学びました。
おなじブランチ上で、先にコミット&プッシュがされた場合、コミットの競合が発生するのですが、その対処法については割愛しました( 対処法としてはrebaseする、mergeする、そもそも競合が起きないようにbranchで開発してあとでmergeする、などなど)。
ほかにもいくつかTIPSがありますが、またの機会に。
以上、おつかれさまでしたー。
RPA/UiPath界隈のヒト向け
ワークフローのバージョン管理にGit/GitHub はいかがでしょうか。
Gitなどのバージョン管理ツールがないと、フォルダごと日付をつけてコピペするとかになると思いますが、Gitを使うことでカッチリとバージョン管理ができます。
最近のUiPath StudioではGitのサポートも充実してきました。UiPath Studioがあれば SourceTreeなどを使う機会はないかもしれませんが、よろしければGit/GitHubの使い方入門として読んでみてください。