🐧

ほぼコマンドラインのみで操作を完結させるためのGitHub開発ガイド

2025/02/24に公開

1. はじめに

この記事では、VSCodeでGitHubと連携した開発の基本的な流れについて解説します。

記載すること

  • Gitの簡易的な説明・用語
  • Gitの基本的な操作コマンド
  • GitHubの活用方法
  • 実践的な使用方法

2. Gitの特徴

Gitとは?

Gitは、バージョン管理システムと呼ばれるものです。難しそうに聞こえるかもしれませんが、簡単に言うと「ファイルの変更履歴を記録してくれる便利なツール」です。

例えば、あなたが書いた文章を編集するたびに、前のバージョンを保存しておきたいとしますよね? Gitを使えば、自動的にそれができます。しかも、単に保存するだけでなく、「誰が」「いつ」「どこを」変更したのかも記録してくれます。

Gitの概念があまり分からないよーという方は以下の動画で詳しく解説しているのでこれを見ると良いと思います!

https://youtu.be/LDOR5HfI_sQ?si=Ux12rqW4Tl_b6kJA

GitHubとは?

Githubは、Gitの仕組みを利用して、インターネット上でのスムーズな共同作業を可能にしたWebサービスです。リポジトリは「パブリック」(誰にでも閲覧できる状態)と「プライベート」(アクセスを許可した特定ユーザーのみが使用できる状態)を選ぶことができます。

GitHubのメリット

  • チーム開発が容易になる
  • コードのバージョン管理が簡単
  • イシュー管理やプロジェクト管理機能の活用

Gitの基本用語

  • リポジトリ (Repository): ファイルやフォルダ、そしてそれらの変更履歴をまとめて保存する場所です。自分のプロジェクトの「保管庫」みたいなものです。リポジトリには、自分のPCにある「ローカルリポジトリ」と、インターネット上にある「リモートリポジトリ」の2種類があります。
  • コミット (Commit): ファイルの変更をリポジトリに記録することです。「変更内容を保存」するイメージです。コミットするときには、「どんな変更をしたのか」を説明するメッセージ(コミットメッセージ)を書くことが大切です。
  • ブランチ (Branch): 開発の流れを枝分かれさせることです。例えば、新しい機能を作るときに、メインのコードを壊さないように、枝分かれしたブランチで作業します。
  • マージ (Merge): 枝分かれしたブランチを、元の流れに戻すことです。新しい機能が完成したら、メインのブランチに合流させます。
  • インデックス (Index) / ステージングエリア (Staging Area): ステージングエリアは変更をコミットする前の準備場所です。変更したファイルの中から保存したいファイルを選んでコミットすることができます。
  • ワーキングディレクトリ (Working Directory): 実際にファイルが存在する場所です。あなたが普段作業しているフォルダのことです。
  • リモートリポジトリ (Remote Repository): インターネット上にあるリポジトリのことです。GitHub、GitLab、Bitbucketなどが有名です。ローカルリポジトリと連携することで、他の人とファイルを共有したり、バックアップを取ったりできます。

3. Gitを使う前の準備

Gitのインストール

