Reputation: 545
Here's how we work with git.
Every functionality is developped in a separate branch. And then, every server has it's branch (production = Master, QA=QA)
So everytime a functionality is validated by a developper, we merge it to the QA branch, where our QA specialists make their validations.
Here's a scenario :
Developper number one merges functionality1 in QA on monday (merge1)
Developper number two merges functionality2 in QA on tuesday (merge2)
Developper number three merges functionality3 in QA on wednesday (merge3)
On friday, the QA specialist decides that functionality2 and functionality3 are good, but the we have to fix the functionality1.
So my question is, is it possible in Git, to cancel only the merge1, and keep the others?
Thanks a lot
Upvotes: 0
Views: 176
Reputation: 45649
Because the QA branch is presumably shared among a number of developers and QA specialists, there would be significant costs to rewriting the history. (Also it would not be easy to do, because the branch consists of merges.)
Instead you could revert the merge of functionality_1
. This also has some complications, especially when you've fixed functionality_1
and want to re-introduce it into QA
. I'll walk through that procedure momentarily.
But because all methods of doing this (1) have costs as noted above, and (2) also could involve conflict resolution, you might want to consider another option: Is it possible to modify your workflow to minimize or eliminate the need to do this? It would be beyond the scope of this answer to get into all the workflow design considerations involved, but when its feasible to avoid this situation, it saves headaches.
Anyway, to revert the merge, you need an expression that resolves to the merge commit. That could be the merge commit ID, or something like QA~3
assuming the three merges you mentioned are the three most recent commits on the QA
branch.
git revert -m1 QA~3
will create a new commit on the QA branch, which "undoes" the changes that the merge introduced into the QA
branch. (I'm making certain assumptions when I say that, but they should hold for the workflow you described.)
... M1 -- M2 -- M3 -- !M1 <--(QA)
So that part's simple, but simply merging functionality_1
again will not re-introduce the changes you reverted, because from git's perspective they're already accounted for in QA
. When it comes time to re-introduce funcitonality_1
, you'll have two options:
(1) revert !M1
, and then merge the remainder of functionality_1
; if nothing else has since been merged into QA
, then simply QA
will resolve to !M1
and you could say
git revert QA
Or
(2) "force rebase" functionality_1
, re-creating the branch from new commits, and then merge the recreated branch into QA
. To do this, you need to be able to identify all changes "reachable from" functionality_1
that were not "reachable from" QA
until M1
. If you don't want to change the commit topology, you'll need to know the branch point (i.e. the parent of the first commit that introduced such a change). Then you'd say
git rebase -f P functionality_1
where P
is an expression that resolves to the parent commit.
This is a history rewrite of the functionality_1
branch, so if you keep the individual branches on the remove, you'll have to force-push it (and everyone else will have to recover from an upstream rebase condition; see the git rebase
docs).
But this will make the merge behave as expected.
Upvotes: 1