Gitの補足知識・演習

Gitの仕組みや管理上のファイル

Gitの管理対象(.gitフォルダ、.gitignoreファイル)

“sample”というプロジェクトを作成した場合、sampleフォルダ配下の中身すべてを管理対象とします。(マニュアルの序盤であれば「java-○○」)
初回コミットの折に、管理対象フォルダの下でgit initを行うと、gitで管理できる初歩の状態となります。このとき、プロジェクト直下には「.git」フォルダが生成されます。
この「.git」フォルダは、Gitによるバージョン管理の心臓とも言えるもので、Gitがプロジェクトの変更を追跡・管理するために不可欠な情報(プロジェクトのすべてのバージョン履歴、設定、メタデータなど)を格納するフォルダです。

※.gitなどの隠しフォルダは、ファイルエクスプローラーの隠しフォルダを見せる設定にしないと表示されません。

sample/
├── src/
│     └── com/
│            └── cmps/
├── .git/  ←←←ここ!
└── .gitignore

指定したファイル・ディレクトリを管理対象から外す方法

もし管理対象に含めるべきでない(管理する必要がない)フォルダやファイルがある場合、Gitによる管理から除外することもできます。
方法は、プロジェクト直下に「.gitignore」ファイルを作成し、このファイル内にファイル名やフォルダ名を記述します。
(※「.gitignore」自体は管理対象から外さないようにします。)
gitignoreの書き方チートシート【テンプレあり】

READMEファイル ~プロジェクト説明~

READMEはプロジェクトを説明するためのファイルです。一般にGitHub設定時に追加するものです。ファイルの形式はMarkdownで、拡張子は.mdです。
READMEファイルはGitHubから追加することもできますが、自分でREADME.mdという名前のファイルを追加することもできます。プロジェクトの直下に配置します。
記載内容はGitHub上のリモートリポジトリのトップ画面にて表示されます。
参考サイト:【GitHub】READMEって使ってる?使い方と書き方を確認しよう

sample/
├── src/
│     └── com/
│            └── cmps/
├── .git/
├── .gitignore
└── README.md ←←←ここ!

ワークツリーとインデックス ~コミットまでの流れ~

作業者がローカルで作業しているディレクトリのことをワークツリーと言います。
ワークツリーと、保存場所であるローカルリポジトリの間には、インデックスと言う中間領域が設けられています。コミット前に準備をするための場所です。

Gitのローカルリポジトリに登録するまでの仕様は、以下の通り。「addした後にcommit」という順序で行うのは、このような仕組みによります。
add   :ワークツリー → インデックス へ仮置き
commit :インデックス → ローカルリポジトリ
addをすることで、ローカルリポジトリに状態を記録する対象ファイルを絞ることもできますし、ミスの防止にも繋がります。

origin ~リモートリポジトリのデフォルト名称~

originとは、Gitにおけるリモートリポジトリのデフォルトの名称(エイリアス)です。

・学習単元の「Git」で、初回コミットの際に使用する「git remote add origin ~」コマンドでも、このデフォルト名originと名付けています。
originの部分は他の任意の名前に変えることもできますが、慣習的にoriginと名付けることが一般的です。
git remote -vという、リモートリポジトリとの接続を確認するコマンドを実行すると、エイリアスであるoriginが表示されるのが確認できます。

git push origin master(またはpull)のコマンドでも、送信先のリモートリポジトリを指定するのにoriginという名前を使っています。
改めて書くと git push [送信先のリモートリポジトリ] [対象のブランチ] というコマンドなのです。

git cloneコマンドでリポジトリをコピーした場合、Gitは自動的に元のリポジトリをoriginという名前で登録します。

その他、コマンドを調べた際に「origin」が出てきた場合は、「リモートリポジトリそ指定しているんだな」と考えて良いです。

主な機能、操作の概要

ブランチ、マージ ~分岐と統合~

ブランチ

ブランチは、開発の本流から分岐し、本流の開発を邪魔することなく作業を続ける機能のことです。別の世界線を作るようなイメージです。
幹から枝が伸びていくように、おおもとになるmaster(main)のブランチから、一時的に別の開発ライン(ブランチ)を作成して作業を進めることができます。
ブランチを使い分ける理由としては
・メインのコード(masterブランチ)を壊さずに、新しい機能開発やバグ修正、実験的な変更を安全に行える
・もし開発途中で問題が発生しても、そのブランチだけを削除することができる
・複数の開発者がそれぞれ別のブランチを作成して同時に作業を進めることができるので、チーム開発の効率が向上する
・ブランチごとに変更履歴が記録されるので、どの変更がどの機能や修正に対応するものなのかを追跡しやすくなる
等が挙げられます。
本流のブランチ名は”master”か”main”が多く、どちらも同じ意味ですがコンパスでは”master”を使用しています。
【Git入門】ブランチ(branch)とは?メリットや使い方を解説!

