2023-2I プログラミング1 第16回 講義資料

2023年10月16日(月)1・2時限

1 概要・連絡

1.1 達成目標

1.2 連絡

2 定着確認

後期授業ではシラバス記載のように「小テスト」を実施し、その結果を成績評価のなかに組み込みます。以下、小テストの練習問題です (このままの形式で出題されるわけではありません)。

シラバスから抜粋
課題の提出状況とその内容(80%)ならびに授業中に実施する小テスト(20%)を総合して評価する。

3 拡張機能のインストール

git を利用したバージョン管理に役立つ「VSCode の拡張機能」として次の 2 つをインストールしてください。

3.1 Git Graph

Git Graph は 「コミットグラフを VSCode で表示するための拡張機能 です。VSCode の拡張機能の検索欄に mhutchie.git-graph と入力し、Git Graph をインストールしてください。使い方については、今回の授業のなかで紹介します。

img

3.2 Auto Commit Message

Auto Commit Messageコミットメッセージを自動生成してくれる拡張機能 です。例えば、ファイルの追加や変更を読み取って「update xxx.html, yyy.css and zzz.js」や「create 3 files and update 6 files」のようなコミットメッセージを生成してくれます。

VSCode の拡張機能の検索欄に michaelcurrin.auto-commit-msg と入力し、Auto Commit Message インストールしてください。

img

Auto Commit Message のインストール後、なんらかのコミット対象が存在するときに、次のようにアイコンをクリックすると ❸ の「コミットメッセージ」のテキストボックスに、自動生成されたコミットメッセージが入力されます。

img

4 プロジェクトフォルダを過去のコミット時点に戻す

ここでは git の機能を使用してプロジェクトフォルダ (ローカルリポジトリ) を「過去の任意のコミット時点に戻す方法」について学びます。また、この機能に関して理解を深めるためにいくつかの実験をしてみます。

4.1 準備

準備として、プロジェクトフォルダに次のような変更を加えながら 4つのコミット を作成していきます。


  1. first commit
    • フォルダの中身:(空)
  2. 2nd commit「README.md と aaaa.txt を追加」
    • フォルダの中身:README.md, aaaa.txt
  3. 3rd commit「bbbb.txt を追加」
    • フォルダの中身:README.md, aaaa.txt, bbbb.txt
  4. 4th commit「cccc.txt を追加」
    • フォルダの中身:README.md, aaaa.txt, bbbb.txt, cccc.txt

このような変更履歴の記録を作成した後、つまり「4th commit」までを完了させた後、プロジェクトフォルダを「2nd commit」の時点に巻き戻すような実験をしてみます。

以下に、実験の「準備手順」を示します。

4.1.1 「first commit」

ターミナル (Git Bash モード) を起動して cd コマンドを使ってドキュメントフォルダなどの適切な場所に移動します。例えば C:\Users\xxxx\Documents などに移動します。

Git Bash でのフォルダ移動

Git Bash は Linux 互換環境 (シェル) です。そのため cd する場合、C: などのドライブレター (Windows特有のパス表記) を含むときは cd "C:\Users\xxxx\Documents" のようにダブルクォーテーションで囲むか、cd /C/Users/xxxx/Documents のようにLinux形式のファイルパスを使用してください。

Git-Playground というフォルダを作成し、そのフォルダ内に移動して「git初期化」します (git によるバージョン管理を開始します)。 Playground という単語は、一般には「子どもが遊ぶための場所や施設」を意味しますが、プログラミング分野では新しいアイディアや技術を試したり、実験したりするための環境やスペースを指す意味で使用されます。

$ mkdir Git-Playground
$ cd Git-Playground/
$ git init
Initialized empty Git repository in C:/Users/xxxx/Documents/Git-Playground/.git/

上記の操作により .git という隠しフォルダが作成されたことを確認しておきます (確認には ls -al などのコマンドを利用してください)。

また git status コマンドで現在の「git 管理の状態」を確認しておきます

$ git status
On branch main
No commits yet
nothing to commit (create/copy files and use "git add" to track)

「On branch main」「nothing to commit」、つまり、現在は main という初期ブランチ (デフォルトブランチ) にいて、まだコミットが存在していない状態 であることが確認できます。

ここで main というブランチ名はgit のインストール設定に基づいて設定されます。ブランチの概念や操作については講義後半で詳しく取り上げます。

現在の「ブランチ」を確認する確認

「現在、どのブランチにいるか」は Git Bash の表示からも確認できます。下記の場合 main ブランチにいることが読み取れます。

img

初期状態 (フォルダ内に .git 以外は存在しない状態) で「first commit」を作成します。フォルダが空の状態でコミットする場合には、次のように --allow-empty オプションを付ける必要があります (このオプションをつけないとコミットできません)。

$ git commit --allow-empty -m "first commit"
[main (root-commit) d0e8462] first commit

git log --oneline で「コミットの履歴」を確認します。--oneline をつけると 1 コミットの情報が 1 行 で出力されます。以下のような応答があればコミットに成功しています。

$ git log --oneline
d0e8462 (HEAD -> main) first commit

なお、上記応答の先頭にある 16進数で7桁の値 d0e8462コミットハッシュ と呼ばれます。コミットハッシュは、コミットの内容タイムスタンプに基づきSHA-1(慣例的に「シャー・ワン」と読みます) により生成される一意な ID となります。

このため、皆さんの手元で実行したときはコミットハッシュの値は、上記の実行例と違う値になるはずです。ハッシュ値 についての概要は「情報 2」の第09回講義資料の p.146 を参照してください。

4.1.2 「2nd commit」

プロジェクトフォルダにファイルを追加して編集をくわえるために VSCode を起動します。

VSCode へのパスが適切に設定されていれば Git Bash から code . & と入力することで VSCode を起動することができます。

$ code . &

上記コマンドの末尾に & (読み方は情報 1 で習ったようにアンパサンド) を付けずに実行すると VSCode のウィンドウを閉じるまで Git Bash が操作できない ので注意してください。このように & をつけて起動することを「バックグラウンド実行」といい、Linux 操作の基本として知られているので覚えておいてください (現在利用している Git Bash は Linux 互換環境です)。

VSCode で README.md を新規作成して以下の内容をコピペして保存してください。ここでは、保存操作を確実に実行してください (保存しないまま操作すると以降の結果が違ってくるので注意してください)。

# first commit
- フォルダの中身: (空)

# 2nd commit「README.md と aaaa.txt を追加」
- フォルダの中身: `README.md`,`aaaa.txt`

VSCode のマークダウンプレビュー機能