インストール:
Gitを使うには、まず自分のPCにGitをインストールする必要があります。

  • Windows: Git for Windows (https://git-scm.com/download/win)
  • macOS: Homebrew (brew install git)
  • Linux (Debian/Ubuntu): sudo apt-get install git
  • Linux (Fedora): sudo dnf install git

Gitの設定

インストールが終わったら、ターミナルを開きます。
VScodeの場合は「Terminal」>「New Terminal」で開きます。
image.png

以下の画面が出るので、コマンドを打っていきます。
image.png

PS C:\XXX\XXX\> 
  • gitの設定をするコマンド
    最初に、Gitに自分の名前とメールアドレスを教えてあげる必要があります。名前は自分だと分かれば何でもOKです。
$ git config --global user.name "自分の名前"  # 例: git config --global user.name "山田太郎"
$ git config --global user.email "自分のメールアドレス" # 例: git config --global user.email "taro.yamada@example.com"

これは、「誰が変更したのか」を記録するために必要な情報です。

  • 設定値を確認するコマンド
$ git config --list

以下のように表示されていればOKです。

user.name="自分の名前"
user.email="自分のメールアドレス"

4. Gitの基本的な操作

既にローカルに作業フォルダがある場合にはスキップしてOKです。

ローカルリポジトリの作成・削除

  • 新しいリポジトリの作成:
    Gitで管理するフォルダ(プロジェクト)を作成し、そのフォルダをGitで管理するように設定します。
    git initコマンドを実行すると、そのディレクトリにローカルリポジトリが作成されます。これでそのディレクトリ配下のファイルは全てGitでバージョン管理されることになりますが、Gitで管理したくないファイルは「.gitignore」ファイルを作成し、管理したくないファイルを指定することが可能です。
$ mkdir <project_name>  # 新しいフォルダ(プロジェクト)を作成
$ cd <project_name>    # 作成したフォルダに移動
$ git init             # このフォルダをGitで管理する

ローカルリポジトリには、このような「.git」というディレクトリが自動作成されています。

以下のコマンドを実行し、test.mdというファイルを作成します。

$ New-Item -ItemType File -Path "test.md" -Force
  • ローカルリポジトリの削除:
    もう使わないプロジェクトを削除する場合、以下のコマンドを実行してフォルダごと削除します。
$ rm -rf <project_name>  # フォルダごと削除 (注意: 復元できません)

ローカルリポジトリの状態確認

ローカルリポジトリの状態を確認することができます。

$ git status 
git statusコマンドの実行例
On branch master
No commits yet

**Untracked files:**
(中略)
      test.md # 一度もコミットしていない場合に表示される

nothing added to commit but untracked files present (use "git add" to track)

コミット

ファイルの変更をリポジトリに記録し、バージョン管理の基礎を築きます。コミットメッセージは、後で変更履歴を追跡する際に重要な情報源となります。

  • インデックスへの追加:
$ git add . # 今いるフォルダ配下の全てのファイルを「次の保存」へ準備
$ git add ディレクトリ名 # 今いるディレクトリ配下の全てのファイルを「次の保存」へ準備
$ git add ディレクトリ名/ファイル名 # 今いるディレクトリ配下の特定のファイルの「次の保存」
の準備

test.mdに以下のような文字を追加し、「git add. 」コマンドを実行します。

  • 状態の確認:
    ステージングエリアへの状態を確認することができます。
$ git status # 今、どんなファイルが変更されているか確認
git statusコマンドの実行例
  • 「git add .」などでファイルがステージングエリアに登録されている場合
On branch master
No commits yet
    
**Changes to be committed:** # test.mdがステージングエリアに登録されている
(中略)
    new file:    test.md
  • ファイルの内容が変更されているが、「git add .」コマンドが実行されておらず、ファイルが
    ステージングエリアに登録されていない場合
On branch master
No commits yet
    
**Changes to be committed:** # test.mdが変更されている
(中略)
    modified:    test.md 
  • 差分の確認:
$ git diff # ワーキングディレクトリとステージングエリアの差分を確認
$ git diff --cached # ステージングエリアとGitディレクトリとの差分を確認

ワーキングディレクトリの「test.md」ファイルに以下の変更を加えます。

  • ワーキングディレクトリの「test.md」ファイルとステージングエリアの差分を確認すると、差分
    が表示されます。
$ git diff
(中略)
@@ -1,2 +1,3 @@
 testです
    
+test1です #追加した行
\ No newline at end of file
  • ステージングエリアの「test.md」ファイルとGitディレクトリの差分を確認すると前回のコミットとの差分が表示になります。「test1です」という変更はまだステージングエリアに登録されていないため、ステージングエリアに登録された行だけが表示されています。
$ git diff --cached
(中略)
+++ b/test.md
@@ -0,0 +1,2 @@
+testです # ステージングエリアに登録された時点の内容
+
  • コミットの実行:
    変更内容をリポジトリに保存します。「-m」の後ろには、どんな変更をしたのかを説明するメッセージを書きます。
$ git commit -m "変更内容の説明" # 例: git commit -m "testです"
  • 状態の確認:
    コミットの状態を確認することができます。
$ git status # 今、どんなファイルが変更されているか確認
git statusコマンドの実行例

変更をすべてコミットすると、ステータスを確認してもファイルは表示されなくなります。

On branch master
No commits yet

**nothing to commit, working tree clean:** # コミットしていないファイルがない
(中略)
  • 差分の確認:
$ git diff # ワーキングディレクトリとステージングエリアの差分を確認
$ git diff --cached # ステージングエリアとGitディレクトリとの差分を確認
  • コミット履歴の表示:
    git logコマンドを実行すると、新しい順に「コミットハッシュ」「誰がコミットしたか」「コミットした日時」「コミットメッセージ」を確認できます。
$ git log             # これまでの保存記録を確認
コミット履歴の例
commit 709373b748b118d2a2e755ba4a292eb82f126e16 (HEAD -> master) # コミットハッシュ
Author: "<user_name>" "<e-mail>" # ユーザー名とメールアドレス
Date:   Sun Feb 16 11:44:53 2025 +0900 # コミット日時

    testです #コミットメッセージ

ローカルリポジトリでの操作を取り消す

  1. コミット前の変更取り消し
  • ステージング前(git addする前)の変更を取り消す場合
    直前にコミットした状態まで戻したくなった場合は、git checkoutコマンドでワークディレクトリの変更を取り消すことが出来ます。
$ git checkout -- <file_name> #ファイルの変更を破棄する
$ git checkout <commit_hash> <file_name> # ファイルを特定のコミットの状態に戻す
$ git checkout <branch_name> # 指定したブランチに切り替える
詳細

用途

  • git checkout -- <file_name>
    まだ git add していない変更を破棄し、現在のHEAD(最新のコミット)の状態に戻したい場合

  • git checkout <commit_hash> <file_name>
    過去のコミットの状態に戻って一時的に作業したい場合(HEADが移動)

  • git checkout <branch>:ブランチを切り替え
    特定のブランチに戻って作業を再開したい場合
    ※現在の変更内容は失われます。

  • ステージング後(git add後)の変更を取り消す場合
$ git restore --staged <file_name> # 特定のファイルをステージングから取り消し(変更は保持)
または
$ git reset HEAD <file_name> # 特定のファイルをステージングから取り消し(変更は保持)

$ git restore --staged . # 全てのファイルをステージングから取り消し(変更は保持)
または
$ git reset HEAD # 全てのファイルをステージングから取り消し(変更は保持)

2. コミット後の変更取り消し*

  • 直前のコミットを修正する場合
$ git commit --amend -m "新しいコミットメッセージ" # 直前のコミットメッセージを修正

$ git add <file_name> # 直前のコミットに変更を追加
$ git commit --amend --no-edit  # メッセージは変更せず
  • コミットを取り消す場合
    HEAD(現在のブランチが指すコミット)を特定のコミットに戻します。checkoutコマンドとは異なり、ワークディレクトリ内のファイルの変更は取り消されません。
$ git reset --soft HEAD^ # 直前のコミットを取り消し(変更はステージングに残す)
$ git reset --mixed HEAD^ # 直前のコミットを取り消し(変更は作業ディレクトリに残す)
$ git reset --hard HEAD^ # 直前のコミットを完全に取り消し(変更も削除)

$ git reset --soft <commit_hash> # HEADを指定したコミットに戻し、ステージングエリアとワーキングディレクトリはそのまま
$ git reset --mixed <commit_hash> # HEADを指定したコミットに戻し、ステージングエリアをリセットするが、ワーキングディレクトリはそのまま
$ git reset --hard <commit_hash> # HEADを指定したコミットに戻し、ステージングエリアとワーキングディレクトリをリセット
詳細

用途

  • 特定のコミットまで遡って、それ以降のコミットを取り消したい場合
  • ステージングエリア(インデックス)の内容を変更し、git add したファイルをステージングエリアから削除したい場合

モードの種類

  • --soft: HEAD のみを指定したコミットに戻します。ワーキングディレクトリとステージングエリアの内容はそのまま残ります。取り消したコミットで行った変更は、ステージングされた状態になります。

  • --mixed (デフォルト): HEAD を指定したコミットに戻し、ステージングエリアの内容もリセットします。ワーキングディレクトリの内容はそのまま残ります。取り消したコミットで行った変更は、未ステージングの状態になります。

  • --hard: HEAD を指定したコミットに戻し、ステージングエリアとワーキングディレクトリの内容もリセットします。取り消したコミットで行った変更は完全に失われます。

  • プッシュ済みの変更を安全に取り消す場合
    git revertは、指定したコミットの変更を打ち消す新しいコミットを作成するコマンドです。git resetとは異なり、履歴を書き換えるのではなく、新しいコミットとして変更を打ち消します。
$ git revert <commit_hash> # 特定のコミットを打ち消す
$ git revert HEAD # 直前のコミットを打ち消す
$ git revert <oldest_commit_hash>..<latest_commit_hash> # 複数のコミットを打ち消す
詳細

用途

  • リモートリポジトリにプッシュ済みの変更を安全に取り消したい場合
  • コミット履歴を残したまま変更を元に戻したい場合
  • 複数人で作業しているブランチで変更を取り消す場合

3. 作業途中の変更を一時的に退避させたい場合
ワーキングディレクトリとステージングエリアの変更を一時的に退避させます。これにより、クリーンな状態に戻って、別の作業を行うことができます。後で git stash pop または git stash apply で変更を復元できます。

$ git stash "作業中の変更" # 変更を一時保存(メッセージ付き)

$ git stash list # stashリストの表示

$ git stash apply stash@{0} # 特定のstashを適用
 
$ git stash drop stash@{0} # 特定のstashを削除
 
$ git stash show -p stash@{0} # stashの内容確認

Git管理下のファイルを削除

  • Git管理下のファイル・ディレクトリを削除
    Git管理下のファイルを削除します。git rmコマンドを実行すると、ワークディレクトリからファイルやディレクトリを削除し、削除した状態をステージングエリアに登録します。その後、コミットすると削除が完了します。
$ git rm <file_name> # ファイルを削除
$ git rm -r <directory_name> # ディレクトリごと削除
「test.md」ファイルを削除する例
$ git rm .\test.md
rm 'test.md'

$ git status
On branch master
Changes to be committed:
  (use "git restore --staged <file>..." to unstage)
        deleted:    test.md

$ git commit -m "test.mdを削除"
[master 1d3ce88] test.mdを削除
 1 file changed, 3 deletions(-)
 delete mode 100644 test.md

Git管理しないファイルを設定

ステージングエリアに登録するときに、毎回Gitで管理したくないファイルを意識することは大変です。そういうときに、Gitで管理したくないファイルを設定することができます。

  • Git管理しないファイルを作成
    「.git」ディレクトリと同じディレクトリに「.gitignore」というファイルを作成し、そこに無視したいファイル名やディレクトリを記載します。「.gitignore」はどこに置いても良いですが、ファイルが配置されたディレクトリ配下のパスにしか効果がありません。

  • Git管理しないファイルをステージングエリアに登録
    「.gitignore」ファイルを作成後、ステージングエリアに登録します。

$ git add .\.gitignore
  • Git管理しないファイルをコミット
$ git commit -m "「.gitignore」ファイルを追加する"
[master 709373b] 「.gitignore」ファイルを追加する
 1 file changed, 0 insertions(+), 0 deletions(-)
 create mode 100644 .gitignore

5. GitHubの基本的な操作

GitHubは、Gitのリポジトリを作成してソースコードをホスティングできるWebサービスのことです。
複数人での共同作業に便利な機能を備えていることも特徴です。

プロジェクトをフォークする

複数人でプロジェクトを進めていく場合、共同開発をしたいリポジトリをフォーク(複製)し、どーくした先で変更を加えた後に、最終的にフォーク元のオリジナルへその変更を反映させるというやり方が一般的です。

複製したいリモートリポジトリにアクセスし、「Fork」>「Create Fork」をクリックします。
https://github.com/OpenTouryoProject/SampleProgram

自分のアカウントに複製先のリポジトリが表示されていれば完了です。

リモートリポジトリのクローン

フォークしたリポジトリなどのリモートリポジトリをローカルリポジトリとして取得し、開発準備を行います。リモートリポジトリからすべてのファイルと履歴(コミット、ブランチ、タグなど)をダウンロードします。

リモートリポジトリのURLを取得します。

任意のディレクトリでgit cloneコマンドを実行します。

$ git clone git clone https://github.com/xxx/SampleProgram.git #リモートリポジトリのURL

クローンされたリポジトリのディレクトリに移動します。
例えば"https://github.com/xxx/SampleProgram.git"というURLの場合、「SampleProgram」というディレクトリが作られています。

$ cd .\SampleProgram\

リモートリポジトリの追加

ローカルリポジトリに、新しいリモートリポジトリへの参照(エイリアス)を追加することができます。git cloneとは異なり、リモートリポジトリへの接続情報を登録するだけなので、ファイルのダウンロードは行われません。
すでにローカルリポジトリが存在し、別のリモートリポジトリと連携する必要がある場合、複数のリモートリポジトリと連携する必要がある場合に使用します。

git remote add upstream
https://github.com/xxx/SampleProgram.git #リモートリポジトリのURL

ファイルのダウンロードを行う場合は、プルやフェッチコマンドを使う必要があります。

$ git pull origin master # masterブランチからプル
$ git fetch origin # リモートリポジトリ(origin)からフェッチ

リモートリポジトリの設定確認

git remoteコマンドを実行し、リポジトリの設定を確認したり変更します。

$ git remote -v

「-v」オプションをつけて実行するとクローンされたリポジトリのURLが表示されます。「origin」はクローン元のリポジトリを表しています。

$ git remote -v
origin  https://github.com/xxx/SampleProgram.git (fetch)
origin  https://github.com/xxx/SampleProgram.git (push)

ブランチの基本操作

ブランチは、Gitで記録する履歴を枝分かれさせるための機能です。同時に複数の異なる作業をしたい場合、内容ごとに別々に管理できた方が良いですよね。また、本番環境、テスト環境それぞれで異なるバージョンを動かしたいときも、ブランチを活用することでバージョンの切り替えが簡単にできます。

命名規則と作成タイミング
  • ブランチ命名規則
    以下のように、ブランチの機能ごとに名前をつけます。
  • 機能開発: feature/機能名
  • バグ修正: fix/課題名
  • リリース: release/バージョン番号
  • 緊急修正: hotfix/課題名
  • ブランチの作成タイミング
    一般的に以下のタイミングでブランチを作成します。
  • 新機能開発開始時
  • バグ修正着手時
  • リリース準備開始時
  • ブランチの作成:
    作成したいブランチの名前を指定して実行します。
$ git branch <branch_name> 

  • ブランチの切り替え:
    操作対象となるブランチを指定するにはgit checkoutコマンドを使用します。このコマンドを実行すると、指定したブランチが使われるようになります。
$ git checkout <branch_name>

  • ブランチの作成と切り替えを同時に行う:
$ git checkout -b <branch_name> 

  • ブランチの一覧表示
    使用中のブランチを確認します。
$ git branch

$ git branch -r # リモートブランチの一覧表示

& git branch -a # 全ブランチの一覧表示(リモート含む)

$ git branch -vv # ブランチの追跡状態確認

サンプルプロジェクトで「test」ブランチを作成し、切り替える例
$ git checkout -b test
Switched to a new branch 'test'

$ git branch          
  master
* test # testブランチに切り替わっている
  • 現在のブランチに別のブランチの変更を取り込む
    現在自分が作業しているブランチに、別のブランチの変更も取り込みたいときはマージします。
$ git merge <branch_name>  # 取り込む先のブランチ名

  • ブランチの削除
$ git branch -d <branch_name>   # ローカルブランチを削除 (マージ済みのブランチのみ)
$ git branch -D <branch_name>   # ローカルブランチを強制的に削除 (マージされていないブランチも削除可能)
$ git push origin --delete <baranch_name>  # リモートブランチを削除

プルリクエストの作成~承認

プルリクエストは、作成したブランチの取り込みを依頼する際に使用します。プルリクエストを作成すると、自分がプロジェクトに加えた変更を他の開発者に知らせ、変更を加えた人以外がレビューできるようになります。

  • リモートリポジトリへのプッシュ:
    プルリクエストは、リモートリポジトリの内容をもとに行うため、ローカルリポジトリからコミットを反映させる必要があります。
    「プッシュ」を行うと、リモートリポジトリにも同じ内容のブランチが作成されます。

デフォルトのGitHubのブランチの名前は「main」になります。

$ git push origin <branch_name>
サンプルプロジェクトの「test」ブランチにブランチをプッシュする例
$ New-Item -ItemType File -Path "test.md" -Force # test.mdファイルを作成する

$ git add . # ステージングエリアに登録する

$ git commit -m "初めてのプッシュです" #コミットする

$ git push origin test # testブランチにプッシュする
Enumerating objects: 4, done.
Counting objects: 100% (4/4), done.
(中略)
remote:      https://github.com/XXX/SampleProgram/pull/new/test
remote: 
To https://github.com/XXX/SampleProgram.git
 * [new branch]      test -> test
  • masterブランチへのプルリクエスト
    プッシュ完了後、サンプルリポジトリをブラウザで開きます。

プッシュしたブランチが表示されます。
「Compare & pullrequest」をクリックします。

レビュー対象のブランチ(トピックブランチ)、マージ先のブランチ(ベースブランチ)を確認します。
ここでトピックブランチがtest、マージブランチがmasterになっています。
※フォークした場合:デフォルトでは、ベースブランチのリポジトリはフォーク元のリポジトリとなっています。そのため、自分のアカウントのリモートリポジトリを選択します。

プルリクエストに必要な情報を入力し、変更内容が分かるようにします。

Reviewersにレビュアーを指定します。
※1人で作業をしている場合、レビュアーは出てきません。

「Create Pull request」をクリックします。

プルリクエスト作成後、以下のように表示されます。

プルリクエストを作成する際のベストプラクティス
  • 変更内容を明確に説明する
  • レビュワーが理解しやすいように変更を小さく保つ
  • 関連するイシューがある場合は参照を追加
  • プルリクエストの基本的なレビュー
    レビュイー側はプルリクエストをレビューします。

「Files changed」をクリックして、変更前後の内容を確認します。

「Commits」で、コミット単位で確認します。

「Conversatlon」レビュー結果をコメントできます。

  • プルリクエストの詳細なレビュー
    上記で基本的なレビュー機能を使いましたが、GitHubではファイルの内容をより詳細にレビューすることができます。

「Files changed」をクリックして、変更前後の内容を確認します。

「+」ボタンをクリックすると、変更を加えたファイルの行に対してコメントをつけることができます。

「Add single comment」をクリックすると、単なるコメントしてレビュイーに公開されます。「Start a review」をクリックすると、以下のように「Pending」と表示され、レビュイーには公開されません。

レビューを公開するには、「Finish your review」をクリックし、レビュー全体のコメントを入力後、レビューの種類を選んで「Submit review」をクリックします。

レビュイー側でレビュー内容を確認すると、以下のように表示されています。

  • レビュー対応
    レビュアーの指摘を受け、修正したら再度ブランチへプッシュします。

プッシュが完了すると、新しいコミットが表示されます。必要に応じてレビュアーにリプライしてください。

  • プルリクエストの承認
    レビュアーは承認可能だと判断したら、「Files changed」で、「Approve」をクリックして承認します。

マージ

  • レビュー後にマージする
    リモートリポジトリにあるメインブランチを更新します。

「▼」をクリックすると、マージの種類を選択できます。

マージの種類
  • Create a merge commit...トピックブランチの全コミットをそのまま保持します。具体的には、ベースブランチに「マージコミット」というコミットが新たに作成され、トピックブランチでの操作履歴が残るため、コミットの見直しやバージョン切り替えを行うことが出来ます。

  • Squash and merge...トピックブランチの全コミットを1つにまとめます。具体的には、トピックブランチで追加したコミットがベースブランチに1つのコミットととしてまとまるため、トピックブランチのコミット単位での見直しやバージョン切り替えは出来ません。しかし、ベースブランチの履歴が整理されるため、見やすくなります。

  • Rebase and merge...ベースブランチのコミット履歴を一直線にします。トピックブランチで作業している間にベースブランチに「ABC]という変更(コミット)が入った場合、通常であればコミットされる前からトピックブランチが枝分かれしますが、リベース機能を使うと、「ABC」というコミットからトピックブランチが作成されたかのように操作履歴が表示されます。
    トピックブランチが複数ある場合に、通常のコミットだと複数のベースブランチのコミット時点からトピックブランチが分岐されることになり、複雑になりますが、リベースするとコミット履歴が一直線になります。

