TT Lab
Get started
Learn Learning paths Courses

Git in Practice

Nothing to Merge, Says Git, About the Feature You Just Reverted

Continue in TT Lab

Goal

You revert and revive a merge commit, and bring over a release branch fix while leaving its source. And you also check how a machine decides what has already gone in.

Why it matters

reset deletes commits and revert adds a reversing commit. For history that has already gone to other people you can use only revert, but with a merge commit that reversal is not simple. Because there are two parents, a person has to say which side's state to go back to. And what comes after the revert matters even more — merge judges by the reachability of the history, so even if you merge the reverted feature again, it answers "there is nothing to merge". If you do not know these two things, you lose 30 minutes in the same place during incident response. The last two steps are the basics of running backports. You build for yourself the fact that whether the same change is already in is decided not by the hash but by the patch-id, and that a commit brought in after resolving a conflict drops out of that verdict.

Steps

  1. Create at /root/gitx7/repo a history that has a merge commit and a release branch.
  2. Try to revert the merge commit without -m, leave the refusal message in notes/revert-m.txt, and then revert it with -m 1.
  3. Write what git merge feature answers in notes/reland.txt, and revive the feature by reverting the revert.
  4. With -x, bring the release's hotfix commit into main.
  5. When bringing in the release's configuration change commit, if it conflicts, back out with --abort, then do it again and finish with --continue. Leave the process in notes/conflict.txt.
  6. Leave the result of git cherry -v main release in notes/cherry.txt.
  7. Write the patch-ids of the original and the brought-in commit side by side in notes/patchid.txt.
  8. Summarize in notes/report.md when to use what.

Notes

A history with a merge commit and a release branch

Create at /root/gitx7/repo a history that has a merge commit and a release branch.

Commit the basic files on main, on a feature branch add feature.txt and modify the second line of app.txt, and then merge with --no-ff. At that point branch off release, stack three commits there (a hotfix, a configuration change and a release note), go back to main and modify the same configuration value differently. This last one creates the conflict in step 5.

A merge commit must say which side to go back to

Try to revert the merge commit without -m, leave the refusal message in notes/revert-m.txt, and then revert it with -m 1.

Find the merge commit hash with git rev-list --merges main. If you simply run git revert <해시>, it is refused — keep that line as it is. Also write what -m 1 means it takes as the base, and revert without an editor by adding --no-edit.

Even if you merge again, there is nothing to merge

Write what git merge feature answers in notes/reland.txt, and revive the feature by reverting the revert.

Just try git merge feature. It answers in one line. Write why it answers that way — merge judges not by content but by the reachability of the history. The way to revive it is to git revert the revert commit you just made.

Bring it in while leaving the source

With -x, bring the release's hotfix commit into main.

Find the hash of the release commit that added hotfix.txt with git rev-list release -- hotfix.txt. If you run git cherry-pick -x <해시>, one line is appended at the end of the new commit message. Check with git log -1 --format=%B.

If it conflicts, back out and come again

When bringing in the release's configuration change commit, if it conflicts, back out with --abort, then do it again and finish with --continue. Leave the process in notes/conflict.txt.

The release commit that modified conf.txt conflicts if you git cherry-pick it. First, with git status --short, look at UU and cleanly back out with git cherry-pick --abort. Then bring it in again, fix conf.txt to the value the release decided, git add it, and finish with GIT_EDITOR=true git cherry-pick --continue. Be sure to check that no conflict marker lines remain in the file.

Count what has already gone in

Leave the result of git cherry -v main release in notes/cherry.txt.

git cherry -v <upstream> <head> judges by patch-id whether each commit of head is already in upstream. - means it is there and + means it is not. Of the three commits, only one comes out as -, and you must write why the one brought in after resolving a conflict is +. That is where this tool's limit lies.

The hashes differ but the patch-ids are the same

Write the patch-ids of the original and the brought-in commit side by side in notes/patchid.txt.

git show <커밋> | git patch-id --stable outputs two values — the first is the patch-id and the second is the commit hash. The commit brought in with -x in step 4 has the same patch-id as the original. You can find that commit with git log --grep 'cherry picked from commit <해시>'.

When to use what

Summarize in notes/report.md when to use what.

Write five chunks: the question that separates reset from revert, the -m when reverting a merge commit, why you use a revert of the revert and not merge when reviving, why you make -x a rule, and the limits of the patch-id verdict.