VSCode でマークダウン形式のファイルを編集しているとき、下記のアイコンを押下するか、ショートカットキー Ctrl+K,V を入力すると「マークダウンのプレビュー表示」ができます。Ctrl+K,V は「Ctrl」を押しながら「K」を押下、つづいて「Ctrl」を離して「V」を押下する操作です。

img

また、同様に aaaa.txt というファイルも新規作成してください。このファイルの中身は空で問題ありません (何かを記述してもよいです)。

そして README.mdaaaa.txtステージング して 2nd commit「README.md と aaaa.txt を追加」 というコミットメッセージをつけて コミット してください。これは VCode から実行しても、Git Bash からコマンドを入力して実行してもどちらでも問題ありません

VSCode から変更内容をステージングしてコミットする

左端の ソース管理 のアイコンをクリックして「ソース管理」パネルに切り替えます。

変更」から「」のアイコンをクリックしてファイルをステージング (=コミット対象として選択) して、テキストボックスにコミットメッセージを入力してから「 コミット」のボタンを押下します。このセクションでは GitHub は使用しないので「コミットしてプッシュ」や「コミットして同期」ではなく「コミット」を選んでください。

img

今後、「ステージングとコミットの操作は再解説しない」ので覚えておくようにしてください。

なお、コミットメッセージを空欄にしてコミットボタンを押下してしまったときの対応は、前回講義のファイルの作成とコミット のコラム「コミットメッセージを付けずにコミット操作をすると…」を参照してください。

コマンドライン から変更内容をステージングしてコミットする

コマンドラインからは git add --all ですべての変更内容をステージングして、git commit -m "xxxxx" でコミットができます。

$ git add --all
$ git commit -m "2nd commit「README.md と aaaa.txt を追加」"

git add --all の代わりに、git add README.md aaaa.txt のように対象となるファイルを明示的に指定しても実質的に同じ動作になります。


git log --onelineコミット履歴の確認 をします (VSCode からコミットした場合もコマンドラインから必ず履歴の確認をしてください)。以下のようになっていれば問題ありません (繰返しになりますがコミットハッシュの値は違っていても問題ありません)。

$ git log --oneline
9a305d1 (HEAD -> main) 2nd commit「README.md と aaaa.txt を追加」
d0e8462 first commit

ここで「2nd commit」のところに (HEAD -> main) という表記があることに着目してください (重要)。これについての詳細は後で解説しますが「2nd commitn」に対して main というブランチのポインタが紐づいており、さらに main には HEAD というポインタが紐づいていることを意味します。ポインタとは「しおり」や「ブックマーク」「目印」をイメージしてください。


このあともコミットメッセージを「3rd commit …」「4th commit …」のように続けていきますが 実務ではこのような「何番目のコミット」ようなメッセージの付け方はしないので注意してください (first commmit は例外)。いまは、後で行なう実験を分かりやすくするために、このようなコミットメッセージにしています。

4.1.3 直前のコミットを取り消す

VSCode で 直近のコミットをやり直したいとき (例えば「コミットメッセージを誤った」「変更の漏れがあった」などでコミットを取り消したいとき) は、次のように「前回のコミットを元に戻す」を選択してください。

img

同様に コマンドラインから直近のコミットをやり直したいとき は、次のように git reset --soft HEAD^ を実行します。

$ git reset --soft HEAD^

ただし、VSCode の場合でも、コマンドラインの場合でも、この取り消し操作は「当該コミットをリモートリポジトリにプッシュしたあとには絶対に実行しない」ようにしてください (特にチーム開発をしている場合は絶対にしないでください)。リモートリポジトリとローカルリポジトリの履歴に不整合が生じて、その修正のためにコマンドラインを使って相当に面倒な修正が必要となります。

コミットメッセージだけの修正

直前のコミットについて「コミットメッセージだけ」を修正したい場合は、次のように --amend をつけて git commit を実行します。

$ git commit --amend -m "新しいコミットメッセージ"

これも、リモートリポジトリにプッシュした後には実行しないようにしてください。git 中級者になってリモートとローカルの不整合を自力で手動修正できるレベルになったら、プッシュ後に実行しても問題ありませんが・・・。

4.1.4 「3rd commit」

README.md を以下のように書き換えて保存してください (VSCode を使用していると保存操作を忘れることが多いです。コミット前には確実に保存してください)。また bbbb.txt という空ファイルをプロジェクトフォルダに追加してください。そして、README.mdbbbb.txtステージング して 3rd commit「bbbb.txt を追加」 というコミットメッセージをつけて コミット してください。

# first commit
- フォルダの中身: (空)

# 2nd commit「README.md と aaaa.txt を追加」
- フォルダの中身: `README.md`,`aaaa.txt`

# 3rd commit「bbbb.txt を追加」
- フォルダの中身: `README.md`,`aaaa.txt`,`bbbb.txt`

git log --onelineコミット履歴の確認 をします。以下のようになっていれば問題ありません。

$ git log --oneline
3757332 (HEAD -> main) 3rd commit「bbbb.txt を追加」
9a305d1 2nd commit「README.md と aaaa.txt を追加」
d0e8462 first commit

ここで、さきほどまで「2nd commit」のところにあった (HEAD -> main) が「3rd commit」のところに移動していることに着目してください (=ブランチポインタ main が「3rd commit」を指し示すようになり、HEAD ポインタは引き続き main を指し示していることに着目してください)。

現時点では、上記の説明がピンとこない、モヤモヤすると思いますが、以下、読み進めていくことで段々と理解できると思います。

4.1.5 「4th commit」

同様に README.md を書き換えて保存し、cccc.txt という空ファイルをプロジェクトフォルダに追加し、ステージング してから 4th commit「cccc.txt を追加」 というコミットメッセージで コミット してください。

# first commit
- フォルダの中身: (空)

# 2nd commit「README.md と aaaa.txt を追加」
- フォルダの中身: `README.md`,`aaaa.txt`

# 3rd commit「bbbb.txt を追加」
- フォルダの中身: `README.md`,`aaaa.txt`,`bbbb.txt`

# 4th commit「cccc.txt を追加」
- フォルダの中身: `README.md`,`aaaa.txt`,`bbbb.txt`,`cccc.txt`

git log --onelineコミット履歴の確認 をします。

$ git log --oneline
15c7ee4 (HEAD -> main) 4th commit「cccc.txt を追加」
3757332 3rd commit「bbbb.txt を追加」
9a305d1 2nd commit「README.md と aaaa.txt を追加」
d0e8462 first commit

ここでは「4th commit」のところに (HEAD -> main) が移動していることに着目してください。