ブランチを切り替えた時、現在の作業コンテキスト=「今どこにいるか」を示すポイントHEADと言います。
基本的には、現在使用しているブランチの先頭(最新のコミット)を指します。
Gitの学習中や使用中によく出てくることのあるワードですので、覚えておくと良いでしょう。

ブランチモデル

こちらの画像は、2010年オランダのエンジニアVincent Driessen氏が提案したgitのブランチモデル”A successful Git branching model” で、世界中に広く浸透しgit運用モデルとして参考にされています。
ブランチのイメージを掴む参考にしてください。
[日本語訳]A successful Git branching model

各名所の説明を下記に記載いたします。

masterプロダクトとしてリリースするためのブランチ(完成形)。リリースしたらタグ付けする。
develop開発用ブランチ。コードが安定し、リリース準備ができたら master へマージする。リリース前はこのブランチが最新バージョンとなる。
feature branches機能の追加。 develop から分岐し、 develop にマージする。
hotfixesリリース後のクリティカルなバグフィックスなど、 現在のプロダクトのバージョンに対する変更用。 master から分岐し、 master にマージし、タグをつける。次に develop にマージする。
release branchesプロダクトリリースの準備。 機能の追加やマイナーなバグフィックスとは独立させることで、リリース時に含めるコードを綺麗な状態に保つ(機能追加中で未使用のコードなどを含まないようにする)ことができる。develop ブランチにリリース予定の機能やバグフィックスがほぼ反映した状態で develop から分岐する。リリース準備が整ったら, master にマージし、タグをつける。次に develop にマージする。

マージ

マージとは、分けたブランチ(開発の分岐点)での作業が完了したとき、ブランチの変更内容を他のブランチに統合する操作のことを言います。
一般にチーム開発ではそれぞれ別のブランチで作業をして、後から本流にマージ(統合)します。

なお、ブランチは一人で作業する時も活用できます。
”master”から切り離して”develop”というブランチを作成してそこで作業するとします。”develop”で内容をいくら変更しても、”develop”を”master”にマージするまでは”master”に影響を与えることはありません。別バージョンのコーディングを試して(例えばjQueryのプラグインを入れてみるなど)、うまく行けばマージすればよく、仮に失敗してもブランチを”master”に切り替えればもとの状態に戻すことができます。

プル、フェッチ、リベース

プッシュとは対照的に、リモートリポジトリの更新内容や履歴をローカルに取得し適用するのがプルです。
複数人で作業をする場合は、他の人がリモートリポジトリに登録した変更を取り込む必要があるので、この操作は必須になります。

ただし「プル」と一口に言っても、実際には「フェッチ」「マージ」(またはrebase)の同時実行がプルなのです。
フェッチ(Fetch):リモートリポジトリの最新の変更履歴をローカルリポジトリに取得してくる(適用はしない)。リモートの状況を確認する際に便利。次に説明する「コンフリクト」を回避したいケースでも役立ちます

併せて、リベース(Rebase)についても説明すると、変更内容をすべて派生元ブランチに取り込める操作です。
マージでは、コミット当時の時系列にしたがって変更履歴が記録され、変更履歴が入り混じってしまうのに対し、リベースでは、新たに追記する形で変更履歴が記録されます。変更履歴の見やすさを保ってマージしたい場合に有用です。

コンフリクト(衝突、競合)

コンフリクト(Conflict)は、複数の人が同じファイルの同じ行を編集した場合などに、変更内容が衝突(競合)してしまい、自動でマージが進行できない状態です。Git側がどちらの変更を取り込むかを自動で判断できないため発生するもので、ユーザー側で解決する必要があります。
マージやリベース、リモートリポジトリからのプル等の際に発生することがあります。開発チームの一メンバーの立場としては、プルをする際に起こる可能性が最も高いでしょう。
とはいえ、コンフリクトが発生するということは、Gitの重要な機能である「共同開発」が正常に機能している状態でもあります。

プルリクエスト ~コードレビュー依頼~

プルリクエストとは、本流以外のブランチで修正や追加した内容を「本流へマージをしてください」と他の開発者にコードレビューを依頼するGitHubの機能です。もちろん自分でマージすることもできるのですが、プルリクエストを行うと他の開発者に変更内容やコードの差分が通知されます。マージの前にレビュー者(マージ担当者)による確認作業を挟むため、バグが起こりづらくなります
実際に複数人で一つのプロジェクトを作成する時は、本流以外のブランチで作業することになります。その際に「プルリクエストしてください」と言われたら本流へのマージを依頼することだと覚えておいてください。

