Gitチェックアウト、ブランチ関連のメモ

Git ブランチ操作

ブランチの一覧表示

> git branch
* master
  branch1

ブランチの切り替え

既存のブランチに切り替える

> git checkout branch1
Switched to branch 'branch1'

ブランチを新規作成し、同時に切り替える。すでに存在する場合、
エラーになる

> git checkout -b b001
Switched to a new branch 'b001'

不要になったブランチの削除

マージ済みの場合は、-dオプションで削除できる。
マージされてないブランチを強制削除する場合は-Dを使用する。

> git branch -d "branch1"

ファイル編集中にブランチを切り替えるとどうなるのか?

編集状態 ブランチの切り替え (git checkout)
管理外ファイル (untracked files) 残ったまま切り替わる
git addされたファイル (一度もコミットされてないファイル) インデックス領域にaddされたまま切り替わる。そのままコミットすると、アクティブブランチにコミットされる
コミット済みファイル 切り替え先のブランチに存在しないものは、ワーク領域から削除される
git addされたファイル (コミットされているファイル) エラーになり、切り替わらない。git stashで一時的に退避すれば可能
not stagedファイル (コミットされているファイル) エラーになり、切り替わらない。git stashで一時的に退避すれば可能

ブランチ関連のトラブル対処まとめ

ワーキングディレクトリのファイルの内容を破棄して元に戻したい。手で削除したファイルを復活させたい。

ステージの内容で復元してもいいなら、以下で良い。

> git checkout .
> git checkout <file name>

git addされた内容も破棄するのであれば、リポジトリからチェックアウトする。
ステージの内容とワーキングディレクトリの内容はHEADの内容で上書きされる。

> git checkout HEAD .
> git checkout HEAD <file name>

ファイルを管理するためにgit addしたが、余計なファイルも混入していた。ワーキングには残したまま、addだけを取り消したい

git resetを使用して、インデックスの内容をHEADで上書きする。

> git reset HEAD <file name>

本来ブランチを作成してから作業開始すべきところ、masterブランチでファイルを追加してしまった。

一度もコミットしていないのであれば、そのままブランチの作成および切り替えすればよい。

> vi newfile.txt
> git add newfile.txt

> git checkout -b branch1
A     newfile.txt
Switched to a new branch 'branch1'
> git commit -m "add newfile.txt"
 1 file changed, 1 insertion(+)
 create mode 100644 newfile.txt

masterブランチに直近で2回コミットした内容を、branch2を作成して、branch2のコミットに変更したい。

以下のようなケースで、本来newlfile1.txtをbranch2で追加して作業するところを、うっかりmasterブランチで作業してしまったケース。
最後の9d0b65eb4c0242をmasterからbranch2に移動することが目的。

> git log --oneline --decorate --graph master branch1
* b4c0242 (HEAD -> master) modified newfile1.txt
* 9d0b65e add newfile1.txt
* 900ae21 add abc2.txt
* 8bb3e73 add abc1.txt
| * ef9f8e8 (b001) modified xxx.txt
| * 45b649d create branch1
|/
* 1740fee add xxx.txt
* ef29be9 initial commit

まず分岐したいところにブランチを作成する。"add newfile1.txt"以降をブランチに移動したいので、
その前900ae21に対してブランチを作成する

> git branch branch2 900ae21
> git log --oneline --decorate --graph master branch1 branch2
* b4c0242 (HEAD -> master) modified newfile1.txt
* 9d0b65e add newfile1.txt
* 900ae21 (branch2) add abc2.txt
* 8bb3e73 add abc1.txt
| * ef9f8e8 (branch1) modified xxx.txt
| * 45b649d create branch1
|/
* 1740fee add xxx.txt
* ef29be9 initial commit

branch2に切り替えて、git cherry-pickコマンドでコミット内容をコピーする

> git checkout branch2
> git cherry-pick 9d0b65e

[branch2 b06a7bc] add newfile1.txt
 Date: Tue Feb 28 21:21:05 2017 +0900
 1 file changed, 1 insertion(+)
 create mode 100644 newfile1.txt

> git cherry-pick b4c0242

[branch2 4796fd4] modified newfile1.txt
 Date: Tue Feb 28 21:21:39 2017 +0900
 1 file changed, 1 insertion(+)

ここまでで、ツリーの状態は以下のとおり。同じコメントの履歴がbranch2に複製された状態になっている。
ワーク領域にもファイルが生成されていることを確認できる。

* 4796fd4 (HEAD -> branch2) modified newfile1.txt
* b06a7bc add newfile1.txt
| * b4c0242 (master) modified newfile1.txt
| * 9d0b65e add newfile1.txt
|/
* 900ae21 add abc2.txt
* 8bb3e73 add abc1.txt
| * ef9f8e8 (branch1) add xxx.txt
| * 45b649d branch branch1
|/
* 1740fee add xxx.txt
* ef29be9 initial

masterブランチの直近の2つのコミットは不要になったので削除する。

> git checkout master
> git reset --hard HEAD~2
HEAD is now at 900ae21 add abc2.txt

作業完了後のツリーは以下のとおり

> git log --oneline --decorate --graph master branch1 branch2

* 4796fd4 (HEAD -> branch2) modified newfile1.txt
* b06a7bc add newfile1.txt
* 900ae21 (HEAD -> master) add abc2.txt
* 8bb3e73 add abc1.txt
| * ef9f8e8 (branch1) add xxx.txt
| * 45b649d branch branch1
|/
* 1740fee add xxx.txt
* ef29be9 initial