HEAD について

HEAD というポインタ (目印・ブックマーク・しおり) は、(HEAD -> main)(HEAD -> dev)(HEAD -> bug-fix) のように、基本的には ブランチポインタ (ブランチの先端を示すポインタ) を指し示します。

しかし、状況によっては、以下のように HEAD が特定のブランチポインタを指さない状態 (通称「detached HEAD」な状態) になることもあります。

15c7ee4 (main) 4th commit「cccc.txt を追加」
3757332 3rd commit「bbbb.txt を追加」
9a305d1 (HEAD) 2nd commit「README.md と aaaa.txt を追加」
d0e8462 first commit

detached HEAD の状態は 特定のコミットをチェックアウトして、プロジェクトフォルダを過去の状態に戻したとき などに発生します。この状態で新たな変更を加えてコミットを追加すると、そのコミットはどのブランチにも所属しないものとなり、あとから参照することが難しくなります (もし、その状態で変更を加えてコミットする場合は、新たなブランチを作成することが推奨されます) 。このことから detached HEAD の状態での作業は慎重に行う必要があります。

4.2 GUI による変更履歴/コミットグラフの確認

コマンドラインからは git log --oneline でコミット履歴 (変更内容を記録した履歴) が確認できました。これは、先にインストールした Git Graph という拡張機能を使って VSCode からも確認ができます。実際に確認してみてください。

img

上記の「Git Graph 表示」が、以下の「git logの出力」と同じ情報を表していることを確認してください。Git Graph では、中抜きの丸印が HEAD を表しています。

15c7ee4 (HEAD -> main) 4th commit「cccc.txt を追加」
3757332 3rd commit「bbbb.txt を追加」
9a305d1 2nd commit「README.md と aaaa.txt を追加」
d0e8462 first commit

4.3 プロジェクトフォルダを過去の状態に戻す (Git Graph 編)

git はバージョン管理システムであり、プロジェクトフォルダの内容を過去の時点 (任意のコミットの時点) に戻すことができます。例として「2nd commit (=プロジェクトフォルダ内に README.mdaaaa.txt だけがあった状態)」に戻してみます。

以下のスクリーンショットを参考に Git Graph のタブを表示して「戻したい時点のコミット行」をマウスでクリック選択し、その後、右クリックメニューから「Checkout…」を選択します。

作業中に「Are you sure you want to checkout commit 9a305d1a? This will result in a ‘detrached HEAD’ state. (コミット a305d1a に切り替えてもよろしいですか?これにより「detached HEAD」の状態になります)」という確認がでた場合は「Yes, checkout」を選択します。

img

この操作により、リポジトリ (収納庫) のなかから「選択したコミット (9a305d1a) 」を Checkoutする (チェックアウト: リポジトリから取り出し手続きする) という処理が行われます。そして、チェックアウトした内容は ワーキングツリー (=プロジェクトフォルダ) に展開されます。つまり プロジェクトフォルダの内容が「2nd commit」時点のものに戻ります。

Git Graph ではチェックアウト操作をすると、以下のように HEAD (=中抜きの丸印) が「2nd commit」に移動します。プロジェクトフォルダのファイル構成が、そのコミット時点のものになっていることを確認してください。また README.md の内容が「2nd commit」時点の記述になっていること (ファイルの内容も過去時点に戻っていること) も確認してください。

img

つづいて 最新 (=4th commit) の状態 に戻します。Git Graph の「4th commit」のコミット行を選択し、右クリックから「Checkout…」を選択してください。ワーキングツリー (プロジェクトフォルダ) に bbbb.txt, cccc.txt が復活し、また README.md の内容も最新 (=4th commit) のものになっていることを確認してください。

このように git ではプロジェクトフォルダの中身を過去コミット時点に戻すことができます。必要があれば、過去のコミットに戻した状態で、エクスプローラを使ってファイルを別フォルダに移動すること などもできます。

4.4 プロジェクトフォルダを過去の状態に戻す (コマンドライン編)

プロジェクトフォルダを過去の状態に戻す操作は、コマンドラインからは次のように実行できます。

まずは git log を使って、戻したい時点のコミットの コミットハッシュ を調べてメモします。ここでは「2nd commitの状態に戻したい (切り替えたい) のでメモすべき値は 9a305d1 となります。

$ git log --oneline
15c7ee4 (HEAD, main) 4th commit「cccc.txt を追加」
3757332 3rd commit「bbbb.txt を追加」
9a305d1 2nd commit「README.md と aaaa.txt を追加」
d0e8462 first commit

次のようにコミットハッシュを引数に与えて git checkout 9a305d1 のように gitチェックアウトコマンド を実行します。

$ git checkout 9a305d1
Previous HEAD position was 15c7ee4 4th commit「cccc.txt を追加」
HEAD is now at 9a305d1 2nd commit「README.md と aaaa.txt を追加」

最近の git (Git 2.23 以降) では checkout ではなく git switch 9a305d1 --detach のような gitスイッチコマンド を使うことが推奨されています (実質的に同じコマンドです)。

$ git switch 9a305d1 --detach
HEAD is now at 9a305d1 2nd commit「README.md と aaaa.txt を追加」

コマンドを実行したら、VSCode の Git Graph を確認してください。Git Graph 上でも「2nd commit」に戻っていることが確認できます (必要に応じて GitGraphタブ の右上にある「」アイコンをクリックして画面更新してください)。

ここで注意すべきは、この状態でコマンドラインから git log --oneline を実行したときの結果です。現時点で履歴を表示すると次のように 3rd と 4th commit は表示されず、戻るべき「4th commit」のコミットハッシュ が確認できません。

$ git log --oneline
9a305d1 (HEAD) 2nd commit「README.md と aaaa.txt を追加」
d0e8462 first commit

このようなときは git reflog --oneline (引数は log ではなく reflog) を実行して、そこから「4th commit」のコミットハッシュ (=15c7ee4) を調べて git switch 15c7ee4 --detach のようにコマンドを打ち込んで最新の状態に戻ることができます。

$ git reflog --oneline
9a305d1 (HEAD) HEAD@{0}: checkout: moving from main to 9a305d1
15c7ee4 (main) HEAD@{1}: commit: 4th commit「cccc.txt を追加」

$ git switch 15c7ee4 --detach
Previous HEAD position was 9a305d1 2nd commit「README.md と aaaa.txt を追加」
HEAD is now at 15c7ee4 4th commit「cccc.txt を追加」

ブランチのポインタを指定してチェックアウト/スイッチ