:::

マージコミットのコメントは必要に応じて記入しますが、そのままで問題ありません。
「Commit」をクリックします。

プルリクエストがマージされました。

  • ベースブランチのコミット履歴を確認
    マージ後に変更されたベースブランチを確認します。

ベースブランチの「Code」に表示されている「This branch is 3 commits ahead Of OpenTouryoProject/Samp1eProgram:master」をクリックします。

プッシュ~マージコミットまでの履歴を確認することができます。

ローカルリポジトリにマージを反映

プルリクエストがマージされた状態では、リモートリポジトリ側のみマージが反映されています。
そのため、ローカルリポジトリにもマージを反映させる必要があります。

  • 「プル」と「フェッチ」
    「プル」または「フェッチ」という操作で、リモートリポジトリの内容をローカルリポジトリに取り込みます。プルの場合は、ワークディレクトリの内容もそ即座に変更され、フェッチの場合はローカルリポジトリに取得するのみになります。ワークディレクトリに反映させるには、再度プルorマージを行う必要があります。
$ git pull origin master # masterブランチからプル
$ git fetch origin # リモートリポジトリ(origin)からフェッチ

先ほどのtest.mdのマージをローカルリポジトリに反映します。
まずはmasterブランチへ切り替えます。

$ git checkout master
Switched to branch 'master' # masterブランチに切り替わる
Your branch is behind 'origin/master' by 3 commits, and can be fast-forwarded.

