mvした後にうっかりコミットをし忘れてしまうことってありますよね。ここにも書いてあるように、mvした状態で一度renameコミットを作らないとあとで歴史を辿れない場合があります。
ここではmvしたあとに変更してしまった状態で、変更を失わずにrenameのコミットのみ作る方法を紹介します。
前提
$ ls
a
$ git status
On branch master
nothing to commit, working tree clean
$ mv a b
$ ls
b
$ echo "modified" >> b
$ git status
On branch master
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git checkout -- <file>..." to discard changes in working directory)
deleted: a
Untracked files:
(use "git add <file>..." to include in what will be committed)
b
no changes added to commit (use "git add" and/or "git commit -a")
ファイルa
をb
にリネームし、更に変更をしています。
解決策1
$ git add b
$ git stash
$ git status
On branch master
nothing to commit, working tree clean
$ mv a b
$ git commit -m 'rename a to b'
$ git stash list
stash@{0}: WIP on master: 90d4e0c first
$ git checkout stash@{0} .
$ git status
On branch master
Changes to be committed:
(use "git reset HEAD <file>..." to unstage)
modified: b
こんな感じです。
ちなみに普通にgit stash pop
しようとすると以下のようなエラーになります。
$ git stash pop
CONFLICT (rename/delete): b deleted in Stashed changes and renamed in Updated upstream. Version Updated upstream of b left in tree.
$ git status
On branch master
Unmerged paths:
(use "git reset HEAD <file>..." to unstage)
(use "git add <file>..." to mark resolution)
added by us: b
no changes added to commit (use "git add" and/or "git commit -a")
また、checkoutするのではなくてrm b
した後にgit stash pop
してもCONFLICTせずにmergeできます。(こちらの方法のほうがstash履歴が残らずきれいかもですね)
まとめ
- リネームと変更のコミットを後から分けたければ、
- git stash
- mv
- commit
- checkout stash@{0} .
もっと良い方法があればおしえてください。