「特定のコミット」と「ブランチのポインタ」が紐づいている場合は、そのブランチの名前を指定して git checkout [ブランチ名] あるいは git switch [ブランチ名] を実行してチェックアウト/スイッチができます。

例えば、現在のケースでは以下のように main というブランチのポインタが「4th commit」を指し示しているので git checkout main または git switch main と入力して「4th commit」に戻ることもできます。

15c7ee4 (main) 4th commit「cccc.txt を追加」
3757332 3rd commit「bbbb.txt を追加」
9a305d1 (HEAD) 2nd commit「README.md と aaaa.txt を追加」
d0e8462 first commit

4.5 コミット間の差分を確認する

Git Graph を使って、任意のコミット間の差分 (=どの部分が異なるのか) をグラフィカルに確認することができます。ここでは、README.md について「4th commit」と「2nd commit」の差分 (=どこが違うのか) を確認してみます。

まずは、「新しいほうのコミット行」をクリックして選択します。

img

次に、Ctrl を押下しながら「古いほうのコミット行」を選択します (選択後は Ctrl を離してください) 。つづいて差分を確認したいファイルをクリックします。

img

以下のスクリーンショットのように差分を確認することができます。緑背景になっている部分が追加された行になります (ここでは該当行はありませんが、削除されている行があれば赤背景で表示されます)。なお、VSCode のウィンドウを横に十分に広げれば、「旧」と「新」を左右にならべて比較した画面で差分の確認ができます。

img

コマンドラインからはコミットハッシュを指定して git diff 9a305d1 15c7ee4 -- README.md のように差分を確認できます。差分表示には Git Graph を使用することをお勧めします。

以上の作業が終わったら、必ず Git-Playground のプロジェクトフォルダは、削除するか、フォルダ名を変更 しておいてください。

5 GitHub を使用したチーム開発の概要

GitHub のほか、BacklogBitbucket のような「git リポジトリのホスティングサービス」を利用することで 複数人によるチーム開発を効率的・効果的に進めることができます。このような開発スタイルは OSS (Open Source Software) の開発はもちろん、大学の研究室や企業における実開発でも広く採用されています。

GitHub のようなリモートリポジトリは、チーム開発で チーム全員のソースコードの変更を集約・統合・管理する中心的な場所 として位置づけられることから 中央リポジトリ とも呼ばれます。

GitHubを利用したチーム開発の流れ (概要)

チーム開発では、メンバー各自が PC にローカルリポジトリを作成すると共に、GitHub などオンライン上に (1 個の) 中央リポジトリを作成し全員で「共有」します。

そして、メンバーはそれぞれのローカル環境で担当する範囲の開発を進め、ある程度、完成したものを中央リポジトリに「プッシュ (アップロード)」していきます。また、定期的に中央リポジトリから変更内容を「プル (ダウンロード)」することで、他のメンバーによる変更をローカルリポジトリに取り込みます。これを繰返すことでチーム全体でコードを共有・統合・同期しながら開発を進めます。

5.1 最もシンプルなチーム開発フロー

いつもの「アリス」と「ボブ」を例に GitHub を利用してチーム開発する際の具体的なフロー (流れ) を示します。このフローでは「フォーク」や「プルリクエスト (プルリク)」は使用せず、ブランチの機能コラボレータの設定 だけを利用する最もシンプルな方法を示します。

未知の用語 (ブランチ (枝・分岐・支流) やコラボレータなど) もでてきますが、まずは全体の流れを理解しましょう。

(準備・段取りフェーズ)

  1. アリスが「ローカルリポジトリ」を作成し、その main ブランチに プロジェクトのスケルトン (=基盤・土台・フレームとなるプログラム) を作成します。
  2. アリスが、GitHub に空の「中央リポジトリ (リモートリポジトリ)」を作成し、ローカルリポジトリの内容を プッシュ (アップロード) します。
  3. アリスが、GitHub の設定ページからボブを「コラボレータ」として招待する手続きをします。
  4. ボブは招待通知のメールから GitHub にアクセスし、アリスの作成した「中央リポジトリ」に「コラボレータ」として参加することを承諾します。ボブはコラボレータとなったことで この中央リポジトリに「プッシュ」すること ができるようになります。
  5. ボブが「中央リポジトリ」をクローン して「ローカルリポジトリ」を作成します。

(開発編フェーズ)

  1. アリスとボブは、ローカルリポジトリで mainブランチを起点に新しいブランチを作成して、その ブランチ のうえで個別に担当部分の開発をします。
    • ここでは、アリスが feature/dev-alice というブランチを作成し、ボブが feature/dev-bob というブランチを作成するものとします。
  2. アリスは feature/dev-alice で自分の担当範囲の開発を進めます。そして、その開発が完了したら main ブランチに feature/dev-alice ブランチを マージ (取り込み) します。
  3. 同様に、ボブも自分の担当部分について feature/dev-bob ブランチで開発を進めます。そして、開発が完了したら mainfeature/dev-bobマージ します。
  4. アリスとボブは 定期的に「中央リポジトリ」に自分のブランチを「プッシュ」するとともに、「プル」により中央ブランチの main ブランチにある最新の内容をローカルリポジトリに取り込みソースコードの同期と統合を図ります

このような方法で、アリスとボブは 各自が担当範囲を並行・独立して開発しながらも、中央リポジトリの main ブランチには 全体として統合・整合されたソースコードが 積み詰みあがっていくことになります。この手法のポイントを整理すると次のようになります。

コラボレータを設定しないチーム開発

不特定多数が参加する OSS 開発などでは、開発メンバーをコラボレータに設定することなく「フォーク」と「プルリク (プルリクエスト)」という機能を使用してチーム開発する手法が採用されます。

この方式の利点は、開発に関わるメンバーが オリジナルの中央リポジトリに直接変更を加える ことなく、独立して作業を進めることができる点です。また、中央リポジトリの管理者 (オーナー や 数名のコラボレータ) は、提出されたプルリクエストをレビュー (=コードの品質や機能を確認・評価) し、品質を確保しながら変更を取り込むこと ができます。

6 コラボレータの設定

ここでは、GitHub で「コラボレータ」を設定する手順を説明します。ここでは「アリス」がオーナーの中央リポジトリに、コラボレータとして「ボブ」を参加させるという設定で説明します。

なお、ここからの操作はあとの演習で実際に体験してもらうので、いまは実行する必要はありません。解説を読んで理解するだけでOKです。


はじめに アリス側の操作 です。

GitHub にアクセスして、コラボレータとして「ボブ」をメンバーに加えたいリポジトリのページを開きます。上部にある「Settings」タブを選択して画面を切り替え、左パネルから「Collaborators」を選択します。