git pullコマンドを実行します。

$ git pull origin master
From https://github.com/XXX/SampleProgram
 * branch            master     -> FETCH_HEAD
Updating 9b53109..b5d37c2
Fast-forward
 test.md | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 test.md
ローカルリポジトリにないブランチを取得する方法

プルを実行するには、マージ先のブランチが必要ですが、そのブランチがリモートリポジトリにしかない場合、ローカルリポジトリにも作る必要があります。
以下のコマンドを実行すると、リモートリポジトリのブランチをローカルリポジトリにも自動で作成してくれます。

$ git fetch origin
$ git checkout update # updateブランチをローカルリポジトリに作成する

6. コンフリクト

  • コンフリクトとは
    コンフリクト(競合)は、同じファイルの同じ箇所が異なるブランチで異なる編集が行われた場合に発生します。Gitはこのような状況で自動的にマージすることができず、手動での解決が必要になります。

発生条件

  • 同一ファイルの編集

    • 複数のブランチで同じファイルを編集
    • 特に同じ行や近接する行の変更
  • タイミング

    • ブランチのマージ時
    • プル(pull)実行時
    • リベース(rebase)実行時

コンフリクトの解決手順

  1. コンフリクトの検出
    マージした際にコンフリクトが検出されます。
$ git merge feature-branch 
Auto-merging sample.txt
CONFLICT (content): Merge conflict in sample.txt # コンフリクトが発生
Automatic merge failed; fix conflicts and then commit the result.
  1. コンフリクトファイルの確認
    ステータスを確認すると、マージ先とマージ元両方で変更が加えられたファイル「sample.txt」がコンフリクトしていることが分かります。
