Open13
git ブランチ操作 ケース
過去のコミットに戻したい
過去のコミットに戻したいとなった場合に以下のパターンがあると思われる。
- 一時的にあるコミット時点の状況を再現したい。
- HEADをブランチ内の時系列をあるコミット時点に戻したい。
- 特定の範囲(単数、または複数のコミット)の変更を取り消して前の状態に戻したい。
git revert
git reset
git patch & git apply
-
複数のコミットを一つのパッチファイルにまとめて出力したい
=> --stdoutオプションを使えば良い? -
範囲指定ではなく飛び飛びのコミットを指定してパッチ出力したい
=> rebaseでコミットをひとまとめにしてからパッチ出力するのが現実的?
- 異なる地点からパッチを作成する
https://stackoverflow.com/questions/31733081/how-do-i-make-a-git-patch-from-multiple-commits-at-different-points-in-history
=> パッチの作成は飛び飛びの任意のコミットを選択することができないが、cherry-pickは飛び飛びのコミットを反映することができる。
git cherry-pick commit1 commit2 commit3
マージの取り消し
- ローカルブランチからローカルブランチへのマージを取り消したい
- リモートブランチからリモートブランチへのマージを取り消したい
- リモートブランチからローカルブランチへのマージを取り消したい
ブランチをマージしたい
- ローカルのdevelopブランチにリモートのdevelopブランチの最新を取り込みたい
- ローカルのfeatureブランチにリモートのdevelopブランチの最新を取り込みたい
- ローカルのfeatureブランチからローカルのfeatureブランチを取り込みたい
履歴をひとまとめにしてマージしたい(スカッシュマージ)
ブランチ内の一部のコミットをマージしたい(チェリーピック)
git cherry-pick
ブランチを綺麗にしたい
1機能開発ごとのブランチをひとまとめにしたい
- featureブランチに切って開発してマージする
- rebaseで同一の機能開発に関するコミットを統合する
gitでコンフリクトが発生した際に、コンフリクトが発生する前に戻りたい。
以下のようにコンフリクトが起きた際に、コンフリクトを起こしたアクションを取り消したい。
結論
git [取り消したいコマンド] --abort
か
git reset --merge
が上手くいった。
そもそも今回は
hint: To abort and get back to the state before "git cherry-pick",
hint: run "git cherry-pick --abort".
と表示されていたので指示通りに「git cherry-pick --abort」を実行しろという話だった。
解決するまでにハマったこと
例えばマージによるコンフリクトであれば原因となったマージのアクションを、以下のようにcherry-pickであればcherry-pickを取り消したい。
- コンフリクトの発生
>> git cherry-pick [対象コミットのSHA-1]
Auto-merging src/xxx.php
CONFLICT (content): Merge conflict in src/xxx.php
hint: After resolving the conflicts, mark them with
hint: "git add/rm <pathspec>", then run
hint: "git cherry-pick --continue".
hint: You can instead skip this commit with "git cherry-pick --skip".
hint: To abort and get back to the state before "git cherry-pick",
hint: run "git cherry-pick --abort".
- git statusで確認すると検知されたコンフリクトが解消されずにマージされていないステータスとなっている。
>> git status
On branch update-231207
Unmerged paths:
(use "git restore --staged <file>..." to unstage)
(use "git add <file>..." to mark resolution)
both modified: src/xxx.php
Untracked files:
(use "git add <file>..." to include in what will be committed)
0004-.patch
no changes added to commit (use "git add" and/or "git commit -a")
- git merge --abortを実行すると「MERGE_HEAD ファイルが見つからない」、つまりGitがマージ操作中であると認識していないと怒られる。
git merge --abort
fatal: There is no merge to abort (MERGE_HEAD missing).
- reset soft を実行すると「マージの最中だからソフトリセットできません」と言われる。
3もあったので「マージ中と認識していないのにマージの最中ってどうなってんねん...」と思った。
>> git reset --soft xxxxxx
fatal: Cannot do a soft reset in the middle of a merge.
--abort と --quitの違い
マージコミット作成 VS スカッシュマージ
- スカッシュのマージ
hint: You have divergent branches and need to specify how to reconcile them.
hint: You can do so by running one of the following commands sometime before
hint: your next pull:
hint:
hint: git config pull.rebase false # merge
hint: git config pull.rebase true # rebase
hint: git config pull.ff only # fast-forward only
hint:
hint: You can replace "git config" with "git config --global" to set a default
hint: preference for all repositories. You can also pass --rebase, --no-rebase,
hint: or --ff-only on the command line to override the configured default per
hint: invocation.
指定したファイルだけある変更点の直前に戻す
指針
- cherrypickコマンドを使って、あるファイルの取り消したい変更のコミットの直前のコミットを現在のブランチに適用する。
git cherrypick <commit-hash>
指定したコミットハッシュの内容を現在のブランチに取り込む。
-
最終的にmainブランチに取り込む変更作業用のブランチを作成
-
戻したい状態が含まれるコミットを一時的に別ブランチに切り出す。
git checkout -b temporary-branch <commit-hash>
3. 2の一時ブランチにて対象のファイル以外を削除する
git rm --cached <file-to-ignore>