ファイルダウンロード方法、クローン

GitHubからファイルをダウンロードする方法は「手動」か「Gitクローン」の2通りあります。

手動(zip)

  1. GitHubで対象のリポジトリを開いたら右上の「Code▼」をクリック
  2. 「Download ZIP」からダウンロード
  3. zipを解凍し、手動で配置する

Gitクローン

  1. GitHubで対象のリポジトリを開いたら右上の「Code▼」をクリック
  2. 「Clone」項目のhttps:~で始まるアドレスをコピー
  3. ファイルエクスプローラーの配置したいディレクトリで右クリック →「Git Bash Here」を選択
  4. Git Bashが立ち上がったら git clone [コピーしたアドレス] を入力してEnter ※[]は不要

クローン(clone)とは、リモートリポジトリ全体をローカル環境に複製(コピー)すること、またはそのコマンドを指します。
その時の最新版のデータと変更履歴などをまとめて取得できるので、クローンしたタイミングのリモートリポジトリと全く同じ環境をローカルに作成します。
例えばチームで開発する場合、リモートリポジトリを最初に作成した人以外は、この機能を利用して同じ環境を自分のローカルに準備することができます。

Git演習

ここまで学習した内容について、実際に操作しながら確認していきましょう。(CUI操作で行います)

練習に使用するローカルのディレクトリリモートリポジトリを用意し、GitHubに初回コミットプッシュするところまで実施しましょう。(「Git」単元参照)
マニュアルでは以下の仕様で作成し、進行します。
・ディレクトリ名、リモートリポジトリ名:「gitPractice」
・ディレクトリパス:デスクトップ直下

ブランチの操作

主なブランチ操作コマンドは以下

コマンド説明
git branchローカルブランチの一覧を表示します。
現在のブランチには *印付きで強調して表示されます
git branch --remote
git branch -r
リモートブランチの一覧を表示します
git branch [作成するブランチ名]新しいブランチを作成します
git checkout [移動先ブランチ名]ブランチを切り替えます。HEAD(現在地)の移動

その他ブランチ名の変更、ブランチの削除(ローカル/リモート)等のコマンド等もありますが割愛します。

ブランチ操作の基本コマンド実践

下記の画像に習って実践してみましょう。

順に説明すると
①ブランチ一覧を表示。初期状態のためmasterのみ
②「develop」ブランチを作成
③ブランチ一覧を表示。
 作成したdevelopブランチが表示されていること、現在はmasterブランチにいることが分かります。
④developブランチに切り替え
⑤の箇所で、青字で (develop) と表示されているのは現在いるブランチを示しています。
 移動できていることが確認できました。

GitHub上でのブランチの確認

ローカルブランチの作成ができましたが、現時点ではGitHub(リモート)上にはdevelopブランチは存在しません。
developブランチのコミットをプッシュすることで、リモートブランチにも反映されます。

コミット履歴を作成してリモートにプッシュし、GitHub上でどのように確認できるか見てみましょう。
まず、ファイルを作成します。
・「gitPractice」フォルダ直下に下記の内容で「abc.txt」ファイルを作成します。(フォルダで右クリック>テキストドキュメント を選択)
・ファイルには「Gitの学習を始めます。」と記載しておきます。

ファイルが作成出来たらプッシュしていきます。