$ git status
Unmerged paths:
  (use "git add <file>..." to mark resolution)
        both modified:   sample.txt # マージ先とマージ元両方で変更が加えられたファイル
  1. コンフリクト箇所の確認
    コンフリクト箇所を確認すると、以下のようにコンフリクトマーカーが表示されているため、現在のブランチの内容を適切に修正します。
<<<<<<< HEAD
現在のブランチの内容
=======
マージしようとしているブランチの内容
>>>>>>> feature-branch
  • コンフリクトマーカーの構造
  1. <<<<<<< HEAD
    • コンフリクト部分の開始を示す
    • HEADは現在のブランチの内容を表す
  2. =======
    • 現在のブランチの内容とマージしようとしているブランチの内容の区切り
    • 上部がHEAD(現在のブランチ)の内容
    • 下部がマージしようとしているブランチの内容
  3. >>>>>>> feature-branch
    • コンフリクト部分の終了を示す
    • feature-branchはマージしようとしているブランチ名
具体例
  • コンフリクトマーカーの内容を確認
# 元のファイル(main branch)
function getUserName() {
    return "John Doe";
}

# 開発ブランチでの変更
function getUserName() {
    return "Jane Smith";
}

# コンフリクト発生時のファイル
function getUserName() {
<<<<<<< HEAD
    return "John Doe";
=======
    return "Jane Smith";
>>>>>>> feature-branch
}
  • 解決方法
  1. 片方を採用
