Gitとは
Gitはプログラムのソースコードやファイルの変更履歴を管理するための分散型バージョン管理システムです。
Gitのインストール
入会届でGitHubアカウントを作成し、入会まで完了された方はこちらに進んでください。
本サークルでは、LinuxにGitをインストールする手順を説明します。WindowsやMacの場合は、公式サイトからインストーラをダウンロードしてください。
また、弊学ではWSLを開発環境として使うことが多いため、Windows側ではなくWSL側(Linux)にGitを入れることをお勧めします。
Ubuntuの場合
ターミナルを開き、以下のコマンドを実行してください。
sudo apt install git
インストール後にバージョンを確認するために、以下のコマンドを実行してください。
git --version
Gitの初期設定
Gitをインストールしたら、初期設定を行います。ターミナルを開き、以下のコマンドを実行してください。
git config --global user.name "<username>"
git config --global user.email "<email>"
<username>
と<email>
にはGitHubアカウントで登録したユーザ名とメールアドレスを入力してください。
設定した情報の確認は、以下のコマンドを実行してください。
git config --global --list
GitHub CLIの認証
レポジトリやIssueなどの操作には、GitHub CLIなどを使ってSSH認証を行う必要があります。
以下のコマンドを実行してください。
(type -p wget >/dev/null || (sudo apt update && sudo apt-get install wget -y)) \
&& sudo mkdir -p -m 755 /etc/apt/keyrings \
&& wget -qO- https://cli.github.com/packages/githubcli-archive-keyring.gpg | sudo tee /etc/apt/keyrings/githubcli-archive-keyring.gpg > /dev/null \
&& sudo chmod go+r /etc/apt/keyrings/githubcli-archive-keyring.gpg \
&& echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/githubcli-archive-keyring.gpg] https://cli.github.com/packages stable main" | sudo tee /etc/apt/sources.list.d/github-cli.list > /dev/null \
&& sudo apt update \
&& sudo apt install gh -y
詳しくはこちらを参照してください。
ソースコードを管理してみよう
リポジトリを初期化する
まず、git-intro
という作業用ディレクトリを作成します。
次に、VSCodeではデフォルトで特定のフォルダを表示しない設定がされているので、表示するように設定を変更します。 ファイル > ユーザー設定 > 設定 > Files Exclude
において、**/.git
を削除してください。
また、VSCodeの自動保存機能を有効にしておきましょう。「ファイル」から「自動保存」にチェックを入れてください。
Gitリポジトリを初期化します。git-intro
ディレクトリ内でターミナルを開き、以下のコマンドを実行してください。
git init
これで、.git
というディレクトリが作成され、このディレクトリがGitの管理対象となりました。
リポジトリとは、Gitで管理するファイルやディレクトリのことを指します。
コミットしてみよう
git-intro
ディレクトリ内にmain.cpp
というファイルを作成し、以下のコードを記述してください。
#include <bits/stdc++.h>
using namespace std;
int main() {
cout << "Hello, World" << endl;
return 0;
}
新しく作成したmain.cpp
は Untracked(未追跡) 状態であり、まだGitの管理下にないことを示しています。
これはコマンドでも確認できます。以下のコマンドを実行してください。
git status
On branch master
No commits yet
Untracked files:
(use "git add <file>..." to include in what will be committed)
main.cpp
nothing added to commit but untracked files present (use "git add" to track)
では、このmain.cpp
ファイルをGitの管理下に置いてみましょう。以下のコマンドを実行してください。
git add main.cpp
main.cpp
ファイルが Added(追加) 状態になりました。これは、Gitの管理下に置く準備ができたことを示し、これを ステージング と言います。
これはコマンドでも確認できます。以下のコマンドを実行してください。
git status
On branch master
No commits yet
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: main.cpp
Untracked files
だったファイルがChanges to be committed
に変わっていることが確認できます。
それでは、このファイルをGitの管理対象に追加しましょう。以下のコマンドを実行してください。
git commit -m "Hello, Worldを表示するプログラムを追加"
[master (root-commit) xxxxxxx] Hello, Worldを表示するプログラムを追加
1 file changed, 7 insertions(+)
create mode xxxxxx main.cpp
-m
オプションは、コミットメッセージを指定するためのオプションです。コミットメッセージは、そのコミットに対する説明を記述するために使います。
これで、main.cpp
ファイルがGitの管理下に置かれ、コミットされました。
修正をコミットしてみよう
Hello, World
をHello, Maximum
に変更してみましょう。
main.cpp
ファイルを修正し、以下のコードに変更してください。
#include <bits/stdc++.h>
using namespace std;
int main(){
- cout << "Hello, World" << endl;
+ cout << "Hello, Maximum" << endl;
return 0;
}
ファイルに変更があったため、Modified(変更済み) 状態になります。以下のコマンドを実行してください。
git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: main.cpp
no changes added to commit (use "git add" and/or "git commit -a")
修正したmain.cpp
ファイルの変更をコミットします。以下のコマンドを実行して、確認してください。
git add main.cpp
git commit -m "Hello, WorldからHello, Maximumに変更"
[master xxxxxxx] Hello, WorldからHello, Maximumに変更
1 file changed, 1 insertion(+), 1 deletion(-)
これで、main.cpp
ファイルの変更がGitの管理下に置かれ、コミットされました。
VSCodeでのGitにおけるファイルの状態には、以下のようなものがあります。
アルファベット | 状態 | 意味 |
---|---|---|
U | Untracked | gitが未追跡、新規作成 |
M | Modified | 変更済み |
A | Added | 新規追加 |
C | Conflict | 競合 |
D | Deleted | 削除 |
R | Renamed | 名前変更 |
S | Submodule | サブモジュール |
コミット履歴を確認してみよう
コミット履歴を確認するには、以下のコマンドを実行してください。
git log
commit xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (HEAD -> master)
Author: batora9 <[email protected]>
Date: Sun May 19 19:10:29 2024 +0900
Hello, WorldからHello, Maximumに変更
commit xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Author: batora9 <[email protected]>
Date: Sun May 19 19:07:17 2024 +0900
Hello, Worldを表示するプログラムを追加
これで、コミット履歴が表示されます。
Gitの基本的な流れ
Gitの基本的な流れをおさらいしましょう。
Gitはローカルでファイルの変更履歴を管理することができるツールです。
-
リポジトリを初期化する
git init
でリポジトリを初期化します。 -
ファイルを変更する
ひと通りの作業をする
-
変更をステージングする
git add <ファイル名>
でファイルの変更をステージングします。 -
ファイルをコミットする
git commit -m "<コミットメッセージ>"
でファイルをコミットします。
1~3を繰り返すことで、ファイルの変更履歴を管理することができます。
現在のリポジトリの状態を確認するには、git status
を実行し、過去の変更履歴を確認するには、git log
を実行してください。
Web研では今後の講習ではGitを使って実際に書いたコードを保存しておけるようにしていきます。
GitHubとは
GitHubは、Gitリポジトリをリモートで管理するためのサービスです。リモートで管理することで、Gitのログをクラウド上で管理することができたり、他のユーザーとの共同開発をマネジメントすることができます。
リモートリポジトリを作成してみよう
GitHubにログインし、マイページ上部の「Repository」をクリックし、緑色の「New」ボタンをクリックしてください。
Repository nameにgithub-intro
と入力し、Create Repositoryボタンをクリックしてください。(その他の設定はデフォルトのままで大丈夫です)
作成したリポジトリのURLをコピーしておいてください。
VSCodeに戻って、以下のコマンドを実行してください。
git remote add origin <リポジトリURL>.git
<リポジトリURL>
には、先ほどコピーしたリポジトリのURLを入力してください。
リモートリポジトリにプッシュしてみよう
リモートリポジトリを登録したので、ローカルでの開発内容をリモートリポジトリに送信します。
リモートリポジトリにプッシュするには、以下のコマンドを実行してください。
git branch -M main # ブランチ名をmainにする
git push -u origin main # リモートリポジトリにmainブランチをプッシュする
自分のGitHubのリポジトリにアクセスして、リモートリポジトリに送信されていることを確認してください。
GitHubでの共同開発に必要な知識
前述したように、GitHubを使うことで他のユーザーと複数人での共同開発が可能になります。さらに、Maximumなどの組織を作って、管理権限を設定したり、プロジェクトをまとめて管理することもできます。
Issue
Issueは、プロジェクトの進捗状況やバグの報告、機能の提案などを管理するための機能です。Issueを使うことで、プロジェクトの進捗状況を把握しやすくなります。
Pull Request
先ほどブランチをローカル環境でMergeしましたが、共同開発においては全て自分がMergeをする権限を持つわけではありません。 Pull Requestは、自分のブランチの変更を特定のブランチに統合するためのリクエストです。Pull Requestを使うことで、他のメンバーに変更をレビューしてもらったり、コードの品質を保つことができます。
Review
Pull Requestを送信した際に、他のメンバーに自分の書いたコードをレビューしてもらうことができます。レビューを任された人は、変更を確認してコメントを残したり、Approve(承認)やRequest changes(変更の要求)をすることができます。
Merge
リモートでもローカルと同じようにMergeを行うことができます。共同開発では、Branch Protectionという機能を使うことでPull RequestがApproveされないとMergeできないように設定することができます。(これは、レビューをする前にMergeされることを防ぐためです)
Conflict
複数のユーザーが同じファイルを変更し、それをリモートリポジトリにプッシュしようとすると(厳密には、自分がブランチを切った後かつ自分がPRを出す(マージをする)前に誰かが同じところに変更を入れたとき)、競合(Conflict)が発生します。競合が発生した場合は、競合を解消するために手動でファイルを修正する必要があります。
ブランチを作成してみよう
ブランチは、リポジトリ内での作業を分岐させるための機能です。ブランチを使うことで、複数の作業を同時に進めることができます。
ブランチを作成して切り替える
新しいブランチを作成してmain.cpp
に足し算を行うプログラムを追加してみましょう。
まず、新しいブランチを作成します。以下のコマンドを実行してください。
git branch add-func
次に、作成したブランチに切り替えます。以下のコマンドを実行してください。
git checkout add-func
同時にブランチを作成して切り替える方法
git checkout -b add-func
このコマンドを実行すると、新しいブランチが作成され同時にそのブランチに切り替わります。
add-func
という名前のブランチが作成され、そのブランチに切り替わります。
今どのブランチにいるか確認するために、以下のコマンドを実行してください。
git branch
* add-func
main
*
が付いているブランチが現在のブランチです。
main.cpp
の中身を変更します。
#include <bits/stdc++.h>
using namespace std;
int add(int a, int b) {
return a + b;
}
int main() {
cout << add(3, -2) << endl;
return 0;
}
変更をコミットしてみよう
main.cpp
の変更をステージングし、コミットします。
git add main.cpp
git commit -m "足し算を行う関数を追加"
git log
を実行して、コミット履歴を確認してみましょう。
git log
commit xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (HEAD -> add-func)
Author: batora9 <xxx.example.com>
Date: Mon May 20 00:22:47 2024 +0900
足し算の関数を追加
commit xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (origin/main, main)
Author: batora9 <xxx.example.com>
Date: Sun May 19 19:59:01 2024 +0900
Hello, WorldからHello, Maximumに変更
commit xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Author: batora9 <xxx.example.com>
Date: Sun May 19 19:58:30 2024 +0900
Hello, Worldを表示するプログラムを追加
HEAD
が付いているのが現在のブランチです。main
ではなくadd-func
になっていることが確認できます。
ブランチをマージしてみよう
add-func
ブランチでの作業が完了したので、main
ブランチにマージします。
まず、main
ブランチに切り替えます。
git checkout main
次に、add-func
ブランチをmain
ブランチにマージします。
git merge add-func
リモートリポジトリにプッシュしてみよう
main
ブランチに変更をマージしたので、リモートリポジトリにプッシュします。
git push origin main
これで、リモートリポジトリにも変更が反映されました。
共同開発をしてみよう
ちょっとした共同開発をやってみましょう。2人でペアを組んでAさん、Bさんとします。
Issueを作成(A)
Aさんは、先ほど作成したレポジトリの「Issue」にアクセスし、「New issue」ボタンをクリックします。
タイトルと説明を入力しましょう。
右のAssigneesで、Issueを担当する人を選択することができます。 今回はBさんが担当するので、Bさんを選択してください。
Collaboratorsの招待方法
BさんのGitHubのユーザーネームを入力してもでてきません。「Settings」の「Collaborators」よりBさんを追加し、招待してください。
Bさんに招待メールが送信されます。
Issueのリストに作成したIssueが表示されます。
ブランチを作成(B)
まず、BさんはAさんのリポジトリをクローンします。(もし、作業対象のリポジトリがローカルに存在する場合はこの作業は不要です)
git clone <AさんのリポジトリURL>.git
Bさんはその組織に入ったばかりで、ローカルにリポジトリがないので、リモートリポジトリをCloneしてきます。
BさんはAさんの作成したIssueにアクセスし、ブランチを作成します。
ブランチ名を入力し、「Create branch」ボタンをクリックしてください。
機能を開発する(B)
Bさんは、main.cpp
に引き算を行う関数をを追加します。
まずは、クローンしたリポジトリのディレクトリに移動しブランチを切り替えます。
git fetch origin
git checkout subtract-func
ここでのsubtract-func
は、先ほど設定したブランチ名です。
main.cpp
の中身を変更します。
#include <bits/stdc++.h>
using namespace std;
int add(int a, int b) {
return a + b;
}
int subtract(int a, int b) {
return a * b;
}
int main() {
cout << add(3, -2) << endl;
cout << subtract(3, -2) << endl;
return 0;
}
subtract関数の中身が
*
(掛け算)になっていますがそのままにしておきます。
変更がある程度または完了したら、ローカルでコミットします。
git add main.cpp
git commit -m "引き算の関数を追加"
リモートリポジトリへプッシュする(B)
すべての変更が完了したら、リモートリポジトリにPushします。
git push origin subtract-func
Pull Requestを作成(B)
リモートリポジトリにPushをしたら、Pull Requestを作成します。共同開発では直接main
へ開発した機能をマージするのではなく、基本的にはPull Requestを作成して、監督者のレビューを受けてからMergeします。 自分が開発したコードに「バグがないか」「コードが汚くないか」「セキュリティ上問題ないか」などをチェックしてもらうためです。
Pull Requestを作成するには、リポジトリのページにアクセスし、「Compare & pull request」ボタンをクリックしてください。もしくは、リポジトリのページにアクセスし、「Pull requests」タブをクリックし、「New pull request」ボタンをクリックしてください。
Bさんは機能を開発し終えたのでPull Requestを作成します。 ReviewersにAさんを設定します。
なぜ本文やタイトル、Commit Messageを分かりやすく簡潔に書くのか
レビューをする時は基本、Pull Requestの本文とコミットメッセージを見て大まかな内容や開発の流れを把握します。
みなさんも他人の書いたコードを読む時、読むのにとても時間がかかると思います。
それと同じで、レビューをする人はPull Requestの本文やコミットメッセージを読むのに時間がかかります。
このレビュワーの負担をできるだけ軽減できる工夫がPull Requestの本文やタイトル、コミットメッセージをわかりやすく簡潔に書く
ということです。
レビューをする(A)
Aさんは、Bさんが編集したコードをレビューします。
レビューは1行ずつコメントを残すことができます。コメントを残すことでコードの問題点を指摘したり、改善点を提案することができます。
また、問題のある場合にはRequest changesとして、修正を要求することもできます。
今回、引き算の関数ではなく掛け算の関数を追加してしまったため、AさんはBさんに修正を要求します。
「Review changes」からBさんへのコメントを残し、「Request changes」にチェックを入れ、「Submit review」をクリックしてください。
修正を行う(B)
BさんはAさんのコメントを受けて、修正を行います。
#include <bits/stdc++.h>
using namespace std;
int add(int a, int b) {
return a + b;
}
int subtract(int a, int b) {
return a - b;
}
int main() {
cout << add(3, -2) << endl;
cout << subtract(3, -2) << endl;
return 0;
}
修正が完了したら、再度コミットしてプッシュします。
git add main.cpp
git commit -m "引き算の関数に修正"
git push origin subtract-func
プッシュをすると、リモートに修正が反映されます。
再度レビューをお願いするためには、Reviewersのところの「Re-request review」をクリックします。
再度レビューをする(A)
Bさんが修正を行ったので、Aさんは再度レビューを行います。
変更が正しければ、「Approve」にチェックを入れ、「Submit review」をクリックしてください。
マージする(A)
Aさんがレビューを承認したので、Bさんのブランチをマージします。
マージするには、「Merge pull request」をクリックしてください。
マージが完了すると、Bさんのブランチの変更がmain
ブランチに統合され、反映されます。
マージされると、今までOpenだったPull RequestがMergedになります。 さらに、Issueからブランチを作成したため、IssueもClosedになります。
これで、ひと通りの共同開発による開発フローが完了しました。
ローカルリポジトリを更新する(A)
最後に、Aさんはリモートリポジトリの変更をローカルリポジトリに反映させます。
git pull origin main
これで、Aさんのローカルリポジトリも最新の状態になりました。
視覚的に変更を見る
VSCodeの拡張機能であるGit Graphを使うと、リポジトリの変更履歴を視覚的に確認することができます。
先ほどの共同開発の流れをGit Graphで確認してみましょう。
public-websiteでのGit Graph:
最低限覚えて欲しいこと
-
Git -> 書いたコードを途中でセーブしてやり直したりできるやつ。
-
GitHub -> Gitで管理してるコードを無料でアップロードしたり共同開発をサポートしてくれるクラウド。
-
Add -> コードに対する変更をコミットする対象に含める行為、
git add
。 -
Commit -> Addされたものをセーブする行為、
git commit
。 -
Push -> CommitされたものをGitHubなどのリモートリポジトリに反映させる行為、
git push
。
よく使うコマンドまとめ
コマンド | 説明 | 例 |
---|---|---|
git init | リポジトリを初期化する | git init |
git add <ファイル名> | ファイルをステージングする | git add index.html |
git commit -m "<コミットメッセージ>" | 変更をコミットする | git commit -m "index.htmlを追加" |
git status | リポジトリの状態を確認する | git status |
git log | コミット履歴を確認する | git log |
git remote add origin <リポジトリURL> | リモートリポジトリを追加する | |
git push -u origin <ブランチ名> | 上流ブランチとして設定する | git push -u origin main |
git push origin <ブランチ名> | リモートリポジトリにプッシュする | git push origin subtract-func |
git branch | ブランチを確認する | git branch |
git branch <ブランチ名> | ブランチを作成する | git branch add-func |
git checkout <ブランチ名> | ブランチを切り替える | git checkout main |
git checkout -b <ブランチ名> | ブランチを作成して切り替える | git checkout -b add-func |
git merge <ブランチ名> | ブランチをマージする | git merge add-func |
git clone <リポジトリURL> | リポジトリをクローンする | |
git fetch origin | リモートリポジトリの情報を取得する | |
git pull origin <ブランチ名> | リモートリポジトリからプルする | git pull origin main |
Gitのコマンドは使っていくうちに覚えていくので、まずは自分からこれまでのコードを管理してみたり、なにかアプリを作ってコードを管理してみるところから始めてみましょう。