18
13

More than 5 years have passed since last update.

これだけ知っておけば幸せになれるGitコマンドたち

Last updated at Posted at 2019-08-14

この記事なんやねん

これだけ知っておけば現場での開発では困らないだろうGitコマンドをつらつらと載せていきます。
マニアックなコマンドは載せないので、内容的には初級者向けです。

addcommitなどの超基本的なコマンドはリッチテキストエディタなら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 resetgit rebase -idropコマンドを使うのが簡単です。
それぞれの使い方は下記の項目を参照してください。

reset
rebase

競合が発生した

競合はマージする際に同じ箇所を同じタイミングで修正した場合に発生します。
競合が発生した場合は基本的にはエディタを開いて適用したい履歴を選択してください。

% 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はコミット自体を消すのではなくて、コミットを打ち消すコミットを作成します。
つまり、コミットそのものを消す破壊的なresetrebase -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 でファイルを削除。

18
13
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
13