1

I work in Branch X and take in deliveries from Branch Y which is maintained by other devs. I merge Y into X but need to revert changes by some faulty commits in Y to a file 'KKK' and continue working on top of their other changes while they fix that. This causes a revert commit for file 'KKK' [which I never usually touch] by me in Branch X. This means 'KKK' is reverted to 'Version A' in my branch while work on it continues in Branch Y. (see fig.)

Down the line, when 'KKK' has become more mature at 'Version I', I make another merge of Y into X, this time expecting 'KKK' to update to 'Version I'. Instead, git automatically takes my revert commit 'Version A' and ignores 'Version I' when making the merge. The file is still at 'Version A'. Why does this happen? Is something wrong with my way of working?

I have a feeling that this is related somehow to 'fast forward merges' but I'm not sure. I have tried to visualize this here.

Thanks in advance.

1 Answer 1

1

When you revert something, it means "I don't want this change, ever" (because it was broken).

When merging a branch, Git (or any DVCS for that matter) only merges new changes from new commits. The change that you reverted is already merged, so it will not be re-merged (otherwise the whole point of reverting would be futile – how would an SCM know which reverts are real reverts and which are not?).

Visually:

A-B-M-C'--X-... <- branch a / / C-D-----E--.. <- branch b 

With commit C introducing the change and commit C' reverting the change of said commit. Commits M and X are both merges. When you call merge the first time to create commit M all changes of C and D are included. When you run merge a second time for commit X, only the changes of E are merged, because all other changes of branch b already exist in branch a.

Now, how to get the initial and the followup changes into branch a? Re-revert the commit, in other words run git revert C' before merging branch b again. That way, branch a contains the original changes again, before applying any new changes (e.g. commit E).

Sign up to request clarification or add additional context in comments.

6 Comments

Thanks for replying. In the commit tree you have drawn, are each of the commits changes to the same file?
@AnshGandhi that fact is orthogonal to the way reverts work. But yes, if you revert a commit which touches only a single file then all other commits/changes would still show up "normally". But it doesn't really matter for this discussion
I'll try to rephrase- @knittl Assuming that these commits are to the same file, why didn't git show a conflict between version C' and version E of the file stating that work has been done on the file in both branches?
@AnshGandhi one possibility is changes to different parts of the file. E.g. Commit C changed line 21, commit C' reverted line 21 and commit E changes line 42. All touch the same file, but there will be no content conflicts. If they do touch the same lines, then you should get conflicts. Do you have a MWE?
Sorry for the radio silence, had gone away. I had a discussion about this with another colleague of mine and he said 'git doesn't look at files but content.' which made it more clear for me... so version X is actually a merge of content changes from C' and E in this case, correct? If so, then your suggestion to revert the revert also makes sense. Sorry I don't have an 'mwe'. Just learned what that is. Curious question - what about files that are not readable code for git, then it should throw a conflict when merging E right? @knittl
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.