img

初期状態では「You haven’t invited any collaborators yet (まだコラボレーターを招待していません)」となっているので、コラボレータを追加するために「Add people」ボタンを押下します。

img

テキストボックスに「Bob のユーザーカウント (≠ 表示名)」を入力します。

img

候補となるユーザーが表示されるので、そこからボブのアカウントを選択して「Add XXXX to this repository」のボタンを押下して、「ボブ」をコラボレータとして招待します。

img

招待の処理をすると、Bob について以下のように「Pending Invite」というステータスになります。これは、ボブ宛に招待通知が送信済みであるが、まだボブが「承認・承諾」の手続きをしていない状態であることを意味します。

img

ここからは ボブ側の操作 となります。

アリスがコラボレータの招待手続きをすると、ボブには以下のようなメールが届きます。メールにある「View invitation」を押下します。

なお、メッセージの意訳は次のようになります。

この招待状を承諾するか、辞退するかを選べます。また、https://github.com/ZZZZZ1980/Git-Playground にアクセスしてリポジトリを確認するか、@ZZZZZ1980 の情報を少し見て、彼らについてもっと知ることもできます。

この招待は 7 日間で期限が切れます。

img

GitHub のページにアクセスするのでコラボレータとして参加することを承認する場合は「Accept inviation」を押下します。なお、メッセージの意訳は次のようになります。

「Git-Playground」のオーナー (ここではアリスのこと) は以下の情報を確認できます
・あなたの公開プロフィールの情報
・このリポジトリ内での特定の活動
・リクエストが発信された国
・このリポジトリにおけるあなたの権限のレベル
・あなたの IP アドレス

img

再びアリス側の操作です。

当該リポジトリの「Setting」の「Collaborators」の項目を確認するとボブについて以下のような表示になっていることが確認できます。なお、ボブのコラボレータ権限を解除するためには、右端の「Remove」を選択します。

img

7 ブランチの利用

コラボレータを設定して GitHub を利用してチーム開発する場合、git の ブランチ という機能を利用することが (実質的には) 必須となります。

いま、「アリス」と「ボブ」の 2 名でチーム開発することを考えます。具体的には、アリスがプログラムの骨格となる「スケルトン」を作成を担当して、それに対してボブが「機能 B」の開発 (スタブの作成、実装、リファクタリング) を担当し、アリスも「機能 A」の開発を担当するという役割分担でチーム開発 (共同開発) することを考えます。

知っておいてほしいプログラミング用語「スタブ」と「リファクタリング」

スタブ (stub)」とはプログラミングの分野では「まだ完成していない関数やクラス、モジュール」あるいは「仮の機能しか持っていない関数やクラス、モジュール」を指す用語として使われています。例えば、関数について 実際の処理を実装する前に、関数の名前や引数、返り値の形式だけを定義した ようなものが「スタブ」と呼ばれます。

リファクタリング (refactoring)」 とは、コードをより読みやすく、保守しやすく、再利用しやすい形に改善する作業を意味します。

7.1 ブランチを「使わないとき」と「使うとき」のコミットグラフの違い

ブランチを作成せずに、デフォルトブランチ main で、アリスとボブが開発 (実装・コミット・プッシュ) していったときの コミットグラフ は次のようになります。

img

一方で、アリスは feature/dev-alice というブランチを作成して「機能A」を開発し、ボブは feature/dev-bob というブランチを作成して「機能B」を開発したときの コミットグラフ は次のようになります。

img

アリスは feature/dev-alice というブランチ (上記でマゼンタ色で表示) で作業とコミットを繰返し、「機能A」の開発を終えたら、それを main に取り込んでいることが分かると思います。

図から読み取れるように、ブランチを使う開発とは「 main から feature/dev-alice に分岐して作業を進め、それが終わったら feature/dev-alice main にマージする (取り込む) 」という流れが運用の基本形になります。

7.2 ブランチを利用することのメリット

git において ブランチ (branch) とは「枝」「分岐」「支流」といった意味で使われ 任意のコミットから分岐をつくる ことで、元のブランチや他のブランチに影響を受けず(同時に影響を与えず)に開発作業とコミットを可能にする機能です。

例えば、main ブランチの任意のコミット (=アリスがスケルトンを作成した時点) から feature/dev-alicefeature/dev-bob というブランチを作成し、前者 (図中のマゼンタのブランチ) でアリスが「機能A」の開発を行い、後者でボブ (図中の緑色のブランチ) が「機能B」の開発を進めるとします。

img

このようにすることで、アリスは ボブの影響を受けずに「機能A」の開発 を進めることができます。ここで ボブの影響を受けずに開発 とは次のことを意味します。

ブランチを使えばコンフリクトが生じないの?!

「ブランチを使えば永遠にコンフリクトが生じない」というわけではありません。アリスが「機能A」の開発を完了し feature/dev-alicemainマージするとき (下図の矢印部のように支流の変更を源流に取り込むとき) にはコンフリクトが発生する可能性があります。

img

しかしながら 開発途中にプッシュやプルするたびにコンフリクトが発生して解消に追われる よりも、担当範囲の開発が完了して マージをする段階 でまとめて解消できるほうが格段に労力と時間を削減できます。

また、「機能A」の開発途中でも (必要があれば) アリスは mainfeature/dev-alice にマージして段階的にコンフリクトを解消することができます。

7.3 mainブランチだけで開発を進めることのデメリット

アリスもボブも新たにブランチをつくることなく、デフォルトの main ブランチの上で開発することも技術的には可能です。しかし、この方法を選ぶと、プルやプッシュの操作をするたびにコンフリクトが発生するリスクがあります。さらに、相手の開発の途中段階のコードが随時自分の環境に組み込まれるため、作業の混乱も生じやすくなります

例えば、下図の矢印の部分でコンフリクトが生じる可能性があります。

マゼンタ色の矢印部分はアリス側で、緑色の矢印部分はボブ側で コンフリクトが発生し、その解消をしなければならない可能性 が生じます。

img

基本的に、リモートリポジトリに対して「プッシュ」しようとしたとき リモート側の当該ブランチの直前のコミットが他人により行われて いると、(自分のローカルリポジトリの状態とリモートのリポジトリの内容が異なることに起因して) 以下のようにプッシュが拒否されることがあります。

img

Can’t push refs to remote. Tty running “Pull” first to integrate your changes.
(意訳) リモートへの「プッシュ」ができません。あなたのローカルの変更とリモートの変更が衝突している可能性があります。まずは「プル」を実行し、リモートの最新の変更をローカルに取り込んで、それを統合してから再度「プッシュ」を試してください。

