GitHubハンズオン(2024年度)

はじめに_

本ページは2024年度「実践的システム開発演習」受講者向けである。

以下の環境で確認している。

  • Windows 11 Pro 23H2の
  • Android Studio Koala Feature Drop | 2024.1.2 Patch 1
  • SourceTree 3.4.19

macOSでも本ハンズオンを実行できるが、SourcetreeはWindows版とmacOS版でユーザーインターフェースが少し異なるので、その部分の読み替えは必要となる(大きく異なるところは記載している)。

なお、GitHubアカウントは作成済み&作成したGitHubアカウントは担当教員に連絡済みとする。

Android Studioのバージョン、文字コード、改行コードの統一_

開発時にチームメンバーで Android Studio が異なっているのはトラブルの原因となる。統一すること。

また、トラブル防止のために文字コードおよび改行コードを統一しておく必要がある。文字コードをUTF-8(教科書どおりなら設定済み)、改行コードをUnix改行コード(LF)に統一すること。

SourceTreeによるソースコード管理_

macOS, Windows, Linuxのどの環境でも使用できるGitフロントエンドの一つSourceTreeを利用してソースコードのバージョン管理を行う(Android Studioのソースコード管理機能は使わない)。

Windows版インストール_

macOS版インストール_

GitHubでGit Credential Manager を用いる_

2024年10月現在、HTTPS経由でのリポジトリへのアクセスは、Git Credential Manager を用いることが推奨されている。

Windowsの場合_

Git for Windowsを用いる場合はGit Credential Managerも一緒にインストールされている。

後述するSourceTreeなどを使う際に自動でGit Credential Managerが起動し、GitHubとの連携が求められる。

macOSの場合_

Git Credential Managerをインストールする。Homebrewを利用する。Homebrewをインストールしていない場合はインストールする。なお、HomebrewをインストールするためにはCommand Line Toolsのインストールが必要となる。Command Line ToolsはXcodeをインストールすると同時にインストールされる。念のためインストール済みか確認すること。

Git Credential Managerに従い、以下のコマンドを実行する。

% brew tap microsoft/git
% brew install --cask git-credential-manager

後述するSourceTreeなどを使う際に自動でGit Credential Managerが起動し、GitHubとの連携が求められる。

GitHub上のリモートリポジトリの取得_

Windows版とmacOS版のSourcetreeでは、リモートリポジトリの取得に関わるユーザーインターフェースがかなり異なる。そこで、各版ごとに分けて記載する。

Windows版の場合_

GitHub上の自分のチームのリポジトリ「2024-team-X」(Xはチーム名)のページを開き、「Code」のボタンをクリックする。すると以下のようなウィンドウが開き、このリモートリポジトリのURLをコピーできる。なお、以下の例は「2024-team-template」となっているが、自分のチームのリポジトリを指定すること。

Sourecetreeを起動する。インストール後に作成したリポジトリが表示されている場合は新しいタブを開く(「+」アイコンをクリックする)

新しいタブを開いたら「Clone」アイコンをクリックし、以下の画面を開く。以下の画像の「元のパスURL」の欄(1番上の欄)にGitHub上のリポジトリのURLを入力する。

GitHub上のリポジトリのURLを入力と初回時のみ以下のようにGitHubへのログインを促すウィンドウが開く。「Sign in with your browser」のボタンをクリックし、WebブラウザからGitHubへログインする。すでにブラウザ上でGitHubにログインしている場合はログインは省略される。ログイン方法はアカウント作成時の設定により異なる。

GitHubへのログインに成功するとWebブラウザに以下のメッセージが表示される。

Sourcetreeに戻る。2番目の欄でローカルコンピュータ(今回の場合は自分のノートパソコン)上のどこにローカルリポジトリを作成するのかを指定することができる。今回は「C:\Sandbox\2024-team-X(Xはチーム名)」(Xは自分のチーム名)とする。3番目の欄は2番目の欄に応じて、自動的に入力される。「クローン」のボタンを押す。