・「ls」はGit Bashで使用できるコマンドで、実行したディレクトリ配下にあるフォルダやファイルの一覧を表示します。
現在含まれている「abc.txt」ファイルが表示されています。
・git add ~git pushまでを、コミット名”2nd commit”で実行しています。(ローカルのdevelopブランチから、リモートのdevelopブランチへプッシュ
今回はdevelopブランチとしては初回のプッシュのため、リモートにdevelopブランチを作成した、といったメッセージも表示されています。

プッシュ後、リモートリポジトリのWebページを更新すると、下図のプルダウンからブランチを選択して表示できるようになっています。
developブランチを開くと、developブランチにプッシュしたコミットが登録されていることを確認できます。

マージ、プルリクエストの活用、プル

主なマージ等のコマンドは以下

コマンド説明
git merge [取込み対象ブランチ名]他のブランチの変更を取り込みます。
masterにdevelopを取り込む場合、masterブランチで「git merge develop」を実行
git merge --abortマージを取り消します(コンフリクトが発生して戻したいとき等)
git diffワークツリーとステージングの差分を確認します。
git addする前に使用する
git diff [A] [B]リモートとの差分を確認します。
pullをする前なら「git diff ブランチ名..リモート名/ブランチ名
pushをする前なら「git diff リモート名/ブランチ名..ブランチ名
git fetch origin [ブランチ名]リモートブランチとの差分を確認します。
git fetch」のみだとorigin/masterに対して実行

マージの実践

下記の画像に習って実践してみましょう。

・masterブランチにチェックアウトします。masterブランチでlsを行うと、ファイルが存在しないことが分かります。
・マージを行い、問題なく実行できたのが上記の例です。マージの後にlsを行うと、developで作成したファイルが確認できます。
なお、ローカルのdevelop→masterにマージしただけの段階では、リモートのmasterには反映されていません。
・ローカルのmasterからリモートのmasterにプッシュを行うことで、リモートにも反映されweb上で確認できます。
特にdevelopでのコミット履歴がそのままmasterのコミット履歴に追加されていることが確認できます。

プルリクエストの作成、マージの実行

今度はプルリクエストを作成してみましょう。

developブランチに切り替え、「abc.txt」に以下のように追記した後、プッシュしてください。


プッシュ後、GitHubを開くと、画面上部にプルリクエストを促す通知が表示されています。このボタンをクリックするか、

または、画面上部のPull Requestsタブからも同様にボタンがあり、こちらからも進めることが出来ます。

ボタンクリック後のプルリクエスト画面では、マージ元とマージ先ブランチ、タイトルやメッセージを編集し送信することが出来ます。


プルリクエストに対するマージの承認も、GitHub上で実行できます。右の画像はマージ完了後の表示
・実際にはすぐマージ承認するケースよりも、修正指示→修正→再度確認…→問題なければマージ といった段階を踏むことも多いでしょう。
・マージが不要な場合は、プルリクエストを棄却する機能もあります。

プルリクエストの概要は以上です。
参考サイト:
pull request の作成 – GitHub Docs
プルリクエストの一連の流れについて #Git

プル実行(リモートからフェッチ、マージ)

さて、プルリクエストを行ったことで、リモートブランチのdevelopからリモートのmasterには取り込まれました。
反対に言うと、ローカルのdevelopとmasterの内容は一致していません。
ローカルのmasterブランチにリモートのmasterブランチの内容を取り込んでみましょう。

・「git fetch」のみで実行したとき、origin/masterの内容を取得します。
取得できるものが何もないと何も表示されませんが、取得できた場合は上記のようにメッセージが表示されます。
・git diff でmaster と origin/masterを比較すると差分が確認できます。diffについても、差分がない場合には何も表示されません。
・masterブランチに切り替え、マージコマンドで ローカルのmasterブランチに対してorigin/masterをマージしています。

もちろん、フェッチ、マージを使わずにプルでも同様に実行できます。

コンフリクトの解消

コンフリクトを起こす準備

コンフリクトを意図的に起こして、コンフリクトの解消を実践してみましょう。
今回はマージによる衝突を起こしてみます。

masterブランチにチェックアウトし、「developA」と「developB」ブランチを作成してください。

「abc.txt」の「プルリクエスト~」の行の後ろに
「developA」ブランチでは「Apple」、「developB」ブランチでは「Banana」と追記してそれぞれのローカルリポジトリにコミットします。

マージによるコンフリクト、およびその解消

まず、masterブランチにdevelopAをマージします。ここではエラーは起きません。
続いて、masterブランチにdevelopBをマージすると、ここでコンフリクトが起きます。

developBのマージではコンフリクトが起きた旨(CONFLICT~)が記載されています。
この時点で、コンフリクトを解消するためにGitがファイルに直接差分の書き込みを行ってくれています
ちなみに対象のファイルが分からない場合は、「git status」で確認できます。

今回だと、===== を境に、上がHEAD(現在のmaster)、下がdevelopBの内容です。

このファイルを直接編集し、残したい正しい形にします。
どちらかの変更を残すか、または両方の変更を組み合わせて、最終的な内容に決定します。

今回はこういった形で一部分ずつ残しました。
編集が完了したら、改めてこのままmasterブランチをアド、コミットします。コミットメッセージにはdevelopBからマージした旨を残すと適切でしょう。

以上でコンフリクトの解消は完了です。

このページで紹介・実践したものも、Gitの操作の中では基本的なものです。
他にも、ログ(コミット履歴)を確認したり、コミット名を変更したり、コミットを打ち消すコマンドなどもあります。ぜひ調べて実践してみましょう。

参考サイト:
初心者のためのやさしいGit
ブランチとは|サル先生のGit入門【プロジェクト管理ツールBacklog】

Git基本コマンド – Laravel学習帳
Git の基本コマンドまとめ

複雑なGitマージ作業の進め方|Kinsta
git tag と GitHub の Release 機能でプロっぽさを出してみよう

タイトルとURLをコピーしました