function getUserName() {
    return "John Doe";  // HEADの内容を採用
}
  1. 両方を組み合わせ
function getUserName() {
    return "John Doe and Jane Smith";  // 両方の内容を統合
}
  1. 完全に新しい実装
function getUserName() {
    return getUserPreference() || "John Doe";  // 新しい実装
}
  1. 解決した変更をステージング
$ git add sample.txt
  1. コミット
$ git commit -m "sample.txtのコンフリクト解決"
  1. リモートリポジトリにプッシュ
$ git push origin feature-branch
  1. プルリクエストを確認
    Githubでプルリクエストを確認し、自動的にマージができることを確認します。マージできればレビュー、ベースブランチへマージします。

7. GitHubのフローについて理解する

GitHubのフローでは、作業ごとにトピックブランチを1つ作り、マージやレビューなどのサイクルを回してきます。

作業ごとにブランチを使い分ける理由

作業の影響範囲を限定できる

例えば、2つの機能を実装する場合に、片方のA機能は完成しており、もう一方のB機能はまだ開発中でリリースが遅れそうなケースがあり、A機能のリリースのみ先行で行うことが決定されています。
しかし、A機能とB機能を1つの作業ブランチで行っていた場合、A機能のみを抽出してリリースすることは大変ではないでしょうか。
2つの機能それぞれを違う作業ブランチで開発していれば、機能ごとにリリースを行ったり、バグが発生した際にも速やかに修正対応を行うことができます。

