1. gitの基礎(言葉の意味)
- ワーキングツリー[working tree]:最新のファイルの状態
- インデックス[index](ステージ[stage]):コミットするためのファイルの状態
- ローカルリポジトリ[local repository]:ファイルの変更履歴を記録(手元で管理)
- ヘッド[HEAD]:最新のコミットの状態
- リモートリポジトリ[remote repository]:ファイルの変更履歴を記録(みんなで共有)
- add:「ワーキングツリー → インデックス」への反映
- commit:「インデックス → ローカルリポジトリ」への反映
- push:「ローカルリポジトリ → リモートリポジトリ」への反映
2. git resetを使いこなす
git resetには--hard、--mixed、--softの3つのオプションがある。
※厳密にはもっとあります。詳しくは`git reset -h`を叩くなどして見てください。
それぞれのオプションにおいて、修正の及ぶ範囲は下記。
-
--hard:「HEADの位置・インデックス・ワーキングツリー」全て -
--mixed(or オプション無し):「HEADの位置・インデックス」 -
--soft:「HEADの位置」のみ
- ファイルを変更したらワーキングツリーが変更
- addしたらインデックスが変更
- commitしたらHEAD( = 最新のコミットのハッシュ値のエイリアス)が1つ前に進む
-
reset --hard:全部Yに戻す。 -
reset --mixed:commitとaddの取り消し。 -
reset --soft:commitのみ取り消し。
★主な利用シーン★
① 直前のコミットを取り消したい(コミットのみ取り消し)
git reset --soft HEAD^
-
HEAD^:直前のコミットを意味する。-
@^、HEAD~も同じ意味。 -
HEAD~{n}:n個前のコミットを意味する。 -
HEAD^やHEAD~{n}の代わりにコミットのハッシュ値を書いても良い。 - gitのv1.8.5からは、「
HEAD」のエイリアスとして「@」が用意されている。 -
HEAD^^^とHEAD~3とHEAD~~~とHEAD~{3}と@^^^は同じ意味。
-
-
--softなので、インデックス・ワーキングツリーはそのまま。 - 上書きコミットしたいなら、
git commit --amendを使うとラク!
② 直前のコミットを取り消したい(マルっと消したい)
git reset --hard HEAD^
-
--hardなので、「インデックス・ワーキングツリー」も1つ前のコミットの状態に戻る。
③ コミット後の変更を全部消したい
git reset --hard HEAD
-
--hardなので、「HEADの位置・インデックス・ワーキングツリー」を全てHEADの位置に動かす。-
HEADの位置はそのまま。 - 「インデックス・ワーキングツリー」の変更が消せる。
-
④ addを取り消したい
git reset --mixed HEAD
または、
git reset HEAD
-
--mixed(or オプション無し)なので、「HEADの位置・インデックス」をHEADの位置に動かす。-
HEADの位置はそのまま。 - 従って、インデックスの変更(addした内容)のみ元に戻す。
-
⑤ すごい昔の状態で動作を確認したい
git reset --hard 昔のコミットのハッシュ値
- これをやる前に、
pushして置くことを強くオススメします! -
reset --hardは基本的にすべて消えるので慎重に。- 一応復活させる術はなくはない。
-
remoteに最新の状態を記録しておけば、ローカルは好きな所に移動しても安心。 - コミットのハッシュ値は
git logで確認すればOK!
動作確認後、最新の状態に戻るには、また、
git reset --hard ORIG_HEAD
をすれば良い。
-
git reset --hard ORIG_HEAD:直前のresetをなかったことにするおまじない! -
git resetは未来の状態にも行ける。 -
git reset --hard 最新のコミットのハッシュ値でも良い。 -
git rebase origin/masterでも良い。- rebaseで何か問題が起きたら下記参照。
- http://qiita.com/shuntaro_tamura/items/c505b76c1021a35ca9ff
-
reset --hardやrebaseする時は、こまめにソースツリーの状態を確認しておくといいと思います。
3. 間違えてgit resetしちゃったら・・・
直前のリセットを取り消したいなら、
git reset --hard ORIG_HEAD
をすればOK!
reset後色々いじってしまっていたら、慌てずに、git reflogコマンドを叩きましょう。
-
git log:コミットの履歴を見る -
git reflog:これまでHEADが辿ってきた履歴を見る
git reflogで戻したい状態を見つけ出し、
git reset [(必要なら)オプション] [ハッシュ値]
をすれば良い。
resetで困ったときは「reset&reflog」と覚えておこう!
(注) reflogは万能ではない
git reflogは、「これまでHEADが辿ってきた履歴」を保持しているものです。
addしただけでcommitしてないものがある時に、reset --hardをしてしまったら、addした内容は復元不可能です。
addすらしてないものももちろん消えます。
-
git resetを使うときはくれぐれも慎重に!
4. おまけ(gitを使いやすくする)
① ローカルの変更内容を一時的に退避させる。
git stash
退避させた内容を元に戻すには、下記を叩けばOK!
git stash pop
- その他
stash系コマンドは下記参照。 - http://kentana20.hatenablog.com/entry/2014/07/05/172717
② aliasを作成
gitのaliasは~/.gitconfigに書き込むことが可能。
vim ~/.gitconfig
[alias]
ad = add
br = branch
ci = commit
co = checkout
ft = fetch
pl = pull
ps = push
sh = show
st = status
ただ、個人的にはgitを打つのも面倒なので~/.bashrcにgit系のaliasも書いている。
vim ~/.bashrc
# git
alias g='git'
alias gb='git branch'
alias gs='git status'
alias gd='git diff'
alias gds='git diff --staged'
alias ga.='git add .'
alias gcm='git commit -m'
alias gcam='git commit -am'
alias gpod='git push origin develop'
alias gp='git push'
alias gfo='git fetch origin'
alias grod='git rebase origin/develop'
alias gsp='git stash pop'
alias gsu='git submodule update --init --recursive'
alias gcd='git checkout develop'
alias gmnf='git merge --no-ff'
masterを直接いじることをせずdevelopブランチ切ることが多いため、上のようなaliasにしている。
あと、運用方法の好みとして、pullせずrebaseする風潮が自分のまわりであるので、gpでpushの意味も持たせてしまっている。
③ その他
▼git rebase 失敗した時の対処法
http://qiita.com/shuntaro_tamura/items/c505b76c1021a35ca9ff
▼Gitで補完機能を有効にする方法
http://qiita.com/shuntaro_tamura/items/9ed9321e64dc208fe95a
▼ファイルの変更履歴を行単位(orコミット単位)で調べる方法
http://qiita.com/shuntaro_tamura/items/b8b99a9b4987144581e9
▼コミットの取り消し、打ち消し、上書き
http://qiita.com/shuntaro_tamura/items/06281261d893acf049ed
▼ブランチ切って更新してマージするまでの流れ
http://qiita.com/shuntaro_tamura/items/6c8bf792087fe5dc5103
▼初心者のためのgitコマンド
http://qiita.com/shuntaro_tamura/items/5228a29082a844d4875c
▼【Gitおすすめサイト1】サルでもわかるGit入門
http://www.backlog.jp/git-guide/
▼【Gitおすすめサイト2】Git公式ドキュメント
http://git-scm.com/docs/




