自分が仕事とかでよく使ってるgitコマンドのメモ。
([追記]ファイル名と書いてますが、パス含めてのファイル名です。)
なんとなく、いつも使ってる流れ順
fetch
$ git fetch origin
リモートリポジトリの状態をローカルに持ってくる。
上記だと分かりにくい&誤解がありそう。
自分は、ローカルで持ってる「リモートの(ブランチとかの)構成図」を最新のリモートの構成図に更新する的なイメージを持ってる。
上記コマンド例の場合、originというリモートリポジトリの状態を持ってくる。
branch
$ git branch
ローカルに存在するブランチの一覧を表示する。
出力は、こんな(↓)感じ
ID227_deleteAfunction
* ID228_addBfunction
ID232_fixCfunction
master
先頭に*
が付いてるブランチが、現在いるブランチ
また
$ git branch 新規ブランチ名
で、現在いるブランチを元に、新しいブランチを作成できる。(移動はしない。)
新規ブランチ名のブランチが存在する場合、エラーになる。(作成できない。)
ただ自分は、あまりこのコマンドは使ってない。(checkoutのほうを使う。)
-Dオプション
$ git branch -D ブランチ名
branchコマンドに-Dオプションをつけると、ブランチの削除ができる。
もちろんだが、自分が現在いるブランチは削除できない。
自分は、よく、気付いたらローカルブランチが大量になってるので、たまのタイミングで古いのを一気に消す。
-Mオプション
$ git branch -M 新ブランチ名
branchコマンドに-Mオプションをつけると、ブランチのリネームができる。
上記のコマンドでは、現在いるブランチの名前を新ブランチ名に変更する。
自分ネームセンスが無いんで、よく後から変える。
checkout
$ git checkout ブランチ名
ブランチの切り替えを行う。現在いるブランチが、ブランチ名に指定したブランチになる。
存在しないブランチを指定するとエラーになる。
$ git checkout ファイル名
とした場合、指定したファイルを現在いるブランチの最新commit状態に戻す。
書き換えたけど、やっぱ全部元に戻したい時に使える。
-bオプション
$ git checkout -b 新規ブランチ名 元にするブランチ名
新規にブランチを作り、そのブランチに移動する。
元にするブランチ名は、ローカルでもリモートでもOK。
リモートを指定する場合は、リモート名/ブランチ名。origin/master
こんな感じ。
また、元にするブランチ名を省略した場合、
現在いるブランチを元にして、新規ブランチを作り、そのブランチに移動する。
変更点がある場合(git status
で、Untracked files
以外がある時)、
その変更点が、元にするブランチと競合しない場合、変更を維持したまま、新規ブランチを作成し、そのブランチに移動する。
変更点が、元にするブランチと競合する場合、エラーになって、新規ブランチの作成もされない。
status
$ git status
現在のブランチでのファイルの状態の一覧を表示する。
出力は、こんな(↓)感じ
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: src/A.hs
deleted: src/E.hs
renamed: src/F.hs -> src/G.hs
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)
(commit or discard the untracked or modified content in submodules)
modified: src/main.hs
modified: src/B.hs
deleted: src/D.hs
modified: config/settings.yml
modified: stack.yaml
Untracked files:
(use "git add <file>..." to include in what will be committed)
app.prof
app.log
src/C.hs
読んだとおりだが、
-
Changes to be committed:
は、ステージされた変更
git rm
や、git mv
、既にgit add
したファイルがここに書かれる。 -
Changes not staged for commit:
は、ステージされて無い変更
現在いるブランチの最終commitから変更のあった、まだgit add
されてないファイルがここに書かれる。 -
Untracked files:
は、追跡してないファイル
現在いるブランチで、追跡していないファイルがいる場合、ここに書かれる。
変更の種類は、(これまた読んで字の通りだが)
-
modified
が中身に変更点のあるファイル -
deleted
が削除されたファイル -
renamed
が名前が変更されたファイル(git mv
使った時)
diff
$ git diff
現在のブランチのChanges not staged for commit
にあるファイルの中身の差分を表示する。
この場合、変更のある全てのファイルの差分が表示される。
$ git diff ファイル名
とすれば、指定したファイルの差分のみ表示される。
add
$ git add ファイル名
ファイルの変更を登録する。
git status
でChanges not staged for commit:
にあったファイルをcommit前にgit add
する必要がある。
この登録(?)のことをステージングというらしい。(よくわかってない勉強不足)
自分はいつも、git status
で出てきたファイル名をスペース区切りでgit add
の後ろにコピペしてきて実行する。(パス間違えとかなくなるから)
新規追加したファイルは、Untracked files
にいるので、忘れないように!(戒め)
reset
$ git reset ファイル名
ファイルの変更の登録を取り消す。
git add
するなどして登録したChanges to be committed:
を取り消す。
rm
$ git rm ファイル名
ファイルの削除。この場合、追跡が削除され、ファイルも削除される。
また自動で、削除したことが登録(ステージング)される。
--cachedオプション
$ git rm --cached ファイル名
追跡のみ削除し、ファイルはその場に残す。
削除の取消
よく使うわけではないが、ちょっと手順があったんで、記述。
git rm
で削除したファイルを元に戻すには、以下の手順を踏む。
- 登録の取消
$ git reset HEAD ファイル名
として、登録を取り消す。(HEAD
が必要)
2. 削除の取消
$ git checkout ファイル名
として、ファイルを元に戻す。
mv
$ git mv ファイル名 新ファイル名
ファイルの移動。この場合、ファイルのリネーム関係が登録されるので、変更点の追跡ができる。
また自動で、リネームしたことが登録(ステージング)される。
gitコマンドでなく、$ mv ファイル名 新ファイル名
として、その変更を登録しまうと、
ファイル名のファイルを削除し、新ファイル名のファイルを追加したことになるので、変更点が追えなくなる(はず)ので、注意。
リネームの取消
これもよく使うわけではないが、ちょっと手順があったんで、記述。
git mv
でリネームしたファイルを元に戻すには、以下の手順を踏む。
- リネーム後ファイルの登録の取消
$ git reset リネーム後ファイル名
として、登録を取り消す。
2. リネーム前ファイルの登録の取消
$ git reset HEAD リネーム前ファイル名
として、登録を取り消す。(HEAD
が必要)
3. リネーム前ファイルの復元
$ git checkout リネーム前ファイル名
として、ファイルを元に戻す。
commit
$ git commit
登録された変更(git status
でChanges to be committed
にあるファイル)をコミットする。
このコマンドを実行すると、エディタが開いて、変更のステータスが表示される。
そのファイルの先頭に書いた言葉が、コミットコメントになる。
ファイルを保存してエディタを終了すると、コミットが実行される。
-mオプション
$ git commit -m コメント
コミットコメントを指定してコミットする。
この場合、エディタは開かず、コマンド実行後、すぐにコミットされる。
直前commitの修正
$ git commit --amend
で、直前のコミットをやり直せます。ただし、コミットIDは、変わるので注意。
こちらは、エディタが開く。
追加すべきファイルを追加し忘れた時などに使う。(よく追加し忘れる。)
ファイルの追加や、修正があった場合、先に、addしてからcommit --amend
する。
コメントの修正などは、
$ git commit --amend -m コメント
とする。
こちらはエディタが開かれない。
log
$ git log
現在いるブランチのcommitログをみる。
CommitIDを調べたり、どんなブランチかを調べるのに使ってる。
push
$ git push origin プッシュするブランチ名
ローカルのブランチを、リモートに反映する。(この場合、origin)
・リモートに、同じブランチ名のブランチがない場合は、新しく同じ名前のリモートブランチが作成される。
・リモートに、同じブランチ名のブランチがある場合で、そのリモートのブランチが先に進んでいた場合、エラーになる。
この場合、プッシュ前に、そのリモートブランチをpull (fetch+merge)
してくる必要がある。
・リモートに、同じブランチ名のブランチがある場合で、そのリモートのブランチが先に進んでいなかった場合は、そのままプッシュされる。
・リモートに、同じブランチ名のブランチがある場合で、そのリモートのブランチに自分の権限が無かった場合、エラーになる。
その場合は、管理者に訴えるかあきらめる。 別の名前のブランチとしてプッシュし、PullRequestを出して、管理者にマージしてもらう。
別名のブランチとしてプッシュする
$ git push origin プッシュするブランチ名:リモートでのブランチ名
上記のように、プッシュするローカルブランチ名の後に、:
に続けて、リモートでのブランチ名を指定できる。
ただ、ローカルと、リモートでブランチ名変わって分かりづらい&ミスり易いのでお勧めしない。応急処置のためだけにしておいたほうがいいかと。
rebase
$ git rebase リベース先ブランチ名
現在いるブランチの親を変える。枝分かれの元を変える。
この場合、リベース先のブランチとの差分コミット全てがリベースされる。
リベースしたコミットは、全てCommitIDが変わるので注意。
-iオプション
$ git rebase -i リベース先ブランチ名
-i
をつけることで、リベースするコミットを選べる。
このコマンドを実行すると、エディタが開く。
エディタでは、
- リベースするコミットの選択
- リベースするコミットのコメント修正
- リベース時に直前のコミットと融合するコミットの選択
等が行える。(他にもあるが、使ったこと無いのでわからない。)
自分は、rebase
は、機能単位でブランチを切ってPullRequestを出す時に、
masterにリベースする感じでよく使う。
あとは、適当に名前つけて段階的にcommit
したものを、まとめたり、コメント変えたりするのに使っている。
リベースは、コミットログを大きく変えるので、基本的に、リモートにプッシュしたあとのブランチでは、行わないように気をつける。(自分しか関係ないならいいが...)
リベース時に、競合が発生することもあるので注意。
競合解決後、rebaseを再開するには、
$ git rebase --continue
「やっぱリベースやめよ」となったら
$ git rebase --abort
merge
$ git merge マージするブランチ名
現在いるブランチに、別のブランチのcommitを取り込む。
commit単位での取り込みならgit pick
があるが、あちらは、CommitIDが変わるので注意。
こちらmerge
は、基本的に、CommitIDはそのまま。
マージするブランチ同士で、変更点に競合が無ければ、無事自動マージされる。
変更点に競合があれば、残念。mergeが途中で止まり、
競合を解決したのち、
$ git merge --continue
で、mergeを再開する。
「競合したわ。マージやめよ(白目)」ってときは、
$ git merge --abort
競合の解決
競合(コンフリクト)したファイルを編集し、競合を消してから、
add
してcommit
。
ちなみに、自分は、
$ git config --global alias.conflicts '!git ls-files -u | cut -f 2 | sort -u'
として、
$ git conflicts
で、競合したファイルの一覧を表示できるようにしている。
(よく競合したファイルがわからなくなるので。)