クローン(リモートリポジトリをローカルリポジトリにコピーする)に成功すると以下の画面のようにリポジトリ画面になる。なお、以下の例では何度かコミットしているが、みなさんのリポジトリの場合はコミット回数が異なるので、異なる表示がされているはずである。

先ほどのGitHubへのログイン情報はGitHub Credential Managerという機能でノートパソコン上に保存されている。このため、以後は再度ログインする必要はない。この情報を確認してみる。Sourcetree上で新しいタブを開く(「+」アイコンをクリックする)。新しいタブ上で「Remote」アイコンをクリックする。開いた画面で「アカウントを編集...」をクリックする。

「github.com」という文字列をクリックする。これがGitHubのログイン情報となっている。これを削除すると、再度GitHubへのログインが必要となる。なお、以下の例では複数の項目が列挙されているが、みなさんの場合は異なる表示になっているはずである。

macOS版の場合_

GitHub上の自分のチームのリポジトリ「2024-team-X」(Xはチーム名)のページを開き、「Code」のボタンをクリックする。すると以下のようなウィンドウが開き、このリモートリポジトリのURLをコピーできる。

macOS上でSourcetreeを起動し、「新規」のタブをクリックする。「URLからクローン」を選択する。

開いたウィンドウで以下を入力する。

  • ソースURL:GitHubでコピーしたリモートリポジトリのURL(https://から始まるもの)
  • 保存先のパス:/Users/ユーザ名 以下に保存する(ターミナルからGitコマンドを実施できるようにするため)
  • 名前:保存先のパスから自動的に生成されるのでデフォルトでよい(自分がわかりやすいように変えてもよい)

SourcetreeでGitHubのリモートリポジトリに初めてアクセスするときは、Git Credential Managerのウィンドウが開く。GitHubのアカウント名とパスワードを入力する。

リモートリポジトリをローカルに取得することをクローン(clone)という。クローンが終わると以下のように追加したリポジトリが表示される。リポジトリをダブルクリックする。

以下の画面が開く。この画面では、変更のあったファイルや管理候補のファイルが適宜表示される。ファイルの編集やファイルの追加はAndroid StudioやFinder、ターミナルから行う。

コミットを行うと以下の画像のように「プッシュ」アイコンの横にリモートリポジトリに反映されていないコミット回数が表示される。このときに「プッシュ」アイコンをクリックするとリモートリポジトリに変更結果を反映することができる。

プッシュをクリックすると以下のようにウィンドウが表示される。反映させるブランチを確認の上で「OK」をクリックする。通常は現在操作しているブランチに対応したリモートのブランチに反映される。

Sourcetreeを用いたソースコード管理の練習_

チームでのソースコード管理を練習してみる。今回の練習ではコンフリクトが発生しやすいような状況をわざと作っている。失敗しても問題の無いように練習用のブランチで実施するのでコンフリクトが発生しても特に気にしないこと。

今回の練習ではチーム内のメンバーを班長(1名)と班員(班長以外のメンバー)の2種類に分けて行う。誰を班長にするのかは、当日の講義での指示に従うこと。

以下の操作についてWindows版とmacOS版の違いは少ないため、基本的にWindows版で説明する。macOS利用者は適宜読み替えること(たとえば「エクスプローラーで」とある部分は「Finderで」と読み替える)。

班長の操作:testブランチを作成し、リモートリポジトリに反映させる_

この作業は班長だけが行う。班長はクローンしたリポジトリをSourcetreeで開く。そして、「ブランチ」アイコンをクリックする。「新規ブランチ」の欄に「test」と入力し、「ブランチを作成」をクリックする。これでmainブランチを元に新たなブランチtestが作成され、testブランチにチェックアウトできる。

左側の「ブランチ」の欄にtestブランチが追加されていること、testの前に○がついていることを確認する(○がついているブランチが現在のブランチを表している)。

このtestブランチは班長のノートパソコン上にのみ存在するため、班員はクローンできない。そこで、GitHub上のリモートリポジトリにtestブランチをアップロードする。「プッシュ」アイコンをクリックする。

どのブランチをプッシュできるかを選択できる。testブランチにもチェックをいれ、プッシュする。これで、班員もリモートリポジトリからtestブランチをプルできるようになる。

班員の作業:testブランチをプルする_

この作業を班員が行う。クローンしたリポジトリをSourcetreeで開く。ブランチがmainブランチしかないことを確認する。

左側にある「リモート」をクリックし、「origin」→「test」と展開する。これがリモートリポジトリのブランチを表している。そこにtestブランチがあるのでダブルクリックする。

すると以下のウィンドウが開く。「チェックアウト」をクリックする。するとtestブランチが自動的にプルされ、testブランチにチェックアウトする(mainブランチからtestブランチへ移動する)。

これで、班長も班員も全員testブランチがローカルリポジトリにある状態になった。

班長・班員ともに操作:作業用ブランチの作成_

班長と班員ともに操作する。testブランチから作業用ブランチの「test_ユーザ名」を作成する。現在のブランチがtestであることを確認する。もし、testブランチでなければ、左側の「ブランチ」の項のtestブランチをダブルクリックするとチェックアウトできる。「ブランチ」アイコンをクリックする。作業用ブランチを作成する。

Gitではブランチごとにファイル構成を変えてくれるので、何か間違っても元になったブランチにチェックアウトしてしまえば、その間違いを無かったことにできる。

班長・班員ともに操作:プロジェクトの追加_

Android Studioでプロジェクを追加したときの挙動を確認してみる。Android Studioを起動する。「New Project」をクリックする。

「Phone and Tablet」→「Empty Views Activity」を選択し、「Next」をクリックする。

今回のプロジェクトは練習用でのちほど削除するのでパラメータは適当に作成する。

  • Name: Test_自分の名前_app(例えば Test_gotoh_app)
  • Package name: そのまま
  • Save location: 自分のチームのリポジトリ以下に生成する(たとえば「C:\Sandbox\2024-team-template\TestGotoApp」)
  • Language: Kotlin
  • Minimum SDK:任意のものでよい。
  • Build configuration language:そのまま

以上を設定して「Finish」を押す。

プロジェクトが生成されるまでしばらく待つ。

エクスプローラー上でクローンしてきたリポジトリ(2024-team-X, Xはチームのアルファベット)にプロジェクト用フォルダが作成されていることを確認する。Android Studioを終了する。

Sourcetreeに戻る。Sourcetreeではファイルが追加されたときや、変更が行われたときには画面のように「作業ツリーのファイル」として表示される。「全てインデックスに追加」をクリックし、プロジェクトのファイルを全部コミット対象にする。

適当にコミットメッセージを書く。後でどういう目的のコミットだったのかを思い出せるように記述する。たとえば「Add a new Android project.」とコメントとして記載する。コメントを記述したらコミットする。

現在の作業ブランチにプロジェクトが追加される。

班長・班員ともに操作:作業ブランチの変更をtestブランチにマージする_

Sourcetreeでは、下の画像のように全ブランチのコミット履歴が一覧で表示される。作業ディレクトリの変更内容を別のブランチに反映させることをマージという。マージは現在のブランチに別のブランチの変更内容を反映させる操作なので、まずはマージを反映したいブランチにチェックアウトする。今回は、testブランチにチェックアウトする(testをダブルクリックする)。そして、「マージ」アイコンをクリックする。

マージは以下の画面でおこなえる。マージしたいコミットを選択する。今回は作業ブランチ(今回の例ではtest_gotoh)の最新コミットを選択する。「OK」をクリックする。

マージすると当該コミットがtestブランチに反映されていることがわかる。このようにして作業ブランチの作業結果を親ブランチにマージする。

班長・班員ともに操作:ローカルリポジトリをリモートリポジトリにプッシュする_

現在、変更は手元のノートパソコン上にしか存在しない。そこで、GitHub上のリモートリポジトリに反映させる(プッシュ)。Gitの仕様上、全員が同時にリモートリポジトリにプッシュできないため班長から時計回りに全員のローカルリポジトリをプッシュする。

  1. まず、リモートリポジトリの変更をローカルリポジトリに反映させる(プル)
  2. 続いて、testブランチの変更をリモートリポジトリに反映させる(プッシュ)

プルは以下のように行う。「プル」をクリックする。プルする ブランチを選ぶ。今回はtestブランチを選ぶ。

続いて「プッシュ」アイコンをクリックする。testブランチを選択して、プッシュする。

全員、testブランチでプルして、全員が作成したプロジェクトが存在することを確かめる。試しに、全部のプロジェクトをAndroid Studioから開いてみる。

  • Android Studioをたちあげる
  • 「Open」アイコンをクリックする
  • 開きたいプロジェクトを選ぶ
  • 開けたことを確認したら、プロジェクトを閉じる(Android Studioを終了する)

班長・班員ともに操作:コンフリクト体験。その1:プロジェクトを削除してみる_

今回のプロジェクトは練習用であるため、自分の作業ディレクトリ上で削除してみる。以下の手順で作業を進める。

  1. testブランチをチェックアウトする
  2. testブランチをプルする。
  3. 自分の作業ブランチをチェックアウトする。
  4. 自分の作業ブランチにtestブランチをマージする
  5. 他の人のすべてのプロジェクトを削除する(削除の仕方は後述)。

上の1〜4までをここまでの復習として実行してみること。testブランチからのマージはHEAD(一番上のコミット)をマージする。

現在のブランチが自分の作業ブランチ(test_自分の名前)であること、チームメンバー分のブロジェクトがあることを確認した上でで、他の人のプロジェクトを削除してみる。

まず、Android Studioを立ち上げている場合は、Android Studioを終了する。続いて、エクスプローラーを用いて他の人のプロジェクトを削除する。

Sourcetreeで当該リポジトリを開いてみると、削除したファイルとディレクトリが変更対象(「作業ツリーのファイル」)に列挙されている。今回はこれをコミットするので、「全てインデックスに追加」をクリックし、プロジェクトのファイルを全部コミット対象にする。

その後、コメントを追加してコミットする。コミットメッセージはたとえば「Remove projects.」とする。

自分のプロジェクトだけが残ったら、自分のプロジェクトに変更を加えてみる。手順は以下の通り。

  1. Android Studioで自分のプロジェクトを開く。
  2. 適当なファイルを開き、適当に書き加える。
  3. プロジェクトを保存し、Android Studioを終了する。
  4. SourceTreeでコミットする。

なお、ここでは作業ブランチの変更結果をtestブランチへマージしないこと!。

班長のみ:コンフリクト体験 その2:testブランチをプッシュする_

コンフリクトを体験してみる。コンフリクトとは変更箇所が重なってしまい、Gitではどちらの変更箇所を優先すればよいのか判定がつかなくなった状況である。

ここまでの操作で、班長が削除したプロジェクトについて、班員はそのプロジェクトにファイルを追加している。このため、班長がローカルリポジトリの変更をGitHub上のリモートリポジトリに反映させた後(班長がPushした後)、班員がリモートリポジトリの変更をローカルリポジトリに反映させようとすると(班員がPullすると)、コンフリクトが発生する。

班長は、自分の作業ブランチをtestブランチにマージする。マージの手順は以下のとおり。

  1. testブランチをチェックアウトする(Souretreeでtestブランチをダブルクリックする)。
  2. 「マージ」ボタンをクリックし、HEAD(一番上のコミット)を選択して、マージする。

その後、班長はtestブランチをプッシュする。

班員のみ:コンフリクト体験 その3:testブランチをプルする_

班長がtestブランチのプッシュを行った後に、班員はtestブランチをプルする。

続いて、testブランチを自分の作業ブランチへマージする。すると以下のようにコンフリクトの発生が伝えられる。

コンフリクトが発生した場合は手動で当該ファイルを編集し、不整合をなくす必要がある。今回は練習のためコンフリクトの修正は行わず、作業ブランチを破棄する。

班長・班員ともに操作:不要になったブランチの削除_

作業ブランチは不要になったら削除する。作業ブランチを削除する際には、削除したいブランチとは異なるブランチにチェックアウトする必要がある。testブランチをチェックアウトする。警告が出る場合は「全ての変更を破棄する」にチェックをつけてチェックアウトを行う。続いて「ブランチ」ボタンをクリックする。

「ブランチの削除」をクリックし、削除したいブランチを選択する(今回は作業ブランチ test_自分の名前)。「OK」をクリックし、ブランチを削除する。エラーがでて削除できない場合は、「ブランチの削除」の際に「マージ状態に関わらず強制的に削除」にチェックをいれて「ブランチを削除」する。

無事に削除することができる。

リモートリポジトリのブランチもSourcetree上から削除できるが、GitHub上でも削除できる。次の作業を行った後に班長が削除する。

班長・班員ともに操作:過去のコミットからの新規ブランチの作成_

コンフリクトが発生したとき、通常はコンフリクトを起こしているファイルを編集することで解消するが、場合によってはコンフリクトが発生する前のコミットに戻ってやり直した方が良い場合がある。過去のコミットから新規ブランチを作成する手順は以下のとおり。

まず、testブランチにチェックアウトする。「ブランチ」アイコンをクリックする。

新規ブランチ名は適当に決める。「指定されたコミット」を選択し、「…」ボタンを押す。

以下のような画面で任意のコミットを選ぶことができる。コンフリクトが発生する直前のコミットを選ぶとよい。今回はmainブランチから分岐させた直後のコミットから新たなブランチを生成することにする。「OK」をクリックする。

コミットを選択すると、コミットのハッシュ値が自動的に記入される。「ブランチを作成」を押すと特定のコミットからブランチを生成できる。

以下のように過去のコミットからブランチが作成されている。

これで一通りのSourcetree上でのGit操作となる。

GitHubでチケットに基づく開発を行う_

アジャイル開発ではチケット駆動開発がよく利用されている。スクラムにおけるプロダクトバックログの実現方法としても相性が良い。

GitHubではIssueとProjectという機能があり、これを用いてチケット駆動開発およびそのチケットの管理を行うことができる。「実践的システム開発演習」の成績評価では、チーム内での作業分担状況も評価項目とするため、IssueとProjectを使ってチーム分担ができていることを示してほしい。IssuesやProjectsの使い方は以下のドキュメントで説明されている。

なお、Projectsは仕様が変更されており、以前は各リポジトリごとにProjectを作成する形式だった(今はProjects classicとして説明されている。2023年10月現在、Projects classicsの機能は使えない)。現在は各組織アカウントあるいはユーザアカウントごとにProjectを作成し、リポジトリやプロジェクトの管理者と対応付ける方式になっている。

  • リポジトリが組織アカウントの下で作成されている場合(本演習はこの事例に該当する)
    1. 組織アカウントでプロジェクトを作成する(Organizationプロジェクトの作成の項参照)
    2. 作成したプロジェクトのCollaboratorを設定する(プロジェクトのページへ移動→Settings→Manage access→Invite Collaborators)
    3. 関連付けしたいリポジトリへ移動し、関連付けする(Projects→Add project→当該プロジェクトを選ぶ)
  • リポジトリがユーザアカウントの下で作成されている場合
    1. ユーザアカウントでプロジェクトを作成する(ユーザプロジェクトの作成の項参照)
    2. 作成したプロジェクトのCollaboratorを設定する(プロジェクトのページへ移動→Settings→Manage access→Invite Collaborators)
    3. 関連付けしたいリポジトリへ移動し、関連付けする(Projects→Add project→当該プロジェクトを選ぶ)

本演習では組織アカウントで各チームのリポジトリを用意しているので、教員の方で事前にプロジェクトを作成し、チームのリポジトリに関連付けている。

プロジェクトはボード形式で作成している。ボード形式では標準でカンバン方式(これからやる(ToDo)、作業中(In Progress)、作業終了(Done))でタスクを管理できるようになっている。

タスクの追加は2通りある。Project上で「Add item」で作成するか、すでに作成したIssueを読み込むかをする。以下を一読すること。

チーム開発の方針にもよるが、今回のチーム開発に関わるすべてのタスクはチケットとして扱うのがよい。基本的には1〜2時間で終了する作業を1つのチケットとする。プログラミングだけでなく、調査、ドキュメント作成、プレゼンテーション資料の作成、ユーザ画面のデザインなど、非コーディング作業もタスクとして扱い、チケットとして管理すべきである。

また、あるタスクを1つのチケットして発行したものの、作業を開始してみたら、より詳細なタスクに分割した方が良いとわかる時がある。そのようなときは、そのチケットを終了し、あらたな複数のチケットとして発行し直す。

Issueの作成方法について以下のリンク先の「リポジトリからのIssueの作成」の項を一読する。

慣れないうちは、Title、Comment、Projectsだけでも入力する(Assigneesは後から割り当ててもよい)。

練習:Issueを作成し、Projectsに表示してみる。_

  1. それぞれ、自分のチームのリポジトリにアクセスし、Issueの作成を行ってみる。
    • Title:「自分の名前のイシュー」
    • Asignees:自分
    • Projects:そのチームのプロジェクト
  2. 続いて、自分のチームのリポジトリからプロジェクトを開いてみる。
  3. 確認したら、Issueを移動させたり、終了(close)したりしてみる。

GitHubにおけるドキュメントの編集_

GitHubにおいて、拡張子が.mdのファイルはMarkdown形式文書として扱われ、自動的に見やすいように変換される。このため、本開発の各種文書はMarkdown形式で書くといろいろと便利になる。

また、GitHubにはIssueやコミットへの自動リンク機能がある。

GitHubのIssueにつけるコメント、各文書ファイル(.md)、コミットメッセージ中で利用できる。

使うことを推奨するのはコミットメッセージとIssueの自動リンク。コミット時に特定のフレーズとIssue番号を記載すると、GitHubが自動的にそのコミットとIssueを関連づけしてくれる。

トラブルシューティング_

Windows版SourcetreeでGithubのリポジトリにアクセスできない_

クローンするためにGitHubのリポジトリのURLを入力しても、URLが妥当なものでないと判定される。詳細をクリックしたエラーは以下の通り。

>

コマンド: git -c diff.mnemonicprefix=false -c core.quotepath=false --no-optional-locks ls-remote https://github.com/enpit2su-ics/2024-team-D.git 出力: エラー: remote: Support for password authentication was removed on August 13, 2021. remote: Please see https://docs.github.com/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication. fatal: Authentication failed for 'https://github.com/enpit2su-ics/2024-team-D.git/' <<

原因はSourcetreeが使用しているGitのバージョンが古かったため、Git Credential Managerが利用できなかった(そのため、IDとパスワードのログインを試みてしまい、GitHubから「remote: Support for password authentication was removed on August 13, 2021.」というエラーが送られてきている)。

対処方法はGit for Windowsの最新版をインストールし、その後、Sourcetreeで使用するGitをSystemに切り替える。

  1. Sourcetreeを起動する
  2. 「ツール」→「オプション」を選択する
  3. 「Git」のタブをクリックする
  4. 一番下にあるGitのバージョンで「System」のボタンをクリックする。
  5. 「OK」を押して反映させる。

戻る_