この場合、まずは「プル」または「フェッチ・マージ」によってリモート側の変更をローカル側に取り込み統合 (マージ) する必要が生じます。そして、その「マージ」の過程でコンフリクトが生じる可能性があります。

一方で、feature/dev-alice のようなブランチを作成して、そこで開発を進める場合、feature/dev-alice というブランチに「プッシュ」するのは アリスだけ です (運用ルールを守らずにボブが feature/dev-alice にプッシュするようなことがあれば別ですが) 。そのため、基本的には「リモート側の当該ブランチの直前のコミット」=「自分のコミット」という状況になり、コンフリクトが起こることが無くなります。

8 ブランチを作成してチーム開発する方法

以下、2名1組による実習になります (3名1組の場合は1名は見学になります)。「アリス役」と「ボブ役」を決めて作業してください。

チーム開発のチュートリアルとして、最終的に以下のような「コミットグラフ」が形成されるような開発を体験していきます。なお、相手役の操作解説も飛ばさず読み、相手役のPCの操作画面も覗き込んで学ぶ ようにしてください。また、授業時間外には 復習として役割交代して体験 してみてください。

img

手順を飛ばすなどで失敗した場合は リモートリポジトリとローカルリポジトリを完全削除して、再度、最初から (コラボレータの設定から) やり直してください (やり直しのときは初回の1/3も時間がかからないと思います)

git/GitHubは繰返し体験して慣れるしかない

git/GitHub の利用は、開発の「目的」ではなく、開発の「手段」です。そして、git/GitHub は単なる「ツール (道具)」に過ぎません。git/GitHub の内部の仕組みや細かな挙動を理解することは重要ですが、極論を言えば 使えればよい です (だって道具だもの) 。自動車でも、駆動原理を理解するより、運転できるようになることが優先されるのと同じです。

git/GitHub の習得には とにかく繰返し積極的に使用し、慣れることと、頭と手先で覚えていこと が必要です。解説を見ながらなら使えます というレベルでは不十分です。それは「教本を見ながらなら自動車を運転できます」と言っているようなものです。そんな運転者が公道で自動車を運転していたら恐ろしいですよね? 同じく、そんな git/GitHub の習練度の人が (業務レベルの) チーム開発に参加していたら恐いのです。

「この授業で解説を読みながら問題なく操作できたからOK」ではなく、授業時間外や個人開発、その他の開発活動でも積極的に使用して習得するように努めてください。

8.1 「アリス役」のステップ 1

GitHub に Git-Playground という 空のリポジトリ を作成してください (README.md.gitignore を含めないでください)。公開設定は「パブリック」としてください。つづいて、前半の「コラボレータの設定」の解説に従って、ボブ役をコラボレータとして招待してください。

