この記事なんやねん
これだけ知っておけば現場での開発では困らないだろうGitコマンドをつらつらと載せていきます。
マニアックなコマンドは載せないので、内容的には初級者向けです。
add
、commit
などの超基本的なコマンドはリッチテキストエディタならGUIから操作できるので省略してます。
用語解説
この記事で使う用語解説もついでに載せておきます。
因みに、サルでもわかるGit入門が入門チュートリアルとしてはオススメなので完全にGit触るのが初めてならこちらも確認してください。
リモートリポジトリ
Gitは分散型バージョン管理システムなのでリモートリポジトリとローカルリポジトリが存在します。リモートリポジトリは複数人で作業する時に使う共有リポジトリで、例えばGitHub上で作った自分のリポジトリなどのことです。
ローカルリポジトリ
自分専用のリポジトリです。ローカル環境にあるのでオフラインでも編集内容を登録できます。例えば、リモートリポジトリからgit clone
すると作業ディレクトリがローカルにできますが、これがローカルリポジトリになります。
ブランチ
リポジトリの中には更にブランチという履歴毎の分岐が存在しています。要するに、ブランチ毎にソースが管理されています。ブランチ同士は独立した履歴を持っているので影響を受けません。
例えば、AブランチとBブランチがあった時に、Aブランチで作業を進めたとしても、Bブランチでは一切ソースは変更されません。
ブランチがある事により、同一リポジトリ内で複数の修正作業を同時に進める事ができます。
Trackedファイル
Git管理下にあるファイルのことです。トラッキングされてればファイルの内容を変更するとGitが教えてくれます。
Untrackedファイル
Git管理外にあるファイルのことです。新規に作ったファイルはコミットしない限りトラッキングされずに、UntrackedファイルとしてGitに認識されます。
add
修正した内容をコミット対象に含める事です。具体的には、ワークツリーからインデックスに移動します。
コミット
修正した内容をローカルリポジトリに反映(登録)する事です。これによりGitの履歴に修正内容がコミットログとして反映され、UntrackedだったファイルもGit管理下になります。
プッシュ
ローカルリポジトリでのコミット内容をリモートリポジトリにも反映する事です。これにより自分の修正が他のチームメンバーにも共有可能になります。
ワークツリー
作業領域のことです。Git管理下のファイルや新規でファイルを追加するとワークツリーに反映されます。
インデックス(ステージ)
コミットする対象ファイルを配置する領域です。Gitの操作は基本的にコミット単位で行われるので、コミットを意味のある単位でまとめる事が重要になります。
そのため、ワークツリーとインデックスという2つの領域が存在していて、修正したファイルを全てコミットしなくてもいいようになっています。これにより柔軟なコミットが可能になっています。
ローカルリポジトリの状態についてまとめると下記のようになります
% git status
# ローカルリポジトリにコミットされてまだプッシュされてないコミット
# 今回だと3つがまだプッシュされていない
On branch master
Your branch is ahead of 'origin/master' by 3 commits.
(use "git push" to publish your local commits)
# インデックスに登録されてコミットする準備ができてるファイル
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: hoge.txt
# ワークツリーのファイルでインデックスに登録されていないファイル
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
modified: sample.txt
# git管理外の新規ファイル
Untracked files:
(use "git add <file>..." to include in what will be committed)
foo.txt
ローカルリポジトリとリポートリポジトリの差分をログから確認すると下記のようになってる。
% git log --oneline master
# ローカルリポジトリでは3つのコミットが追加されてるのが分かる
fa18ec5 (HEAD -> master, foo, bugfix) remove sample 03
9f2b27d fix sample
f354df0 reject push master
# リモートリポジトリの最新はここまで
ff78f49 (origin/master, origin/HEAD) add hoge
3be6061 Add Hoge
コマンド集
早速ここからコマンドを紹介していきます。ユースケース毎に紹介していこうと思います。
ブランチの作成と切り替えを同時に行う
git checkout
でブランチの作成と切り替えを同時に行う事ができます。
git checkout -b hoge
ブランチを削除したい
ローカルリポジトリが増えてくると整理したくなりますよね。git branch
に-d
オプションを付与することでブランチを削除する事ができます。
git branch -d hoge
削除したいブランチを複数指定することも可能。
git branch -d hoge foo
強制削除したい時は-D
オプションを指定。
git branch -D hoge
コミットログを1行単位で出力したい
正直デフォルトだと見辛いですよね。そこで--oneline
オプションを使うと1行で表示できてめっちゃスッキリします。
git log --oneline
コミット間の差分を表示したい
diff
コマンドを使用すると差分が確認できます。差分箇所とファイル名などの詳細情報を表示します。
差分を確認したいハッシュ値を指定してください。
git diff fa18ec5 9f2b27d
1つ指定したら今いるブランチの最新コミットとの比較になります。
git diff fa18ec5
ブランチ間の差分を表示したい
ブランチ間の差分を表示したい場合はブランチ名を指定します。
git diff origin/master
別ブランチ同士の比較もできます。
git diff hoge origin/master
差分のあるファイル名のみ表示したい
差分のあるファイル名のみ表示したい場合は--name-only
を付与します。
git diff --name-only fa18ec5 9f2b27d
git diff --name-only origin/master
特定のファイル・ディレクトリの差分が知りたい
特定のファイル・ディレクトリの差分が知りたい場合はファイルパスを指定します。
git diff hoge sample.txt
作業中に別ブランチに切り替えたい
stash
コマンドを使うと作業中の修正を一旦保存してくれます。作業状態の保存は複数登録できます。
保存する時は git stash
,
取り出す時は git stash pop
を使用してください。
git stash list
でstashしたリストも見れます。
一時保存を指定して取り出したい
一時保存の一覧 git stash list
で確認してから、左端のインデックスを指定して取り出しましょう。
% git stash list
stash@{0}: WIP on foo: 9f2b27d fix sample
stash@{1}: WIP on foo: 9f2b27d fix sample
stash@{1}
を取り出したい場合は下記のようにします。
git stash pop stash@{1}
masterの最新を作業中のブランチに反映したい
git rebase
を使うと、ブランチで作業した内容の履歴より前にmasterの最新を反映できるので、コミットログが綺麗になって便利です。
実行前にフェッチするのを忘れずに。
git rebase origin/master
コミットを修正したい
git rebase
に-i
オプションをつけることでコミット履歴を修正できます。かなり便利なコマンドで使用頻度も高いです。
まずは、コミットログを確認しましょう。
% git log --oneline
ba829e6 (HEAD -> hoge) add hoge 02
16ffcff add hoge 01
fa18ec5 (master, foo, bugfix) remove sample 03
add hoge 01
のコミットを修正したい場合は1つ前のコミットハッシュ値を指定してください。
git rebase -i fa18ec5
次に、エディタが開くので、各コミットにコマンドを指定して編集してください。それぞれよく使うのはこんな感じ。
-
pick
: コミットをそのまま使う。 -
r
: コミットは使うけど、コミットメッセージは変える。 -
s
: 上のコミットにまとめる。コミットメッセージも変える。 -
f
: 上のコミットにまとめるけど、コミットメッセージは上のコミットのものを使う。 -
d
: コミットを破棄する。
編集画面はこんな感じです。コミットのハッシュ値の左にコマンドを指定してコミットを編集してください。今回の例だと、add hoge 01
コミットにadd hoge 02
コミットを統合してコミットメッセージはそのままにしていますね。
1 pick 16ffcff add hoge 01
2 f ba829e6 add hoge 02
3
4 # Rebase fa18ec5..ba829e6 onto fa18ec5 (2 commands)
5 #
6 # Commands:
7 # p, pick = use commit
8 # r, reword = use commit, but edit the commit message
9 # e, edit = use commit, but stop for amending
10 # s, squash = use commit, but meld into previous commit
11 # f, fixup = like "squash", but discard this commit's log message
12 # x, exec = run command (the rest of the line) using shell
13 # d, drop = remove commit
ローカルリポジトリでリモートリポジトリを上書きしたい
git push
に-f
をつけると強制プッシュできます。
既にリモートリポジトリにプッシュ済みのコミットをrebase
で編集した時にnon-fast-forward
のためプッシュできなかったりします。
もしブランチで作業しているのが自分だけであれば強制プッシュするのが手っ取り早いです。
git push origin/hoge -f
ただし、強制プッシュはその他のメンバーの開発に影響を与えるので、実行する際は慎重にしてください。自分のみ作業しているブランチ以外で実行する場合は、チームメンバーの了解を得るようにしましょう。
リモートリポジトリでローカルリポジトリを上書きしたい
上記の逆パターンですね。reset
コマンドを使いましょう。
反映させたいリモートリポジトリを指定してください。
git reset --hard origin/master
特定のコミットをブランチに取り込みたい
cherry-pick
を使うと別ブランチのコミットを作業してるブランチなどに取り込む事ができます。
取り込みたいハッシュ値を指定すれば内容が反映されます。
git cherry-pick 7e4bfd0
特定のコミットまで戻したい
reset
コマンドを使いましょう。
戻したいコミットのハッシュ値を指定してください。
git reset --hard 9f2b27d
もしくは最新のコミット(HEAD)から指定してもいいです。
git reset --hard HEAD
← 作業中の内容を破棄したい時
git reset --hard HEAD^
← 1つ前のコミットまで戻したい時
git reset --hard HEAD^^
← 2つ前のコミットまで戻したい時
gitの操作を取り消したい時
reflag
で作業内容を確認して同じくreset
コマンドで戻す事ができます。よく使うパターンはreset
コマンドでミスした時などですかね。
因みに、reflag
で出てくるログはローカルリポジトリでのリポジトリ操作に関する参照ログなので、コミットログとは違います。
# たくさん出てくるの直近5件のログを指定してます
% git reflog -n 5
f354df0 (HEAD -> master) HEAD@{0}: reset: moving to HEAD^
9f2b27d HEAD@{1}: reset: moving to 9f2b27d
fa18ec5 (foo, bugfix) HEAD@{2}: reset: moving to fa18ec5
9f2b27d HEAD@{3}: reset: moving to 9f2b27d
fa18ec5 (foo, bugfix) HEAD@{4}: checkout: moving from hoge to master
例えば、reset: moving to 9f2b27d
にてreset
した内容を取り消したい場合。
git reset --hard HEAD@{1}
コミットを取り消したい
コミットを取り消すやり方をケース毎に紹介します。
リモートにはプッシュしていない時
git reset
かgit rebase -i
のdrop
コマンドを使うのが簡単です。
それぞれの使い方は下記の項目を参照してください。
競合が発生した
競合はマージする際に同じ箇所を同じタイミングで修正した場合に発生します。
競合が発生した場合は基本的にはエディタを開いて適用したい履歴を選択してください。
% git merge origin/fix02
# 競合が発生!
Auto-merging sample.txt
CONFLICT (content): Merge conflict in sample.txt
Automatic merge failed; fix conflicts and then commit the result.
% cat sample.txt
<<<<<<< HEAD
=======
Hoge Hoge
>>>>>>> origin/fix02
上記のログで説明すると、HEAD
で囲まれてる部分がmerge先のブランチの状態で、
<<<<<<< HEAD
=======
origin/fix02
で囲まれてる部分がmergeしようとしてるブランチの状態です。
若干、見辛いですが、エディタを使ってればもっと見易くなります。
=======
Hoge Hoge
>>>>>>> origin/fix02
このコンフリクトを解消する場合は、単純に適用したい方のソースコードを残して、あとのコードは消してください。当たり前ですが、<<<<<<< HEAD
などの記載も消してください。
Atomなどのエディタを使ってれば標準でボタン押すだけでコンフリクト解消できます。
競合する前の状態に戻したい
もし、競合する前の状態に戻したい、要するに、マージを取り消したければ、--abort
オプションを使いましょう。
git merge --abort
rebaseでも使えます。 git rebase --abort
既にリモートにプッシュした時
いくつかやり方がありますが、推奨されてるやり方、というか簡単なのはrevert
です。
revert
はコミット自体を消すのではなくて、コミットを打ち消すコミットを作成します。
つまり、コミットそのものを消す破壊的なreset
やrebase -i
とは異なり、コミットログには履歴が残り続けます。
取り消したいコミットのハッシュ値を指定します。
git revert f354df0
マージコミットを取り消したい場合は-m 1
オプションをつけます。これは親番号を指定するもので、マージコミットには親が2つ以上(masterなどの本線と派生ブランチ)存在するため、どちらを親にするか指定する必要があります。普通の開発フローなら-m 1
で大丈夫です。
g revert -m 1 e3d2c6e
特定のファイルを修正前の状態に戻したい
git checkout
で特定のコミットまで戻すことができます。
使い方は、 git checkout <コミットID> <戻したいファイルパス>
です。
git checkout f354df0 hoge.txt
Untrackedファイルを削除したい
新規で追加したファイルを削除したい時はgit clean
を使います。
git clean -n
でGit管理外のファイルを確認,
git clean -f
でファイルを削除。