There are 2 REST endpoints that allow callers to create merge commits in
Gerrit:
1. Create Change REST endpoint:
Creates a new change. If ChangeInput.merge is specified a merge
commit for the new change is created.
2. Create Merge Patch Set REST endpoint:
Creates a merge commit and adds it as a new patch set to an existing
change.
In both cases the merge is performed by Gerrit and if the merge fails
due to conflicts in the files, so far the request is always rejected
with '409 Conflict'.
This change adds a new option 'allowConflicts' in MergeInput that allows
the merge to succeed even if there are conflicts. If this option is set
and there are conflicts:
* the request still succeeds and the new change / patch set gets created
* the conflicting files in the merge commit contain Git conflict markers
* callers can know that there were conflicts by checking the
'containsGitConflicts' field in the returned ChangeInfo
* the change is set to work-in-progress so that it's not accidentally
submitted with conflicts
* a change message is posted on the change that lists the files that
have conflicts
This functionality is consistent with the existing 'allowConflicts'
option in CherryPickInput which allows to let a cherry-pick succeed even
if there are conflicts. Also here the request succeeds, callers can
check the 'containsGitConflicts' field in the returned ChangeInfo, the
change is set to work-in-progress and a change message lists the files
that have conflicts.
Being able to create merge commits even if there are conflicts is useful
because it:
* allows robots to create merge commits, and let human users resolve
conflicts if needed
* allows to resolve conflicts on merge without having a local git
client, e.g. by using online edit
Implementation-wise some aspects should be pointed out:
* To let callers know whether the request resulted in a merge with
conflicts, ChangeInfo contains a new 'containsGitConflicts' field now.
This field is only populated if the change info is returned in
response to a request that creates a new change or patch set and
conflicts are allowed. Doing this was already considered when the
allow conflicts option was added for cherry-picks (see alternative 1.
in the commit message of change Iae9eef38a). At that time we didn't
take this approach because it might confuse users if this field is not
populated for other requests. Instead we decided to add
CherryPickChangeInfo that extends ChangeInfo. However now this
approach doesn't scale well as we would need to add further classes
that extend ChangeInfo (e.g. NewChangeInfo for the Create Change REST
endpoint). To mitigate the concern that the 'containsGitConflicts'
field might be confusing for users, it states very explicitly in the
documentation when it is populated.
* CherryPickChangeInfo is obsolete now, but we cannot remove it without
breaking the Java API, hence we keep it.
* To be able to test the ChangeInfo that is returned by the Create
Change REST endpoint we need a new createAsInfo(ChangeInput) method in
the Changes API that returns the ChangeInfo (instead of a ChangeApi).
This follows the example of the cherryPickAsInfo(CherryPickInput)
method that was added by change Iae9eef38a.
* PatchSetInserter is enhanced with a method that allows to set the
change to work-in-progress so that this flag can be set in the same
BatchUpdateOp which also creates the patch set. It's not possible to
set this flag from a separate BatchUpdateOp in the same BatchUpdate
because the second BatchUpdateOp cannot observe the patch set that is
created by the first BatchUpdateOp (and the patch set data is needed
to send out the WorkInProgressStateChanged event).
* PatchSetInserter is also bound in BatchProgramModule, but EventUtil is
not available in this Guice stack which is why injecting
WorkInProgressStateChanged into PatchSetInserter fails in this setup.
To solve this, WorkInProgressStateChanged defines a disabled
implementation that is bound in BatchProgramModule (this follows the
example of RevisionCreated which is also needed by PatchSetInserter).
Change-Id: Ib6bc8eedfd8a98bf1088660e27610e1eafb095fc
Signed-off-by: Edwin Kempin <ekempin@google.com>