また、この リポジトリのURL (https://github.com/XXXX/Git-Playground.git) をメモしておいてください (末尾の .git は重要なので抜けないように)。

img

8.2 「ボブ役」のステップ 1

前半の「コラボレータの設定」の解説に従って コラボレータ招待を承諾 してください。また、アリスと同様に リポジトリのURL (https://github.com/XXXX/Git-Playground.git) をメモしておいてください。この URL は アリスがメモしたURLと完全に同じになるはずです。

8.3 「アリス役」のステップ 2

PCのローカルストレージの適当な場所に Git-Playground というプロジェクトフォルダを新規作成してください。ターミナルを Git Bash モードで開いて、その作成したプロジェクトフォルダの中に移動してください (pwd コマンドなどで作成したプロジェクトフォルダの中にいることを確実に確認してください)。

以下のコマンドで「ローカルリポジトリとしての初期化」、「空状態での初期コミット」、「ローカルリポジトリに紐づける中央リモートリポジトリ (リモートリポジトリ) の設定」「リモートリポジトリへのプッシュ」をします。3番目のコマンドでは https://github.com/... の部分を先ほどのメモに置き換えてください。

$ git init
$ git commit --allow-empty -m "first commit"
$ git remote add origin https://github.com/XXXX/Git-Playground.git
$ git push -u origin main

次に VSCode を起動してください。

$ code . &

プログラムの「スケルトン」として、次の内容の main.py を作成して保存してください。

また、プログラムが「正常実行できること」を確認してください。今回は (pip install による追加ライブラリのインストール予定はないので) python -m venv .venv で仮想環境を作成する必要はありません。なお、VSCode で Python プログラム を実行する方法を忘れた学生は第09回の講義資料 を参照してください。

import math

# [機能A]@アリス担当 #############


# [機能B]@ボブ担当 ###############


# メイン処理 #####################
if __name__ == "__main__": 

  print("start.")

  ## 機能Aの実行

  ## 機能Bの実行

  print("end.")

次に .gitignore というファイルを作成して 、以下の内容を記述して保存してください。この .gitignore ファイルには git/GitHub 管理をしないファイルやフォルダを記載します。例えば VSCode のプロジェクト固有の設定を保存する .vscode フォルダや、仮想環境を展開する .venv フォルダ、パスワードや個人的なメモを書いたファイルなどは .gitignore に記述して git/GitHub の管理から外します

ここでは .gitignore の詳細は解説しないので、詳しくは「.gitignore 書き方」などで検索してください。

.vscode/
.venv/

VSCode から main.py.gitignore をステージングし、「アリスがスケルトンを作成」というコミットメッセージを付け「コミット」してください。また、その後、以下のように「プッシュ」をしてください。

img

Git Graph を確認すると次のようになっているはずです。

img

8.4 「ボブ役」のステップ 2

ターミナルを Git Bash モードで開いて Git-Playground というプロジェクトフォルダを作成したいフォルダに移動して開いください。

注意

Git-Playground フォルダを作成する」のでははなくて「Git-Playground フォルダを作成したいフォルダに移動」してください。例えば、最終的に C:\Users\xxxx\Documents\Git-Playground を作成したいのなら、Git Bash のカレントフォルダが C:\Users\xxxx\Documents になるようにしてください。

以下のコマンドで、中央リポジトリをクローンして、Git-Playground の中部に移動してください。最初のコマンドでは https://github.com/... の部分は先ほどメモしたURLに置き換えてください。

$ git clone https://github.com/XXXX/Git-Playground.git
$ cd Git-Playground/

git log --oneline でコミット履歴を確認してください。

$ git log --oneline
91fe5c4 (HEAD -> main, origin/main, origin/HEAD) アリスがスケルトンを作成
b7d80d6 first commit

また 現在のブランチを確認するために git branch を実行してください。以下のような結果になります。これは、ローカルリポジトリに main というブランチが1個だけ存在し、* 印の main が現在のブランチであることを意味しています。

$ git branch
* main

いまからボブが「機能B」を開発するために「アリスがスケルトンを作成」というコミットを起点に feature/dev-bob というブランチを新規作成し、そのブランチに切り替えます(スイッチします)。次のコマンドを実行してください。なお、新機能を開発するブランチには、慣例的に feature/ というプレフィックスを付けます。

$ git branch feature/dev-bob
$ git switch feature/dev-bob

これで feature/dev-bob というブランチが作成され、そのブランチに切り替えられたことになります。念のため git branch で確認します。feature/dev-bob* 印がつき、現在はfeature/dev-bob ブランチに切り替わっていることが確認できます。

$ git branch
* feature/dev-bob
  main

実際にコードを編集して「機能B」を実装していくために VSCode を起動してください。

$ code . &

VSCode では画面左下で「現在のブランチ」を確認できます。確かに VSCode 上でも feature/dev-bob に切り替わっていることを確認してください。

img

まずは「機能B」のスタブを作成します。main.py を次のように編集してください (02、08-09、19行目に編集を加えています)。また、編集したプログラムが正常に実行できることを確認してください。

import math
import datetime

# [機能A]@アリス担当 #############


# [機能B]@ボブ担当 ###############
def func_B ():
  print('func_B called.')

# メイン処理 ####################
if __name__ == "__main__": 

  print("start.")

  ## 機能Aの実行

  ## 機能Bの実行
  func_B()

  print("end.")

動作が確認できたら「ボブが機能Bのスタブを作成」というコミットメッセージでファイルの変更を「コミット」します。つづいて「機能B」のつくり込みをします。関数 func_B を以下のように書き換えて動作することを確認します。

def func_B ():
  t1 = datetime.datetime.now() # 現在時刻
  t2 = datetime.datetime(2023,11,4,10,00,00) # 11/4 10:00
  diff = t2 - t1
  days = diff.days
  hours= diff.seconds // 3600
  print('高専祭まで、あと',end='')
  print(days,end='')
  print('日と',end='')
  print(hours,end='')
  print('時間')

動作が確認できたら「ボブが機能Bを実装」というコミットメッセージで「コミット」します。その後「Branchの発行」というボタンを押下します。

img

8.5 「アリス役」のステップ 3

VSCode で作業します。VSCodeでは定期的にフェッチ (中央リポジトリの内容を取得すること)」が自動実行されますが、念のために手動でも「フェッチ」をしておきます。下図のように Git Graph のタブの右上の「 雲マーク」のアイコンをクリックして、中央リポジトリの最新情報を取得します。

この結果、次のようなコミッグラフが得られます。

img

ボブの作業によって中央リポジトリ(origin) のコミットは伸びていますが、中抜きの丸印で表されるアリスの HEAD (現在コミット位置) は 「アリスがスケルトンを作成」に留まっていることが 分かります。

いまからアリスが「機能A」を開発するために、この「アリスがスケルトンを作成」というコミットを起点に feature/dev-alice というブランチを新規作成し、そのブランチに切 り替えます(スイッチします)。さきほどは、コマンドラインからこの作業を実行しましたが、今回は VSCode で行ってみます

画面左下の現在のブランチを表示している部分をクリックします。画面上部にメニューが表示されるので「新しいブランチの作成…」を選択します。

img

新規作成するブランチの名前 feature/dev-alice を入力して Enter を押下します。

img

これでブランチが作成され、それが現在のブランチになります。画面左下の表示が feature/dev-alice になっていることを確認してください。

img

VSCode で main.py を開きます。内容が「アリスがスケルトンを作成」のコミット時点のものであることを確認してください。ボブは feature/dev-bob で行なわれているので、こちらは影響を受けていません。

「機能A」のスタブを作成として次のように main.py を編集して保存し「アリスが機能Aのスタブを作成」というコミットメッセージで「コミット」します。さらに「ブランチの発行」を実行します。

import math
import fractions

# [機能A]@アリス担当 #############
def func_A ():
  print('func_A called.')

# [機能B]@ボブ担当 ###############


# メイン処理 ####################
if __name__ == "__main__": 

  print("start.")

  ## 機能Aの実行
  func_A()
  
  ## 機能Bの実行

  print("end.")

コミットグラフを確認すると次のようになっていることが確認できます。

img

つづいて「機能A」の実装をします。関数 func_A を以下のように書き換え、動作することを確認します。

def func_A ():
  ans = fractions.Fraction(2,3)+fractions.Fraction(4,6)
  print(f'2/3 + 4/6 = {ans} (= {float(ans):.2f})')  

アリスが機能Aを実装」というコミットメッセージで「コミット」します。ソース管理パネルには、既に「ブランチの発行」を終えているので「変更の同期」が表示されます。このボタンを押下することで、中央リポジトリに「プッシュ」ができます。

img

現時点のコミットグラフは次のようになっているはずです。

img

8.6 「ボブ役」のステップ 3

VSCode で作業します。繰返しになりますが、VSCodeでは定期的にフェッチ (中央リポジトリの内容を取得すること)」が自動実行されます。アリス役のステップ3と同様の方法で、手動で「フェッチ」して、コミットグラフを確認してください。

img

機能B」のリファクタリングとして、次のように main.py を編集して保存してください。

def func_B ():
  t = datetime.datetime(2023,11,4,10,00,00) # 11/4 10:00
  diff = t - datetime.datetime.now()
  days = diff.days
  hours= diff.seconds // 3600
  print(f'高専祭まで、あと{days}日と{hours}時間')

保存したら「ボブが機能Bをリファクタリング」というコミットメッセージで「コミット」を実行します。さらに「変更の同期」を実行します。なお、この「コミット」して「変更の同期」をするという操作は、コミットボタンを展開して「コミットして同期」からまとめて実行もできます。

これでボブの開発が終了したので、この feature/dev-bob を源流の main にマージします(取り込みます)。マージする場合は 取り込む側 (≠取り込まれる側) のブランチ で操作します (重要ポイント) になります。

feature/dev-bobmain にマージします。今回は、コマンドライン (Git Bash) で実行してみます。まずは git fetch で中央リポジトリの最新の情報を取得します。次に git switch main で現在のブランチを main に切り替えます。念のために git branch で、現在のブランチが main であることを確認します。

$ git fetch

$ git switch main
Switched to branch 'main'
Your branch is up to date with 'origin/main'.

$ git branch
  feature/dev-bob
* main

次のコマンドで feature/dev-bob ブランチを現在のブランチ(=main) に取り込みます。--no-ff オプションをつけることで コミットグラフ上でブランチがマージされる様子が分かりやすくなる (明示的になる) ので付けておきます。

$ git merge feature/dev-bob --no-ff
Merge made by the 'ort' strategy.
 main.py | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

コンフリクトが生じることなくマージが完了しました (なお、コンフリクトが発生するとデフォルトエディタが起動します)。git log で状態を確認します。マージ操作によって「Merge branch ‘feature/dev-bob’」というコミットが自動作成されたことが確認できます。

$ git log --oneline
e2ffe93 (HEAD -> main) Merge branch 'feature/dev-bob'
73d84a8 (origin/feature/dev-bob, feature/dev-bob) ボブが機能Bをリファクタリング
ecc8cfc ボブが機能Bを実装
133fdd0 ボブが機能Bのスタブを作成
91fe5c4 (origin/main, origin/HEAD) アリスがスケルトンを作成
b7d80d6 first commit

このコミットを「中央リポジトリ」にもプッシュしておきます。

$ git push -u origin main

VSCode に戻って Git Graph からコミットグラフを確認してください。次のように feature/dev-bobmain に取り込まれたこと が分かります。

img

8.7 「アリス役」のステップ 4

VSCode で作業します。念のため「フェッチ」して最新の中央リポジトリの情報を取得してください。コミットグラフは次のようになっているはずです。

HEAD を表す「中抜きの丸印」が feature/dev-bob ブランチ先端の「アリスが機能Aを実装」コミットを指し示していること が分かります。つまり、ワーキングツリー (=プロジェクトフォルダ) は、feature/dev-bob ブランチ先端の「アリスが機能Aを実装」コミット時点の構成・内容になっています (「フェッチ」の操作をしても影響を受けていないことが確認できます)。

img

main.py を開きます。「機能A」の仕上げのリファクタリングとして、次のように main.py を編集して保存してください。

def func_A ():
  f = fractions.Fraction
  t1 = f(2,3)
  t2 = f(4,6)
  ans = t1 + t2
  print(f'{t1} + {t2} = {ans} (= {float(ans):.2f})')  

変更を保存したらコミットメッセージ「アリスが機能Aをリファクタリング」で「コミット」して「プッシュ」してください。これにより、現在のコミットグラフは次のようになります。

img

これでアリスが担当する「機能A」の開発が終了したので、この feature/dev-alice ブランチを main ブランチに「マージ」していきます。今度は、コマンドラインではなく VSCode を使ってマージを実行してみます。

まずは、取り込む側のブランチである main に切り替える必要があります。VSCode の画面左下にある feature/dev-alice のブランチ名をクリックして、現在のブランチを main に切り替えてください。

現在のブランチが main に切り替わったことで、コミットグラフの HEADmain のところに移動しました (下図の矢印を参照)。しかし、現状で「中央リポジトリ (orgin)」の main ブランチである origin/main は、ローカルリポジトリの main よりも先に伸びています。よって、同期が必要で、そのために「変更の同期」のボタンを押下します。

img

中央リポジトリとローカルリポジトリの同期が完了すると、次のように HEADmain ブランチのの先端に移動します (main ブランチの最新のコミットに対してマージができるようになりました)。このように マージ を行なう場合は、同期 (フェッチやプル) によって関係するブランチを 最新の状態にしておく必要 があります。

img

マージ作業をはじめていきます。現在のブランチが取り込む側のである main になっていることを再確認します (VSCode の画面左下を参照)。つづいて、ソース管理から「ブランチをマージ」を選択します。

img

マージ元のブランチの選択」として feature/dev-alice を選択します。VSCodce ではこのようにして main (=現在のブランチ) に feature/dev-alice をマージ (取り込み) する指示を与えることができます。

img

ここで main.py をすると コンフリクト が生じています。ファイル名の横の「!マーク」がコンフリクトが起きていることの通知になります。コンフリクトを解消するまではマージは完了となりません。

img

コンフリクトマーカーを削除して、ボブの更新も取り込むように編集して保存してください (コンフリクトの解消については前回資料を参照してください)。

以下のようなコードになれば、「機能A」も「機能B」も取り込めた状態と言えます。実際に、2つの機能が正常動作することも確認してみてください。

import math
import datetime
import fractions

# [機能A]@アリス担当 #############
def func_A ():
  f = fractions.Fraction
  t1 = f(2,3)
  t2 = f(4,6)
  ans = t1 + t2
  print(f'{t1} + {t2} = {ans} (= {float(ans):.2f})')  
    
# [機能B]@ボブ担当 ###############
def func_B ():
  t = datetime.datetime(2023,11,4,10,00,00) # 11/4 10:00
  diff = t - datetime.datetime.now()
  days = diff.days
  hours= diff.seconds // 3600
  print(f'高専祭まで、あと{days}日と{hours}時間')

# メイン処理 ####################
if __name__ == "__main__": 

  print("start.")

  ## 機能Aの実行
  func_A()
  
  ## 機能Bの実行
  func_B()

  print("end.")

下図のように「変更のマージ」の項目にある main.py をステージングして「コミット」してください (コミットメッセージはデフォルトのままで構いません)。その後「変更の同期」で、このマージによって更新された main ブランチを「プッシュ」します。

img

コミットグラフを確認すると次のようになっています。そして main ブランチの最新コミット (307ab0f4) には「機能A」と「機能B」の両方が実装された main.py が得られます。

img

VSCodeの「同期」とは

VSCode の git/GitHub 関連の機能では「コミットして同期」や「変更の同期」という用語でてきます。ここでの「同期 (Sync)」とは 「プル」操作をしてから「プッシュ」操作すること を意味します。

img

そのため「変更の同期」というボタンを押下することは、2段階にわけて「プル」してから「プッシュ」することと実質的に同じです。VSCodeで「プル」と「プッシュ」を単独、個別に実行したい場合は、次のように対象操作を選んでください。

img

8.8 「ボブ役」のステップ 4

VSCode で「フェッチ」します。ソース管理パネルに「変更の同期」のボタンが出現するので押下します。これにより、ボブ側でも「機能A」と「機能B」の両方が実装された main.py が得られます。


git/GitHub を利用したチーム開発では、機能の開発は main ブランチの最新のコミットを起点に feature/xxxxx というブランチを作成して行ない、それが完了したら、そこでの変更内容を main ブランチにマージするという運用方法が推奨されています。この運用方法により main ブランチには常にリリース可能な(すなわち、正常に動作する)プログラムのバージョンを維持できるというメリットが得られます。

9 宿題 (授業時間外学習)