1つのプルリクエストには、1つの意味だけを持たせるべきだ。
プルリクエストを作成後、今回のプルリクエストに関係のない修正が紛れ込んでいたことに気づいた。やるべきことは、ブランチを正しい状態にすること。
プルリクエストは GitHub上のリモートブランチに紐づいているので、プルリクエスト自体の修正などは必要ない。ここ、勘違いしていた。
具体的な状況
- img_upload ブランチを作って、画像アップロード機能を追加する1つのコミットを作った
- img_upload ブランチをプッシュ
- GitHub 上でプルリクエスト作成
- GitHub 上で Files changed を確認していたら、画像アップロードに関係のない修正(プルリクエストを分けるべきもの)までしていたことに気づいた
変更手順
reset --soft を使う
今回実際にやった方法。
- ローカルの img_upload ブランチで
$ git reset --soft HEAD^
して、コミット直前の状態に戻す - 今回のプルリクエストに入れない部分を元に戻す
- 手を加えたファイルを
add
- コミット
$ git push --force-with-lease origin img_upload
でリモートブランチを上書き
reset を使う
--soft
をつけなかったらこうなる。ほとんど変わらないけど。
- ローカルの img_upload ブランチで
$ git reset HEAD^
して、コミット前の状態に戻す(ステージしていない状態) - 今回のプルリクエストに入れない部分を元に戻す
- コミットするファイル全部を
add
- コミット
$ git push --force-with-lease origin img_upload
でリモートブランチを上書き
--amend を使う
Gitのドキュメントを見た感じだとこれが一番いいかもしれない。「5. $ git push --force-with-lease origin img_upload
でリモートブランチを上書き」以外の部分について練習リポジトリを作ってやってみた。
想定シーン
- master ブランチに
hello.txt
というファイル(中身は空)が1つだけある hello.txt
をadd
してcommit
(initial commit)hello.txt
にHello!
を書き込んでコミット(second commit)- second commit に、新しいファイル
new.txt
も入れておくべきだったと気づく
# リポジトリの初期化 $ git init # hello.txtを作ってaddしてcommit $ touch hello.txt $ git add hello.txt $ git commit -m 'initial commit' # hello.txtに"Hello!"を書き込んでaddしてcommit $ echo 'Hello!' > hello.txt $ cat hello.txt Hello! $ git add hello.txt $ git commit -m 'second commit' # ここまでのログを確認 $ git log --oneline 5f2b8a6 (HEAD -> master) second commit 30ad88e initial commit # second commitに入れておくべきだったファイルを作ってadd $ touch new.txt $ git add new.txt # commitのやり直し $ git commit --amend # コミットメッセージを入力するためエディタが立ち上がる #(やり直すコミットのメッセージが入力されている)=> 保存 # hello.txtへの修正が反映されているか確認 $ cat hello.txt Hello! # ログ確認(second commitのハッシュは変わる) $ git log --oneline 7512bf9 (HEAD -> master) second commit 30ad88e initial commit
フォースプッシュ
あるブランチですでにプッシュしたコミットがあると、それを取り消したりして矛盾があるプッシュは受け付けてもらえない。そこで必要となるのが、フォースプッシュ(強制プッシュ)。
$ git push -f origin branch_name $ git push --force origin branch_name
フォースプッシュは強制的にリモートリポジトリを上書きするため、かなり注意して使う必要がある。チーム開発では以下のようにすることが多い。
$ git push --force-with-lease origin branch_name
--force-with-lease
オプションをつけておけば、自分が最後にプッシュした後にリモートブランチに変更があるとプッシュができない。他の人の変更履歴を意図せず消してしまう事態を防げる。