一般的なブランチ戦略のベストプラクティス

ベストプラクティスの運用を行うことで、以下のメリットがあります。

  • 並行開発が容易になる
  • リリース管理が簡単になる
  • バグ修正の影響範囲を限定できる
  • コードの品質を維持できる
  1. ブランチの種類と用途
  • main/master: 本番環境用の安定したコード
  • develop: 開発用のブランチ
  • feature/*: 新機能開発用のブランチ
  • hotfix/*: 緊急のバグ修正用のブランチ
  1. ブランチ運用のルール
  • 機能単位で個別のブランチを作成
  • 長期間のブランチ維持を避ける
  • 定期的にベースブランチの変更を取り込む
  • 不要になったブランチは速やかに削除
  1. 開発フロー時の注意点
  • 小さな単位での変更を心がける
  • 頻繁にコミットとプッシュを行う
  • コミットメッセージは明確に記述
  • コードレビューを必ず実施

まとめ

最後に、バージョン管理とチーム開発の本質は「変更の追跡」と「協働」です。GitとGitHubはそのための強力なツールであり、適切に活用することでソフトウェア開発の品質と効率を大きく向上させることができます。この記事が皆さんの開発フローの改善につながれば幸いです。

ぜひ実際に手を動かして試してみて、自分なりのGit/GitHub活用法を見つけてください。
Happy coding!

Discussion