Git と Visual Studio 2017 その 15 : ローカルコミットの修正
前回の記事ではソリューションをリモートに共有後、コミットを取り消す方法を説明しました。今回はプッシュする前にローカルのコミットを修正する方法を見ていきます。
コミットの修正 : Git
既に --amend オプションで最新のコミットにアイテムを追加したりコメントを修正する方法は説明しました。しかし 1 つのコミットを複数に分割したり、複数のコミットを 1 つのコミットにまとめるといった高度な修正はどうやるのでしょうか。早速見ていきましょう。
複数のコミットを 1 つにまとめる (squash)
1. ‘git log --oneline --graph –all’ で現在の状況を確認。ローカルには master と dev 、リモート追跡ブランチとして master が存在。
2. ‘echo “編集 1” >>README.md’ and ‘git commit -am “編集 1 を追加”’ を実行して master ブランチでコミットを追加。
3. 同様にもう 2 つコミットを追加。
4. ‘git log --oneline --graph --all’ を実行して履歴を確認。
5. 最後の 3 つのコミットを 1 つにまとめるため、‘git rebase -i d2badd7’ を実行。-i は --interactive の省略。リベースは別のブランチの変更を現在のコミットの前に適用するコマンドだが、同じブランチで使うと、コミットの中身をやり直すことが可能。d2badd7 を起点にそれ以降のコミットを再実行。コミットの再実行を指定するためにエディタが起動。
6. 文字化けを直すため、’:’ をタイプ後、’set encoding=utf-8’ を実行。Enter を押下すると文字化けが直る。
7. コミットの前の文字列を、ヘルプを参照に変更。以下の場合はじめのコミットはそのまま、残りの 2 つははじめのコミットに統合 (squash) することを指定してからファイルを保存。
8. 次にコミットコメントを変えるための編集画面が起動するので、必要に応じてコメントを編集。ここではそのまま保存。
9. ‘git log --oneline --graph –all’ で履歴確認。コミットは 1 つになっている。
10. ‘git log -1’ で最後のコミットだけ表示。コミットコメントも意図したものとなっている。
11. Vim が起動するたびに encoding を設定したくない場合、’echo set encoding=utf-8 >> c:\Users\kenakamu\.vimrc’ のコマンドでユーザーレベルの設定を作成可能。
コミットの順序変更や削除 Remove or change commits order
1. ‘git reset --hard 4b68b8d’ と ’git rebase -i d2badd7’ でリベースを再実行。
2. 以下のように変更するとコミット 2 は削除、コミット 1 と 3 の順序を変更。
3. 競合が発生するため、‘git mergetool’ で競合を解消。
4. 競合解消後、‘git rebase --continue’ で続行。コミットコメント編集画面が開くので、必要に応じて保存。
5. 自動的に次のコミットを実行するが再度競合発生。’git mergetool’ で修正するとコメント編集画面が出る。任意に編集して保存して再度 ‘git rebase --continue’。適用が終わると完了。
6. ‘git log --oneline --graph --all’ で確認。
コミットの分割
最後にコミットの分割をやってみましょう。
1. ‘git rebase -i d2badd7’ でリベースを再実行。今回はコミット 3 だけを分割し、コミット 1 は削除。
2. Git は初めのコミット 3 が edit 指定されているため一旦ストップ。
3. ‘git log --oneline’ で状況確認。既に ”編集 3” のコミットは作成済。そのため ‘git reset HEAD~1’ を実行。
4. ‘git add -p README.md’ で README.md でファイルを行単位でコミット。
5. “e” をタイプして、より詳細を変更。
6. 以下のようにファイルを変更して、編集 1 の行だけコミット。
7. ’git diff --cached README.md’ でステージされたファイルとコミットの比較。
8. ‘git commit -m “編集 1 の追加”’ を実行してコミット。同様に残りの 2 行も個別にコミット。
9. コミットが終わったら、‘git rebase --continue’ でリベースを続行。今回残りのコミットは drop を指定したためこれで完了。
10. ‘git log --oneline --graph --all’ でコミット履歴を確認。
rebase -i 時の他の選択肢
今回見た、pick、edit、drop、squash 以外にも選択肢はあります。詳細はこちら。
コミットの修正 : VS
Visual Studio 2017 ではインタラクティブリベースに相当する機能がありませんでした。必要に応じてコマンドラインで実行することになります。
まとめ
リベースでローカルコミットの履歴を書き換える手段は、初め少し混乱するかもしれません。またリモートのプッシュ後は実施しないことをお勧めします。ただこの機能があるおかげで、気軽にローカルコミットをしておき、後で整理する運用を個人的には採用できるようになり、便利になりました。実際 Git はすぐにコミットを削除するわけではないため、無駄な Git オブジェクトが増えていきますが、そのうちガベージコレクションが動作してクリアしてくれるはずです。次回は問題を特定するためのデバッグ手法について見ていきます。次の記事へ
中村 憲一郎