Allow creating merge commits with conflicts

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>
18 files changed
tree: aee3f244275265c26f73ac6432a8fded0e82f60c
  1. .settings/
  2. antlr3/
  3. contrib/
  4. Documentation/
  5. e2e-tests/
  6. java/
  7. javatests/
  8. lib/
  9. modules/
  10. plugins/
  11. polygerrit-ui/
  12. prolog/
  13. prologtests/
  14. proto/
  15. resources/
  16. tools/
  17. webapp/
  18. .bazelignore
  19. .bazelproject
  20. .bazelrc
  21. .bazelversion
  22. .editorconfig
  23. .git-blame-ignore-revs
  24. .gitignore
  25. .gitmodules
  26. .gitreview
  27. .mailmap
  28. .pydevproject
  29. BUILD
  30. COPYING
  31. INSTALL
  32. Jenkinsfile
  33. package.json
  34. README.md
  35. SUBMITTING_PATCHES
  36. version.bzl
  37. WORKSPACE
README.md

Gerrit Code Review

Gerrit is a code review and project management tool for Git based projects.

Build Status

Objective

Gerrit makes reviews easier by showing changes in a side-by-side display, and allowing inline comments to be added by any reviewer.

Gerrit simplifies Git based project maintainership by permitting any authorized user to submit changes to the master Git repository, rather than requiring all approved changes to be merged in by hand by the project maintainer.

Documentation

For information about how to install and use Gerrit, refer to the documentation.

Source

Our canonical Git repository is located on googlesource.com. There is a mirror of the repository on Github.

Reporting bugs

Please report bugs on the issue tracker.

Contribute

Gerrit is the work of hundreds of contributors. We appreciate your help!

Please read the contribution guidelines.

Note that we do not accept Pull Requests via the Github mirror.

Getting in contact

The Developer Mailing list is repo-discuss on Google Groups.

License

Gerrit is provided under the Apache License 2.0.

Build

Install Bazel and run the following:

    git clone --recurse-submodules https://gerrit.googlesource.com/gerrit
    cd gerrit && bazel build release

Install binary packages (Deb/Rpm)

The instruction how to configure GerritForge/BinTray repositories is here

On Debian/Ubuntu run:

    apt-get update & apt-get install gerrit=<version>-<release>

NOTE: release is a counter that starts with 1 and indicates the number of packages that have been released with the same version of the software.

On CentOS/RedHat run:

    yum clean all && yum install gerrit-<version>[-<release>]

On Fedora run:

    dnf clean all && dnf install gerrit-<version>[-<release>]

Use pre-built Gerrit images on Docker

Docker images of Gerrit are available on DockerHub

To run a CentOS 7 based Gerrit image:

    docker run -p 8080:8080 gerritforge/gerrit-centos7[:version]

To run a Ubuntu 15.04 based Gerrit image:

    docker run -p 8080:8080 gerritforge/gerrit-ubuntu15.04[:version]

NOTE: release is optional. Last released package of the version is installed if the release number is omitted.