始めに
こんにちは。
git、奥が深いですね。
ここに載ってるコマンドの意味を理解して使うことが出来れば恐らくあまりgitに困らなくなるんじゃないかな?
というチートシートを作成しました。
gitとは?という解説は載っていませんが、調べたらすぐ見つけられて有意義な記事はいっぱいありますので、今回は載せておりません。
参考程度に読んでみてください。
設定とか
gitに自分の名前とアドレスを登録(コミットする時のユーザーとアドレスを登録)
#### ユーザーとして登録(全てのリポジトリに登録)
$ git config --global user.email "you@example.com"
$ git config --global user.name "Your Name"
#### そのリポジトリに対して登録
$ git config user.email "you@example.com"
$ git config user.name "Your Name"
- ~/.gitconfigにはこんな感じで入ってくる
[user]
name = sample-user
email = sample@gmail.com
WSL2環境下でgitを使う(Windows+WSL2限定)
- 何も気にせずWSL2環境下でvscodeとかでgitを使おうとすると作業出来ないことがある
git status
すると以下のようなエラーが出ることがある
root:/home/hoge## git status
fatal: detected dubious ownership in repository at '/home/hoge'
To add an exception for this directory, call:
git config --global --add safe.directory /home/root/hoge
fatal: detected dubious ownership in repository
Git がリポジトリの所有権に関して安全でないと判断するとエラーがでる
リポジトリのファイルやディレクトリが予期しないユーザーやグループに属している場合に発生
以下で解決する
VSCode を閉じる
WSL のターミナルを開く
Git の安全なディレクトリのリストに問題のディレクトリを追加
ターミナルで次のコマンドを実行します
- $ git config –global –add safe.directory /home/hoge
- これは、Git に
/home/hoge
ディレクトリが安全であると認識させ、所有権の警告を無視させる
- その後、VSCode を再び開き、ディレクトリを開いて変更を続ける
- この時点で、Git の差分が正しく表示されるはず
改行コードの設定(Windows向け)
## core.autocrlf を設定(例: windowsはtrue を指定(推奨)linuxはinput)
#### コミット・チェックアウトした際の改行コードの設定
git config --global core.autocrlf true
## core.eol を設定(例: lf をデフォルトに)
#### 新しいファイルがリポジトリに追加されるときの改行コード
git config --global core.eol lf
- autocrlf
true
- リポジトリ内のファイルをコミットする際に
CRLF
からLF
に変換 - チェックアウトする際には
LF
をCRLF
に変換
- リポジトリ内のファイルをコミットする際に
input
- リポジトリ内のファイルをコミットする際に
CRLF
からLF
に変換 - チェックアウトする際には変換を行わない
- リポジトリ内のファイルをコミットする際に
false
- 改行コードの変換を行わない
- ファイルの改行コードがそのまま保持される
- eol
lf
: リポジトリ内のすべてのテキスト ファイルの改行コードをLF
に設定crlf
: リポジトリ内のすべてのテキスト ファイルの改行コードをCRLF
に設定
- ※基本、VScodeは、Gitの設定を尊重する
- VScodeで新しいファイルを作成→Gitで管理していると、Gitの設定によって改行コードが変換される
- ~/.gitconfigにはこんな感じで入ってくる
[core]
eol = lf
autocrlf = true
シンボリックリンクの変換設定
- Windowsはシンボリックリンクを認識できない
git config --global core.symlinks true
Git for Windowsでシンボリックリンクを扱えるようにする
Gitへ移行して、シンボリックリンクにはまったお話 (Usersにシンボリックリンク作成権限を付与するまで)
commitメッセージを扱うエディタをvimに指定
## そのユーザーに設定
$ git config --global core.editor "vim"
## そのリポジトリに設定
$ git config core.editor "vim"
そのリポジトリに対しての設定
#### そのリポジトリに対して設定
vi <リポジトリのディレクトリ>/.git/config
- 以下入力する内容
[core]
editor = vim
グローバルに設定
#### ユーザーの直下で
vi <リポジトリのディレクトリ>/.git/config
- ~/.gitconfigにはこんな感じ
[core]
editor = vim
既存のリポジトリから新しいリポジトリへのコードの移行
- 既存のリポジトリをベースに作業を進める際、自身のGitリポジトリを使用したい
新しいリポジトリへのプッシュ:
## 既存のリモート(origin)を削除
git remote remove origin
## 新しいリモートリポジトリをoriginとして追加
git remote add origin 新しいリポジトリのURL
## ブランチを新しいリポジトリにプッシュ
git push -u origin ブランチ名
チェックアウト系
ローカル
自分がいるブランチを知る
$ git branch
ローカルとリモートの差を知る(現在のGitブランチの状況を知る)
$ git branch -vv
- こんな感じで返ってくる
sample@sample-app01:~/app$ git branch -vv
* AAA-001 26895f2 [origin/AAA-001: behind 2] Merge pull request ##82 AAA-998 into AAA-686
AAA-002 800a7b8 [origin/AAA-002] セッションを保存する為のディレクトリを生成するように、Dockerfileに追記
master d406f30 [origin/master] Merge pull request ##80 AAA-999 into master
- 米印の箇所は今いるブランチ
- 最後のコミットは
26895f2
で、「Merge pull request ##82 AAA-998 into AAA-686」 - このブランチは
origin/AAA-001
ブランチをトラッキングしている- リモートブランチに対して2つのコミットで「
behind
」、遅れている。 ahead
は進んでいることを表す
- リモートブランチに対して2つのコミットで「
新しいブランチを作成(ローカル)
$ git branch <新しいブランチ名>
任意のブランチにチェックアウト (ローカル) ※あまり使わない・古いgitでも使える
$ git checkout <ブランチ名>
任意のブランチにチェックアウト(ローカル) ※使う・古いgitでは使えない
$ git switch <ブランチ名>
ブランチ作成+チェックアウト(ローカル) ※あまり使わない・古いgitでも使える)
$ git checkout -b <新しいブランチ名>
- branchのb
ブランチ作成+チェックアウト(ローカル) ※使う・古いgitでは使えない
$ git switch -c <新しいブランチ名>
- createのc
ブランチ削除(ローカル)
$ git branch -d <削除したいブランチ名>
- マージされているかチェックもする
- マージされていない場合、Gitは削除を拒否する
ブランチ削除 強制(ローカル)
$ git branch -D <削除したいブランチ名>
- ブランチがマージされているかどうかに関わらず、ブランチを強制的に削除
headを過去に移動する
$ git checkout HEAD^
$ git checkout <commitのハッシュ>
$ git restore --source=HEAD^
$ git restore --source=<commitのハッシュ>
HEAD^
は直前- restore は「結果的に同じになる」というだけ
- 目的が違う
- checkout:切り替え
- restore :リセット
- 目的が違う
- ※switchは出来ない
特定のcommitがどのブランチに属しているか確認する
$ git branch --contains HEAD
$ git branch --contains コミットのハッシュ
直前にいたブランチに切り替える
$ git switch -
$ git checkout -
リモート
チェックアウト出来るリモートのブランチを知る
$ git branch -r
#### 以下2行は同義
$ git branch -r | grep aaa
$ git branch -r --list '*aaa*'
- remoteのr
fetchする
$ git fetch
リモートのブランチにチェックアウト ※あまり使わない・古いgitでも使える
$ git checkout -b [新しいローカルブランチ名] [リモート名]/[リモートブランチ名]
exa)
$ git fetch
$ git checkout -b feature/sample-111 origin/feature/sample-111
- ローカルにすでに
feature/sample-111
という名前のブランチが存在する場合、エラーを返す
リモートのブランチにチェックアウト ※使う・古いgitでは使えない
$ git switch -c [新しいローカルブランチ名] [リモート名]/[リモートブランチ名]
exa)
$ git fetch
$ git switch -c feature/sample-111 origin/feature/sample-111
- ローカルにすでに
feature/sample-111
という名前のブランチが存在する場合、エラーを返す
stash
スタッシュの作成
$ git stash save "スタッシュの名前"
- saveオプションを付けないと
- stash@{n}: WIP on [ブランチ名]: [コミットハッシュ] [コミットメッセージの一部]
- “master” ブランチで最新のコミットメッセージが “Add new feature” であった場合、スタッシュのデフォルト名は以下のようになる
- stash@{n}: WIP on [ブランチ名]: [コミットハッシュ] [コミットメッセージの一部]
stash@{0}: WIP on master: 1a2b3c4 Add new feature
スタッシュの一覧表示
$ git stash list
- 表示されたリストの名前を変更することは出来ない
- 一度スタッシュされたモノは名前を変更出来ない
- applyして、drop、再度stashする以外できない
- ※git stash -uで未追跡分もスタッシュ出来るが、未追跡分も含めてのスタッシュは、名前指定は出来ない
- 一度スタッシュされたモノは名前を変更出来ない
最新のスタッシュを適用
$ git stash apply
特定のスタッシュを適用
$ git stash apply stash@{n}
n
に指定した番号のスタッシュを適用- ※{}記号も必要
スタッシュの削除
$ git stash drop stash@{n}
最新のスタッシュを適用して削除
$ git stash pop
未追跡ファイル(新規作成ファイル等)を含めてスタッシュ
$ git stash -u
- 未追跡のファイルもスタッシュするが、名前の指定は出来ない
- 未追跡のファイルを含めてスタッシュする場合は、名前を指定してスタッシュすることは出来ない
最新のスタッシュの変更内容を確認
$ git stash show
特定のスタッシュの変更内容を確認
$ git stash show -p stash@{n}
add系
どのファイルが変更されたかを確認
$ git status
未追跡ファイルの変更を確認
$ git status -u
add
-- ファイルを指定してadd
$ git add index.html
-- 全てadd
$ git add .
- こんな感じになる
#### git statusで変更分を把握
user@sample-project:~/current$ git status
On branch AAA-123
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: index.html
modified: index2.html
no changes added to commit (use "git add" and/or "git commit -a")
#### addする
user@sample-project:~/current$ git add index.html
addした分を、addしていない状態に変更する
-- ファイルを指定して
$ git restore --staged index.html
-- 全て
$ git restore --staged .
- こんな感じになる
user@sample-project:~/current$ git status
On branch AAA-123
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: index.html
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: index2.html
user@sample-project:~/current$
user@sample-project:~/current$
user@sample-project:~/current$ git restore --staged index.html
user@sample-project:~/current$
user@sample-project:~/current$
user@sample-project:~/current$ git status
On branch AAA-123
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: index.html
modified: index2.html
gitが古くてrestoreが出来ない場合
$ git checkout -- .
- 上記で再現可能
addしていない、変更したファイルの変更分をリセット
#### ファイルを指定
$ git restore index.html
#### 全て
$ git restore .
#### 上記はデフォルトで以下のオプションが付いて実行されている
#### 現在のワークツリーの最新までリセット
$ git restore --worktree .
#### 同意義だが、考え方が違う
###### restore --source=hogehoge は、その箇所までheadを戻す作業
$ git restore --source=HEAD
###### 最新のhead(現在のcommit)までheadが移動するから、結果的に、addしていない変更したファイルの変更分をリセット
- — worktreeは
- 指定したファイルに対して最後のコミット (
HEAD
) の内容でワーキングツリーをリセット
- 指定したファイルに対して最後のコミット (
gitが古くてrestoreが出来ない場合
$ git clean -f
- 上記で再現可能
追跡していないファイルを削除
$ git clean -f
- オプションを付けないと、何も走らない
未追跡ファイルの一覧表示:
$ git clean -n
ディレクトリの削除
git clean -fd
-d
オプションは、未追跡のディレクトリも削除
commit系
commit
$ git commit -m"サンプルコミット1"
- messageの-m
- -mつけなければ、Vimとかが起動して、メッセージを入れろと言われる
addとcommitを一緒にやる
$ git commit -a -m "変更をコミット"
$ git commit -all -m "変更をコミット"
$ git commit -am "変更をコミット"
- addしていないものは全てaddしてcommitする
commitメッセージにエディタを使う
#### 何かしらaddされている状態で
$ git commit -e
直前のcommitのコメントを変更する
$ git commit --amend
- コミットメッセージや変更内容を変更した場合、それは新しいコミットとして扱われる
- 過去のコミットを直接変更するのではなく、新しいコミットが作成される
- 修正前のモノは、通常の
git log
では表示されないgit log --reflog
で見ることが出来る- リポジトリの reflog を表示
- Reflog はコミットの歴史におけるブランチや HEAD などの参照の変更履歴を記録している
- リポジトリの reflog を表示
直前のcommitのを内容を変更する
#### 直前のcommit内容に反映する為のコード編集を行った後
$ git add /index.html
$ git commit --amend -m "直前のコミットを変更する"
- これで、新しいコミットが作成され、git logでは表示できなくなる
git log --reflog
で見ることが出来る(直前のコマンド参照)
- 上記のコマンド通りなら、直前のコミットのコメントも「直前のコミットを変更する」に変更される
直前のcommitを打ち消す
$ git reset --hard HEAD^
HEAD^
は直前--hard
は変更差分が残らない(全部消す)--soft
変更差分が残る- デフォルトは
--hard
push系
基本的な使い方
$ git push <リモート名> <ブランチ名>
$ git push origin master
トラッキングブランチのプッシュ
$ git push
- ローカルブランチとリモートブランチがトラッキング関係にある場合、ブランチ名を省略
新しいブランチのプッシュ
$ git push -u origin new-feature
-u
オプションを使ってトラッキングを設定
強制プッシュ
$ git push --f
$ git push --force
- リモートを無理やりローカルの状態にする
ローカルを追跡対象にして新しいブランチをpush
$ git push --set-upstream origin develop
無理やりリモートを過去のローカルに合わせる
- 扱いに注意する事!
1.どこまで過去に遡るかlogを見る
$ git log -n 30 --oneline --graph
遡りたいcommit idを控える
2.HEADを過去に移動して、そこまでコミットをリセットする
$ git reset --hard 123asdf
3.現在のHEADの状況をリモートに無理やり充てる
$ git push -f origin master
merge系
基本的な使い方
## masterブランチに、AAA-001をマージ
$ git switch master
$ git merge --no-ff AAA-001
-no-ff(基本はこれを使う) Non-Fast-Forward Merge
## masterブランチに、AAA-001をマージ
$ git switch master
$ git merge --no-ff AAA-001
- 常にマージコミットを作成し、マージされたブランチの歴史を保持
そのままcommitを進めたみたいに(使わない)Fast-Forward Merge
## masterブランチに、AAA-001をマージ
$ git switch master
$ git merge AAA-001
- マージされたブランチの履歴が直線的に見え、マージが明確に表示されない
pull系
基本的な使い方
#### fetchする
$ git fetch
#### リモートとローカルの差分を知る
$ git branch -vv
#### pullする
$ git pull
- fetchとmergeを同時に行う
rebase
する****
$ git pull --rebase
- これにより、リモートブランチの変更を現在のブランチの変更の前に配置する
- 多大な差分があり、masterと差分を合わせたい時とかに便利
特定のリモートとブランチを指定
$ git pull origin AAA-002
- 今いるブランチに、特定の機能(commit)を追加するときとかに使う
リビジョン範囲について
- Gitにおける「リビジョン範囲(Revision Range)」とは、特定の二つのリビジョン(コミット、ブランチ、タグなど)間の差分や履歴を指定するための記法
..
または...
という記号を使用
A..B(二点間)
- 「AからBまで」を意味
$ git log origin/A...origin/B
origin/A
にはないがorigin/B
に存在するコミットを表示$ git log HEAD..origin/master
- 現在のブランチ(
HEAD
)にはないがリモートのmaster
ブランチにあるコミットを表示
- 現在のブランチ(
A…B(三点間)
A
とB
の共通の祖先から分岐して、A
とB
のいずれかに属するが、両方には属さないコミット$ git log origin/A...origin/B
- 両方のブランチが共通の祖先からどのように異なる進化を遂げたかを確認
- これは、共通しないコミットをそれぞれ表示
diff系
addされていないファイルの差分を確認(行ごとに確認)
$ git diff
- こんな感じで表示される
user@sample-project:~/current$ git diff
diff --git a/index.html b/index2.html
index 07af7e0..0703ac0 100644
--- a/index.html
+++ b/index2.html
@@ -277,7 +277,7 @@ function onPlayerStateChange(event) {
<div class="bg-text2">
<p>変更1</p>
- <p>変更2</p>
+ <p>変更3</p>
@@ -338,7 +338,7 @@ function onPlayerStateChange(event) {
}
+<p>pepepepe</p>
</div>
</div>
- index.htmlについて差分
- 07af7e0..0703ac0
- 07af7e0から0703ac0の間での差分を表示(リビジョンについての解説を参照)
- — a/index.htmlが変更前で、+++ b/index2.htmlが変更後
- @@ -277,7 +277,7 @@
- 277から7行表示
- 07af7e0..0703ac0
addされていないファイルの差分を確認(単語ごとに確認)
$ git diff --color-words
$ git diff -w
- こんな感じで表示される
- 縦でなく、横に表示される同じ行で変更があった場合、機能する
user@sample-project:~/current$ git diff --color-words
diff --git a/index.html b/index2.html
index 07af7e0..0703ac0 100644
--- a/index.html
+++ b/index2.html
@@ -276,8 +276,8 @@ function onPlayerStateChange(event) {
<div id="max_width2">
<div class="bg-text2">
<p>変更1</p>
<p>変更2</p><p>変更ddddd1</p>
<p>変更3</p>
@@ -338,7 +338,7 @@ function onPlayerStateChange(event) {
}
<p>pepepepe</p>
</div>
</div>
addされているファイルの差分を確認(行ごとに確認)
$ git diff --cached
addされているファイルの差分を確認(単語ごとに確認)
$ git diff --cached --color-words
トラッキングしていないファイルをdiffで見る
- 出来ない
- cat とかで見るしかない
$ cat sample.sh
sample_proj@sample-app01:~/proj/sample-app01$ git status
On branch master
Your branch is up to date with 'origin/master'.
Untracked files:
(use "git add <file>..." to include in what will be committed)
sample.sh
nothing added to commit but untracked files present (use "git add" to track)
sample_proj@sample-app01:~/proj/sample-app01$ cat sample.sh
コミット履歴(log)
現在のブランチのコミット履歴を表示
基本
$ git log
- コミット履歴が長い場合は、ページごとに表示される
q
キーを押して終了
一行表示
$ git log --oneline
- これは各コミットを一行で簡潔に表示
特定の数のコミットのみを表示
$ git log -n <数>
- 例:
git log -n 5
は最新の5つのコミットを表示
グラフとして表示
$ git log --graph
- ブランチとマージの履歴を視覚的なグラフとして表示
グラフと1行表示を組み合わせる
$ git log --graph --oneline
他ブランチのログを見る
$ git log --graph --oneline -n 5 sample-222
特定のファイルやディレクトリの履歴を表示する
$ git log -p <ファイルまたはディレクトリ>
Aブランチには存在しないがBブランチに存在するコミットを表示
$ git log origin/A..origin/B
$ git log --oneline origin/A..origin/B
origin/A
ブランチには存在しないがorigin/B
ブランチに存在するコミットを表示- つまり
origin/A
ブランチの最終コミットからorigin/B
ブランチの最終コミットまでの間に行われたコミットをリストアップorigin/B
の観点から見たorigin/A
との差分
- つまり
Aブランチ、又はBブランチにだけ存在するコミットを表示
$ git log origin/A...origin/B
$ git log --oneline origin/A...origin/B
- このコマンドは、
origin/A
とorigin/B
の共通の祖先から分岐した後、どちらか一方のブランチにだけ存在するコミットを表示- つまり
- 両方のブランチが共通の祖先からどのように異なる進化を遂げたかを確認
- これは、共通しないコミットをそれぞれ表示
- つまり
チェリーピック
- あるブランチの特定のコミットを別のブランチに適用する
- 全体のブランチをマージするのではなく、特定の変更だけを取り込みたい場合
基本的な使い方
commitを残したくないとき
$ git cherry-pick --no-commit コミットハッシュ
- 指定されたコミットの内容を適用するが、自動で新しいコミットを作成しない
- 手動で変更を確認してからコミットすることができる
commitを残す
$ git cherry-pick コミットハッシュ
複数のコミットを選択してチェリーピック
$ git cherry-pick コミットハッシュ1 コミットハッシュ2
コミットの範囲を選択してチェリーピック
$ git cherry-pick 開始コミットハッシュ..終了コミットハッシュ
チェリーピックのキャンセル
$ git cherry-pick --abort
- チェリーピック操作をキャンセルし、ブランチを操作前の状態に戻す
コンフリクトの解決後の続行
$ git cherry-pick --continue
- コンフリクトを解決した後、チェリーピックを続行する