0

I'm lacking some fundamental understanding of git revert and the commit history here. Reproducible example:

mkdir git_test
cd git_test
git init
touch test.txt
echo "asdf" >> test.txt
git add test.txt
git commit -m "added file"
echo "asdf2" >> test.txt
git add -u
git commit -m "added another line in main"
git checkout -b feature
echo "asdf3 in feature" >> test.txt
git add -u
git commit -m "added a third line in feature"
echo "asdf4 in feature" >> test.txt
git add -u
git commit -m "added 4th line in feature"
git checkout master
echo "adding line 3 in main" >> test.txt
git add -u
git commit -m "added line 3 in main"

I have two branches, feature and master (which I call main above, sorry)! Now I can merge feature into main, and resolve conflicts:

git merge feature # accept incoming changes in conflict
git add -u
git commit -m "merge feature into main"

git log --oneline

If I regretted this merge I can do git revert -m 1 be62f73. Since this is mimicking a public branch, I don't want to do a git reset.

So, this works alright, but normally I can't merge anything directly into master, so I'd have to create a PR, where I'd have to first merge master into feature instead:

git checkout feature
git merge master # accept currenct changes in conflict
git add -u
git commit -m "merge master into feature"
git checkout master
git merge feature

git log --oneline number 2

If I now try git revert -m 1 225747f I get Already up to date! On branch master \n nothing to commit, working tree clean.

So, why can't I revert it in the second instance? There must be some fundamental concept I'm not understanding here? If HEAD is a merge commit, what does HEAD really contain? What does it mean to revert a merge commit? When I merge two branches, isn't the merge commmit just signaling that "here some merge happened", but the commits from the other branch is mixed into the commit history? If I regretted a merge of feature into master, is there a way of regretting just parts of the commits that were moved from feature, instead of caring about the actual merge commit? I really don't understand how this merge commit relates to regular commits that is incoming into the new branch when merging.

EDIT: adding a screenshot to show that the last commit that I can't revert, actually is a merge commit: merge commit

  • 1
    225747f is not a merge commit. Your branches master and feature are the same branch. That would not happen after a true merge. Looks like you did a fast forward. Instead of `git merge feature` at the end, say `git merge feature --no-ff` – matt Mar 24 '23 at 11:51
  • But also in general reverting a merge commit is tricky because it does not undo the merge. See the link I provide at https://stackoverflow.com/a/69860099/341994 – matt Mar 24 '23 at 11:55
  • @matt well, I did a `git merge ...`, so how can it not be a merge? Git does say `Updating 4b3ed25..225747f Fast-forward`, though, so you are right there! – Berthrand Eros Mar 24 '23 at 12:07
  • @matt thanks for the link, I will try to read and understand. when you are saying in your answer that the topology remains, you mean that the commit you want to revert is already in the branch history - so when you try to merge back this commit in later (after you reverted it), git will see that this commit is already here, so just ignore it, correct? and so your revert will always "counteract" that commit, correct? – Berthrand Eros Mar 24 '23 at 12:11
  • "well, I did a git merge ..., so how can it not be a merge?" Because a fast forward is _not_ a merge. It's a hard reset. And that is why there is nothing to revert. — There are lots of things you can do with the `git merge` command that are not in fact merges. Fast forward is one. Squash is another. What base command you used and what resulted are very different things! – matt Mar 24 '23 at 12:19
  • @matt oh, I see, you are saying that a fast forward is just moving the pointer to a different commit? So the "merge commit" of a fast forward will always be "empty" when I do a `git show merge commit hash`, whereas for a proper merge commit it will display the changes necessary for the branches to be merged (conflict handling)? – Berthrand Eros Mar 24 '23 at 12:35
  • There are no merge commits for a fast-forward merge. Only the branch label is moved. No additional commits are added to your repository. The HEAD commit after a fast-forward merge will be a regular commit with regular changes (it will be the latest commit of your branch) – knittl Mar 24 '23 at 12:36
  • @knittl well, take a look at my `git show` screenshot of that commit hash that you say is no merge (bottom of the Q), and a regular commit. Why does it have two parents? Are you sure about this? – Berthrand Eros Mar 24 '23 at 12:41
  • @BerthrandEros it looks like your mainline is the second parent commit, not the first. I wish I could copy the commit hashes to give a full comment, [but I can't](//meta.stackoverflow.com/q/285551) – knittl Mar 24 '23 at 12:44
  • @knittl ah, I see, what I'm looking at is the merge commit from `feature`. Thank you! – Berthrand Eros Mar 24 '23 at 12:48
  • Yes, that's what _I_ said. Your first merge was a merge but because you equated the two states, your second merge was a fast forward and, the states now being equal, it did nothing except repoint the two branches at the same commit. But as I also said, you could have solved this by saying `--no-ff`. Then you would see two merge commits. – matt Mar 24 '23 at 13:28
  • Another problem of course is that your way of printing out the log is crummy. Add `--graph` when you log, so you can see how these commits relate. Otherwise you're just seeing a bunch of commits with no sense of how they relate to each other. – matt Mar 24 '23 at 13:30
  • I should add: yes it's a merge commit from the point of view of `feature`. But now you are on `master` and you fast forwarded for the second "merge". That is why `master` now has nothing to do when you ask to `revert`. – matt Mar 24 '23 at 13:31
  • Plus: You are not taking knittl's hint. Replace your screenshots with text. Never show us pictures of text on Stack Overflow. – matt Mar 24 '23 at 13:32

0 Answers0