Git基礎学習
自分の理解のため、普段使っているgitについてまとめました。
1. gitを使い始める準備
1.1. インストール
代表的な方法を記載する。
いくつかインストール方法があるので git 公式のダウンロードページを参照
-
Windows
Git for Windows
のインストーラーをダウンロードして実行 -
Mac
gitインストール(Mac)brew install git
-
Linux (Ubuntu)
gitインストール(Linux)apt-get install git
筆者環境は macOS Ventura, git v2.39.2
sw_vers
ProductName: macOS
ProductVersion: 13.3.1
BuildVersion: 22E261
git --version
git version 2.39.2
1.2. config
1.2.1. グローバル設定
# 誰がコミットしたか、git log などに載る
git config --global user.name "<ユーザー名>"
git config --global user.email "<メールアドレス>"
# グローバル設定には、PCやよく使うIDE等、リポジトリに依存しない共通の除外設定を入れる
# ignore ファイルの内容は、以下の設定など参考
# https://github.com/github/gitignore/blob/main/Global/macOS.gitignore
touch ~/.gitignore_global
# よく使うコマンドは短いエイリアスを付けておくと便利 git <エイリアス名> で実行可能
git config --global alias.st status
git config --global alias.co checkout
git config --global alias.br branch
# コミット履歴フォーマット指定
git config --global alias.logp "log --pretty=format:'%h 🕒%cd 🙋%an %s' --date=format:'%Y-%m-%d %H:%M'"
# コミット履歴をグラフ表示
git config --global alias.graph "log --oneline --decorate --graph --branches --tags --remotes --all"
1.2.2. ローカル(リポジトリ毎の)設定
# 誰がコミットしたか、git log などに載る
git config --local user.name "<ユーザー名>"
git config --local user.email "<メールアドレス>"
# ローカル設定には、プログラミング言語やランタイム、対象の開発で使うIDE等の除外設定を入れる
# ignore ファイルの内容は、以下の設定など参考
# https://github.com/github/gitignore/blob/main/Android.gitignore
# https://github.com/github/gitignore/blob/main/Java.gitignore
touch .gitignore
1.3. リポジトリ用意
1.3.1. リモートリポジトリから作る場合
GitHub / GitLab / Bitbucket などのホスティングサービスでリポジトリを作り、それを利用する場合
git clone <リモートリポジトリURL>
git branch -M main
# --allow-empty は空コミットを作る場合のみ必要
# 初期コミットで README.md など何かファイルを作る場合は不要
git commit -m "initial commit" [--allow-empty]
git push
すでにコミットが入っている状態のリポジトリからクローンするのみの場合は以下
git clone [-b <ブランチ名>] <リモートリポジトリURL> <クローン先ローカルディレクトリ>
1.3.2. 既存のローカルリポジトリをリモートにアップロードする場合
予めローカルで作成したリポジトリを GitHub / GitLab / Bitbucket などのホスティングサービスで作った直後のリポジトリと連携する場合
mkdir <プロジェクト名>
cd <プロジェクト名>
git init -b main
# --allow-empty は空コミットを作る場合のみ必要
# 初期コミットで README.md など何かファイルを作る場合は不要
git commit -m "initial commit" [--allow-empty]
# (GitHub httpsの例) git remote add origin https://github.com/{ユーザーID}/{リポジトリ名}.git
# (GitHub sshの例) git remote add origin git@github.com:{ユーザーID}/{リポジトリ名}.git
git remote add origin <リモートリポジトリURL>
git push -u origin main
2. 編集ワークフロー
2.1. コミット状態遷移
コミット状態遷移
コミット・ブランチ図示凡例
2.1.1. コミットフロー
git add <ファイル名/ディレクトリ名>...
# -m を付けない場合はエディターが起動してメッセージを入力する
git commit -m "<メッセージ>"
git push [リモート名: e.g. origin] [<ブランチ名>]
2.1.2. 共有コミットからの同期フロー
git fetch [リモート名: e.g. origin] [<ブランチ名>]
リモートリポジトリからコミット、ファイル、ブランチ等のコミット参照オブジェクトなどをダウンロードする。
ただし、情報を反映するのはローカルリポジトリのリモートブランチまでで、ローカルブランチへは反映しない。
ローカルブランチまで反映したい場合は、リモートブランチからローカルブランチにマージする。
# カレントブランチを切り替えたのちマージ
git switch <ブランチ名>
git merge origin/<ブランチ名>
git switch <ブランチ名>
git pull [リモート名: e.g. origin]
2.1.3. Working Directory の変更差分を一時的に退避する
pull などでリモートリポジトリの内容をローカルに取り込む際、途中まで変更していた差分があると pull が上手くいかないことがある。
そんな場合に、変更差分を一時退避して Working Directory の差分がない状態にできる。
git stash [push [-u]] [<メッセージ>]
Saved working directory and index state WIP on <ブランチ名>: 533daa3 <コミットメッセージ>
一時退避した差分はストックできる。
現在、どんな stash があるか一覧表示で確認可能。
git stash list
stash@{0}: WIP on <ブランチ名>: 533daa3 <コミットメッセージ>
stash@{1}: WIP on <ブランチ名>: 533daa3 <コミットメッセージ>
各 stash の内容を見たい場合は以下で可能。
git stash show stash@{0} -p
diff --git a/sample.txt b/sample.txt
index 422c2b7..de98044 100644
--- a/sample.txt
+++ b/sample.txt
@@ -1,2 +1,3 @@
a
b
+c
一時退避していた差分を適用し直すことができる。
git stash apply [stash@{n}]
git stash pop [stash@{n}]
不要になった stash は削除する。
git stash drop [stash@{n}]
2.1.4. 復元フロー
git restore --staged <ファイル名>...
git restore --worktree <ファイル名>...
git reset --soft HEAD~<取り消すコミット数>
git reset --mixed HEAD~<取り消すコミット数>
git reset --hard HEAD~<取り消すコミット数>
2.2. コミット状態の確認方法
2.2.1. Working Directory と Index の確認
git status
On branch main
Your branch is up to date with 'origin/main'.
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
new file: sample_01.txt
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: sample_01.txt
Untracked files:
(use "git add <file>..." to include in what will be committed)
sample_02.txt
-
Changes to be committed
- Index の内容
-
Changes not staged for commit
- Working Directory の変更 (git 管理済ファイル)
-
Untracked files
- Working Directory の変更 (git 未管理ファイル)
2.2.2. コミット履歴の確認
# 最新何件かのみで良い場合は -n オプション
git log
commit 7cdaa2a180ded54dc0281a7d914f10f1e3a7e999 (HEAD -> main)
Author: {ユーザー名} <{メールアドレス}>
Date: Mon May 1 15:46:56 2023 +0900
{コミットメッセージ}
commit 5bafb2479fa185c731f32d4180383c29da6ab2e8 (origin/main)
Author: {ユーザー名} <{メールアドレス}>
Date: Mon May 1 15:46:56 2023 +0900
{コミットメッセージ}
git log --oneline
7cdaa2a (HEAD -> main, origin/main) {コミットメッセージ}
5bafb24 {コミットメッセージ}
git log --pretty=short
commit 7cdaa2a180ded54dc0281a7d914f10f1e3a7e999 (HEAD -> main, origin/main)
Author: {ユーザー名} <{メールアドレス}>
{コミットメッセージ}
git log --pretty=format:'%h 🕒%cd 🙋%an %s' --date=format:'%Y-%m-%d %H:%M'
<コミットIDハッシュ> 🕒<コミット日時> 🙋<author名> <コミットメッセージ>
140866c 🕒2023-05-03 00:28 🙋<author名> <コミットメッセージ>
c32e3ca 🕒2023-05-02 20:45 🙋<author名> <コミットメッセージ>
git log --decorate --graph --all --oneline
* a04497e (HEAD -> feature/test01) change sample_02
| * bb7624d (refs/stash) WIP on feature/test01: 533daa3 change sample_02
| |\
| | * b7052bf index on feature/test01: 533daa3 change sample_02
| |/
| * 533daa3 change sample_02
|/
* 0ce5883 (origin/main, origin/feature/test01, main) change sample_01
* 7cdaa2a add sample files 01-02
* 5bafb24 🎉 initial commit
2.2.3. ローカル差分の確認
git diff
diff --git a/sample_01.txt b/sample_01.txt
index 422c2b7..de98044 100644
--- a/sample_01.txt
+++ b/sample_01.txt
@@ -1,2 +1,3 @@
a
b
+c
diff --git a/sample_02.txt b/sample_02.txt
index 7898192..422c2b7 100644
--- a/sample_02.txt
+++ b/sample_02.txt
@@ -1 +1,2 @@
a
+b
git diff sample_02.txt
diff --git a/sample_02.txt b/sample_02.txt
index 7898192..422c2b7 100644
--- a/sample_02.txt
+++ b/sample_02.txt
@@ -1 +1,2 @@
a
+b
git add sample_02.txt
git diff --staged
diff --git a/sample_02.txt b/sample_02.txt
index 7898192..422c2b7 100644
--- a/sample_02.txt
+++ b/sample_02.txt
@@ -1 +1,2 @@
a
+b
2.2.4. コミット差分の確認
# git diff <fromコミット> <toコミット>
git diff HEAD~2..HEAD~1
diff --git a/sample_01.txt b/sample_01.txt
new file mode 100644
index 0000000..7898192
--- /dev/null
+++ b/sample_01.txt
@@ -0,0 +1 @@
+a
diff --git a/sample_02.txt b/sample_02.txt
new file mode 100644
index 0000000..7898192
--- /dev/null
+++ b/sample_02.txt
@@ -0,0 +1 @@
+a
git show HEAD
commit 0ce5883c412d04e9837852ae6c57d42abbe215e0 (HEAD -> main, origin/main)
Author: {ユーザー名} <{メールアドレス}>
Date: Mon May 1 16:58:14 2023 +0900
change sample_01
diff --git a/sample_01.txt b/sample_01.txt
index 7898192..422c2b7 100644
--- a/sample_01.txt
+++ b/sample_01.txt
@@ -1 +1,2 @@
a
+b
2.2.5. ファイル内の各行を最後に変更したコミット表示
git blame sample_01.txt
7cdaa2a1 ({ユーザー名} 2023-05-01 15:46:56 +0900 1) a
0ce5883c ({ユーザー名} 2023-05-01 16:58:14 +0900 2) b
00000000 (Not Committed Yet 2023-05-03 17:11:50 +0900 3) c
2.3. ブランチ操作
ブランチは、コミットの履歴を分岐してある目的の修正を他の修正の影響を受けずに開発していくための機能です。
mainブランチ1本でも開発は一応可能ですが、いろんな差分が1本の履歴に入っているとデメリットが多いです。
- 並行作業しにくい
- ある機能を開発している途中に別機能の改造も入ってきて、影響を受けやすい
- 関連する改造が分かりにくく、レビューしにくい
上記は一例ですが、これだけを見てもチーム開発では(個人開発でも)ある程度目的別にコミットを分離することが必要であるとわかります。
2.3.1. ブランチ作成
git branch <ブランチ名>
git branch <ブランチ名> <ブランチ作成位置:ブランチ名、タグ名、コミットIDなど>
2.3.2. ブランチ一覧
git branch
feature/user-list
* main
git branch -r
origin/main
git branch -a
feature/user-list
* main
remotes/origin/main
2.3.3. リモート追跡ブランチ設定(既存リモートブランチなし)
# git push -u <リモートリポジトリ名> <ブランチ名>
git push -u origin feature/user-list
# 実行前
git branch -a
feature/user-list
* main
remotes/origin/main
# 実行後
git branch -a
feature/user-list
* main
remotes/origin/feature/user-list (※リモートに feature/user-list が追加された)
remotes/origin/main
2.3.4. リモート追跡ブランチ設定(既存リモートブランチあり)
# git branch -u <リモートブランチ名> <ブランチ名>
git branch -u origin/feature/user-list feature/user-list
2.3.5. カレントブランチ変更(既存ブランチ)
checkout または switch を使用する。
git checkout <ブランチ名>
git switch <ブランチ名>
2.3.6. カレントブランチ変更(新規ブランチ)
既存でブランチが存在しない場合に、カレントブランチ変更と共にブランチを新規作成する。
git checkout -b <ブランチ名>
git switch -c <ブランチ名>
2.3.7. ブランチ削除
git branch -d <ブランチ名>
カレントブランチは削除不可。
指定したブランチがマージされていない場合などに -d
ではエラーとなる。
問題ない場合は -D
で強制的に削除することができる。
git branch -D <ブランチ名>
git push --delete origin <ブランチ名>
2.3.8. ブランチ名変更
git branch -m <oldブランチ名> <newブランチ名>
存在するブランチ名へ変更する際は -M
で強制する。
既存ブランチが別のコミットを指していた場合は、参照先がoldブランチの参照先に変更となる。
git branch -M <oldブランチ名> <newブランチ名>
リモートブランチ名の変更は、別名でブランチ作成して既存ブランチを削除する。
git branch -m <oldブランチ名> <newブランチ名>
git push --delete origin <oldブランチ名>
git push -u origin <newブランチ名>
2.3.9. マージ
git switch <マージ先ブランチ名>
# カレントブランチに指定したブランチをマージする
git merge <マージ元ブランチ名/コミットID/タグなど>
マージ戦略として fast-forward, 3-way がある。
マージ戦略 | 説明 |
---|---|
fast-forward | マージ先がマージ元の親であり、ブランチ参照先を単純に変更するだけで行うマージ。 |
3-way | マージ元とマージ先の両方を親とするマージコミットを作成し、マージ先の参照先をマージコミットに変更することで行うマージ。 |
main に feature/user-list を マージして fast-forward となる場合
main に feature/user-list を マージして 3-way となる場合
マージ戦略オプション | 説明 |
---|---|
--ff |
可能であれば fast-forward でマージする。できない場合は 3-way でマージする。(デフォルト動作) |
--no-ff |
fast-forward マージできる場合でもマージコミットを作って 3-way マージする。 |
--ff-only |
fast-forward マージできない場合はコマンドを失敗させる。 |
2.4. タグ操作
タグの種類 | 説明 |
---|---|
軽量タグ | コミットの単なる参照 |
注釈付きタグ | タグ付けメッセージ、日付等のメタデータを持つタグ。リリースに際してタグを打つ場合にリリース情報を載せるなどの使い方ができる。 |
2.4.1. タグ作成
# git tag <タグ名> [<コミット>]
git tag v1 HEAD~1
# git tag <タグ名> [<コミット>] -a -m "<注釈メッセージ>"
git tag v2 -a -m "Version 2"
# git push origin <タグ名>
git push origin v1
2.4.2. タグ確認
git tag -l
v1
v2
# ワイルドカードを使ったパターンで検索可能
git tag -l '*2'
v2
git show v2
tag v2
Tagger: {ユーザー名} <{メールアドレス}>
Date: Wed May 3 17:57:31 2023 +0900
Version 2
commit 0ce5883c412d04e9837852ae6c57d42abbe215e0 (tag: v2)
Author: {ユーザー名} <{メールアドレス}>
Date: Mon May 1 16:58:14 2023 +0900
change sample_01
diff --git a/sample_01.txt b/sample_01.txt
index 7898192..422c2b7 100644
--- a/sample_01.txt
+++ b/sample_01.txt
@@ -1 +1,2 @@
a
+b
2.4.3. タグを削除
# git tag -d <タグ名>
git tag -d v1
git push --delete origin v1
3. まとめ
基本的な git コマンドを中心に図を交えてどんな操作ができるのかまとめてみた。
正直、GUIクライアントの方が操作が簡単だったり、状況が分かりやすかったりする部分も多いのだが、CLIでもある程度操作可能な方が安心して使えるだろう。
近いうちに rebase などのコミット履歴の操作についてもまとめたい。
4. さらに学習する
- git 公式 Pro Git book
- git 公式 コマンドリファレンス
- Bitbucket チュートリアル
- サル先生のGit入門〜バージョン管理を使いこなそう〜
- GitHub Training Kit
以上
Discussion