1

I've created a simplification of a scenario in which I'm trying to understand why it works like that.

Here is the timeline of commits:

enter image description here

At first I've created a new branch named dev + feature - both had one commit:

Let's look at dev :

enter image description here

Then added another line and committed :

enter image description here

Then another one :

enter image description here

And another one :

enter image description here

Then I switched to feature branch and added "bad code" :

enter image description here

Then I've switched back to dev and merged feature to dev :

enter image description here

So now I decided to revert the merge commit :

git revert -m 1 2c618a9

(parent 1 is the dev branch) and the revert did work as expected.

However, When I try ( only for testing purposes) to re-merge the feature branch to dev , nothing seems to happen: and I do not see the bad commits again :

enter image description here

Question

As you can see, the bad commits are not entered again. Why is that ? What if I wanted to merge it again?

Royi Namir
  • 144,742
  • 138
  • 468
  • 792
  • Merging is about merging trees/commits, not about cherry-picking. _Why is that?_ - the feature branch is already merged to the master. _What if I wanted to merge it again_ - try using `git cherry-pick`. – terrorrussia-keeps-killing Nov 03 '21 at 07:58
  • @fluffy But I've reverted the merge of `feature` from `dev` . So I don't understand what's going on – Royi Namir Nov 03 '21 at 08:00
  • When you `git revert` any commit that came from any branch, the fact of "it was initially at that branch" is **not tracked** by git: neither `git commit`, nor `git revert`, not `git cherry-pick`, nor `git rebase`, nor `git am` (whatever?) differ from this perspective -- they all apply patches and create new commits. Moreoever, you could even handcraft a `git commit` that would apply the same patch as `git revert` did, and it would be _the same_ from git perspective. When you did a revert, you only applied a reverse patch. – terrorrussia-keeps-killing Nov 03 '21 at 08:12
  • When you `git merge`, and the respective commit _is already_ in the branch you merge into, git simply ignores the merge request, as that commit is already in its history. – terrorrussia-keeps-killing Nov 03 '21 at 08:13
  • @fluffy when you say "_The fact of "it was initially at that branch" is not tracked by git_" , do you mean that because `feature` branch was already merged to `dev` , even if I do `revert` , then it stops from being tracked ? So what if I would add another bad commit (after the `revert` ) to `feature` branch and then try to merge again to `dev` ? – Royi Namir Nov 03 '21 at 08:25
  • When you do `git revert`, you specify where to apply the reverse patch from. When you do `git revert `, is it _totally equivalent_ to you do `git revert `, and no source is recorded: you can do that even from a patch file that does not have a source branch in the file -- these three are all about applying a patch either from a commit in the history or a patch file. – terrorrussia-keeps-killing Nov 03 '21 at 08:33
  • _So what if I would add another bad commit (after the revert ) to feature branch and then try to merge again to dev ?_ -- then it is a new commit that does not belong to the master branch ancestors, so yeah, `git merge` detects that and makes another merge commit. After the merge is concluded, the new merge commit contains all commits in its ancestors graph, and the further git merge will end up with `Already up to date` as you already have. Again, `git merge` is about combining commits, whilst `git commit`, `git revert`, `git cherry-pick` etc are about creating a new commit. – terrorrussia-keeps-killing Nov 03 '21 at 08:36
  • you say `master` but the only two branched I've used here is dev and feature. – Royi Namir Nov 03 '21 at 08:40
  • It does not really matter. :) – terrorrussia-keeps-killing Nov 03 '21 at 08:46
  • I marked this as a duplicate, though it might in some ways be better to mark the other one as a duplicate of this one. This *question* is better, while the other *answer* covers more ground. – torek Nov 03 '21 at 21:56

1 Answers1

1

git merge first looks at how commits are linked one to another :

if you look at your repo's history graph (the blue and red dots on the left of your screenshot), you can see that the result of git revert will :

  • keep the existing history (including the previous git merge feature)
  • add a new commit on top of that

So the next time you try to run git merge feature, git will say "oh, but feature is already merged into dev", and will do nothing more.


One possibility to "re merge" feature is to use git cherry-pick to select the commit(s) that you want to replay on dev :

git cherry-pick <bad commit>

# if there were several commits to 're merge' :
git cherry-pick <commit1> <commit2> ...
LeGEC
  • 46,477
  • 5
  • 57
  • 104
  • _oh, but feature is already merged into dev_........ But what if I go now ( after `revert`) to the `feature` branch and add another commit? The merge now _WILL_ work. But according to your sentence, `feature` is already merged to `dev` and won't merge. But it will.... So? – Royi Namir Nov 03 '21 at 12:00
  • @RoyiNamir: if you add a commit to `feature`, you history graph changes. There would be a new commit on top of the red commit, and you would see that the updated `feature` branch is not meregd into dev. `git merge` would integrate only the differences introduced by that new commit. – LeGEC Nov 03 '21 at 12:38
  • @RoyiNamir : you may check `git help merge` and `git help merge-base`, or [the git book](https://git-scm.com/book/en/v2/), in its [Advanced merging](https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging) section, there is a paragraph detailing what may happen around a revert : [Reverse the commit](https://git-scm.com/book/en/v2/Git-Tools-Advanced-Merging#_reverse_commit) (note : they suggest reverting the revert) – LeGEC Nov 03 '21 at 12:42