Merge "Merge branch 'stable-2.12'"
This commit is contained in:
		| @@ -120,7 +120,7 @@ link:cmd-gc.html[gerrit gc]:: | |||||||
| link:cmd-gsql.html[gerrit gsql]:: | link:cmd-gsql.html[gerrit gsql]:: | ||||||
| 	Administrative interface to active database. | 	Administrative interface to active database. | ||||||
|  |  | ||||||
| link:cmd-index-index.html[gerrit index activate]:: | link:cmd-index-activate.html[gerrit index activate]:: | ||||||
| 	Activate the latest index version available. | 	Activate the latest index version available. | ||||||
|  |  | ||||||
| link:cmd-index-start.html[gerrit index start]:: | link:cmd-index-start.html[gerrit index start]:: | ||||||
|   | |||||||
| @@ -1394,21 +1394,37 @@ Type of database server to connect to.  If set this value will be | |||||||
| used to automatically create correct database.driver and database.url | used to automatically create correct database.driver and database.url | ||||||
| values to open the connection. | values to open the connection. | ||||||
| + | + | ||||||
| * `POSTGRESQL` | * `DB2` | ||||||
| + | + | ||||||
| Connect to a PostgreSQL database server. | Connect to a DB2 database server. | ||||||
|  | + | ||||||
|  | * `DERBY` | ||||||
|  | + | ||||||
|  | Connect to an Apache Derby database server. | ||||||
| + | + | ||||||
| * `H2` | * `H2` | ||||||
| + | + | ||||||
| Connect to a local embedded H2 database. | Connect to a local embedded H2 database. | ||||||
| + | + | ||||||
|  | * `JDBC` | ||||||
|  | + | ||||||
|  | Connect using a JDBC driver class name and URL. | ||||||
|  | + | ||||||
|  | * `MAXDB` | ||||||
|  | + | ||||||
|  | Connect to an SAP MaxDb database server. | ||||||
|  | + | ||||||
| * `MYSQL` | * `MYSQL` | ||||||
| + | + | ||||||
| Connect to a MySQL database server. | Connect to a MySQL database server. | ||||||
| + | + | ||||||
| * `JDBC` | * `ORACLE` | ||||||
| + | + | ||||||
| Connect using a JDBC driver class name and URL. | Connect to an Oracle database server. | ||||||
|  | + | ||||||
|  | * `POSTGRESQL` | ||||||
|  | + | ||||||
|  | Connect to a PostgreSQL database server. | ||||||
|  |  | ||||||
| + | + | ||||||
| If not specified, database.driver and database.url are used as-is, | If not specified, database.driver and database.url are used as-is, | ||||||
|   | |||||||
							
								
								
									
										189
									
								
								ReleaseNotes/ReleaseNotes-2.12.1.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										189
									
								
								ReleaseNotes/ReleaseNotes-2.12.1.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,189 @@ | |||||||
|  | Release notes for Gerrit 2.12.1 | ||||||
|  | =============================== | ||||||
|  |  | ||||||
|  | Gerrit 2.12.1 is now available: | ||||||
|  |  | ||||||
|  | link:https://gerrit-releases.storage.googleapis.com/gerrit-2.12.1.war[ | ||||||
|  | https://gerrit-releases.storage.googleapis.com/gerrit-2.12.1.war] | ||||||
|  |  | ||||||
|  | Gerrit 2.12.1 includes the bug fixes done with | ||||||
|  | link:ReleaseNotes-2.11.6.html[Gerrit 2.11.6] and | ||||||
|  | link:ReleaseNotes-2.11.7.html[Gerrit 2.11.7]. These bug fixes are *not* | ||||||
|  | listed in these release notes. | ||||||
|  |  | ||||||
|  | *WARNING:* This version includes a manual schema upgrade when upgrading | ||||||
|  | from 2.12. | ||||||
|  | + | ||||||
|  | If you have already upgraded to 2.12, you need to issue this SQL statement | ||||||
|  | manually (e.g. using the `gerrit gsql` SSH command or the `gqsl` site | ||||||
|  | program): | ||||||
|  | + | ||||||
|  |   alter table patch_sets modify push_certficate clob; | ||||||
|  | + | ||||||
|  | Or with this command if the site is configured to use PostgreSQL: | ||||||
|  | + | ||||||
|  |   alter table patch_sets alter column push_certficate type text; | ||||||
|  | + | ||||||
|  | Note that the misspelled `push_certficate` is the actual name of the | ||||||
|  | column. | ||||||
|  | + | ||||||
|  | If you are upgrading from a version earlier than 2.12, this manual step is | ||||||
|  | not necessary and should be omitted. | ||||||
|  |  | ||||||
|  |  | ||||||
|  | Bug Fixes | ||||||
|  | --------- | ||||||
|  |  | ||||||
|  | General | ||||||
|  | ^^^^^^^ | ||||||
|  |  | ||||||
|  | * Fix column type for signed push certificates. | ||||||
|  | + | ||||||
|  | The column type `VARCHAR(255)` was too small, preventing some PGP push | ||||||
|  | certificates from being stored. | ||||||
|  |  | ||||||
|  | * Add the `DRAFT_COMMENTS` option to the list changes REST API endpoint | ||||||
|  | and mark it as deprecated. | ||||||
|  | + | ||||||
|  | It was removed in version 2.12 because it's not needed any more by the UI, | ||||||
|  | but this caused failures for clients that still use it. | ||||||
|  | + | ||||||
|  | Now it is added back, although it does not do anything and is marked as | ||||||
|  | deprecated. | ||||||
|  |  | ||||||
|  | * link:https://code.google.com/p/gerrit/issues/detail?id=3669[Issue 3669]: | ||||||
|  | Fix schema migration when migrating to 2.12.x directly from a version | ||||||
|  | earlier than 2.11. | ||||||
|  |  | ||||||
|  | * link:https://code.google.com/p/gerrit/issues/detail?id=3733[Issue 3733]: | ||||||
|  | Correctly detect symlinked log directory on startup. | ||||||
|  | + | ||||||
|  | If `$site_path/logs` was a symlink, the server would not start. | ||||||
|  |  | ||||||
|  | * link:https://code.google.com/p/gerrit/issues/detail?id=3871[Issue 3871]: | ||||||
|  | Throw an explicit exception when failing to load a change from the database. | ||||||
|  | + | ||||||
|  | If a change could not be loaded from the database, for example if it was | ||||||
|  | manually removed from the changes table but references to it were remaining | ||||||
|  | in other tables, a null change was returned which would then lead to an | ||||||
|  | 'Internal Server Error' that was difficult to track down. Now an error is | ||||||
|  | raised earlier which will help administrators to find the root cause. | ||||||
|  |  | ||||||
|  | * https://code.google.com/p/gerrit/issues/detail?id=3743[Issue 3743]: | ||||||
|  | Use submitter identity as committer when using 'Rebase if Necessary' merge | ||||||
|  | strategy. | ||||||
|  | + | ||||||
|  | When submitting a change that required rebase, the committer was being | ||||||
|  | set to 'Gerrit Code Review' instead of the name of the submitter. | ||||||
|  |  | ||||||
|  | * link:https://code.google.com/p/gerrit/issues/detail?id=3758[Issue 3758]: | ||||||
|  | Fix serving of static resources when deployed in application container. | ||||||
|  | + | ||||||
|  | When deployed in a container, for example Tomcat, it was not possible to | ||||||
|  | load the UI because static content could not be loaded from the WAR file. | ||||||
|  |  | ||||||
|  | * link:https://code.google.com/p/gerrit/issues/detail?id=3790[Issue 3790]: | ||||||
|  | When deployed in a container, for example Tomcat, the 'Documentation' menu | ||||||
|  | was missing. | ||||||
|  |  | ||||||
|  | * link:https://code.google.com/p/gerrit/issues/detail?id=3786[Issue 3786]: | ||||||
|  | Fix SQL statement syntax in schema migration. | ||||||
|  | + | ||||||
|  | An extra semicolon was preventing migration from 2.11.x to 2.12 when using | ||||||
|  | an Oracle database. | ||||||
|  |  | ||||||
|  | * Send email using email queue instead of the default queue. | ||||||
|  | + | ||||||
|  | Some emails sent asynchronously were already being sent using that queue | ||||||
|  | but some were not. This was confusing for a gerrit administrator because | ||||||
|  | if there is a build up of `send-email` tasks in the queue, he would | ||||||
|  | think that increasing `sendemail.threadPoolSize` would help but it did not | ||||||
|  | because some of the email were sent using the default queue which is | ||||||
|  | configurable using `execution.defaultThreadPoolSize`. | ||||||
|  |  | ||||||
|  | * Fix XSRF token cookie to honor `auth.cookieSecure` setting. | ||||||
|  |  | ||||||
|  | * link:https://code.google.com/p/gerrit/issues/detail?id=3767[Issue 3767]: | ||||||
|  | Fix replication of first patch set for new changes. | ||||||
|  | + | ||||||
|  | When new changes were pushed from the command line, the first patch | ||||||
|  | set did not get replicated to destinations. | ||||||
|  |  | ||||||
|  | * link:https://code.google.com/p/gerrit/issues/detail?id=3771[Issue 3771]: | ||||||
|  | Remove `index.defaultMaxClauseCount` configuration option. | ||||||
|  | + | ||||||
|  | When `index.maxTerms` was either not set (thus no limit) or set to a value | ||||||
|  | higher than `index.defaultMaxClauseCount` it was possible that viewing the | ||||||
|  | related changes tab could cause a 'Too many clauses' error for changes that | ||||||
|  | have a lot of related changes. | ||||||
|  | + | ||||||
|  | The `index.defaultMaxClauseCount` configuration option is removed, and the | ||||||
|  | existing `index.maxTerms` is reused. The default value of `index.maxTerms` | ||||||
|  | is reduced from 'no limit' to 1024. | ||||||
|  |  | ||||||
|  | * link:https://code.google.com/p/gerrit/issues/detail?id=3919[Issue 3919]: | ||||||
|  | Explicitly set parent project to 'All-Projects' when a project is created | ||||||
|  | without giving the parent. | ||||||
|  |  | ||||||
|  | UI | ||||||
|  | ^^ | ||||||
|  |  | ||||||
|  | * link:https://code.google.com/p/gerrit/issues/detail?id=3071[Issue 3071]: | ||||||
|  | Fix display of submodule differences in side-by-side view. | ||||||
|  |  | ||||||
|  | * link:https://code.google.com/p/gerrit/issues/detail?id=3718[Issue 3718]: | ||||||
|  | Hide avatar images when no avatars are available. | ||||||
|  | + | ||||||
|  | The UI was showing a transparent empty image with a border. | ||||||
|  |  | ||||||
|  | * link:https://code.google.com/p/gerrit/issues/detail?id=3731[Issue 3731]: | ||||||
|  | Fix syntax higlighting of tcl files. | ||||||
|  |  | ||||||
|  | * link:https://code.google.com/p/gerrit/issues/detail?id=3863[Issue 3863]: | ||||||
|  | Fix display of active row marker in tag list. | ||||||
|  | + | ||||||
|  | Clicking on one of the rows would cause the tag name to disappear. | ||||||
|  |  | ||||||
|  | * link:https://code.google.com/p/gerrit/issues/detail?id=1207[Issue 1207]: | ||||||
|  | Fix keyboard shortcuts for non-US keyboards on side-by-side diff screen. | ||||||
|  | + | ||||||
|  | The forward/backward navigation keys `[` and `]` only worked on keyboards where | ||||||
|  | these characters could be typed without using any modifier key (like CTRL, ALT, | ||||||
|  | etc..). | ||||||
|  | + | ||||||
|  | Note that the problem still exists on the unified diff screen. | ||||||
|  |  | ||||||
|  | Plugins | ||||||
|  | ^^^^^^^ | ||||||
|  |  | ||||||
|  | * Allow plugins to get the caller in merge validation requests. | ||||||
|  | + | ||||||
|  | Plugins that implement the `MergeValidationListener` interface now get the | ||||||
|  | caller (the user who initiated the merge) in the `onPreMerge` method. | ||||||
|  | + | ||||||
|  | Existing plugins that implement this interface must be adapted to the new | ||||||
|  | method signature. | ||||||
|  |  | ||||||
|  | * link:https://code.google.com/p/gerrit/issues/detail?id=3741[Issue 3741]: | ||||||
|  | Fix handling of merge validation exceptions emitted by plugins. | ||||||
|  | + | ||||||
|  | If a plugin raised an exception, it was reported to the user as 'Change is | ||||||
|  | new', rather than 'Missing dependency'. | ||||||
|  |  | ||||||
|  | * link:https://code.google.com/p/gerrit/issues/detail?id=3821[Issue 3821]: | ||||||
|  | Fix repeated reloading of plugins when running on OpenJDK 8. | ||||||
|  | + | ||||||
|  | OpenJDK 8 uses nanotime precision for file modification time on systems that | ||||||
|  | are POSIX 2008 compatible. This leads to precision incompatibility when | ||||||
|  | comparing the plugin's JAR file timestamp, resulting in the plugin being | ||||||
|  | reloaded every minute. | ||||||
|  |  | ||||||
|  | Documentation | ||||||
|  | ^^^^^^^^^^^^^ | ||||||
|  |  | ||||||
|  | * Update documentation of `commentlink` to reflect changed search URL. | ||||||
|  |  | ||||||
|  | Upgrades | ||||||
|  | -------- | ||||||
|  |  | ||||||
|  | * Upgrade JGit to 4.1.2.201602141800-r. | ||||||
| @@ -9,6 +9,7 @@ Version 2.13.x | |||||||
| [[2_12]] | [[2_12]] | ||||||
| Version 2.12.x | Version 2.12.x | ||||||
| -------------- | -------------- | ||||||
|  | * link:ReleaseNotes-2.12.1.html[2.12.1] | ||||||
| * link:ReleaseNotes-2.12.html[2.12] | * link:ReleaseNotes-2.12.html[2.12] | ||||||
|  |  | ||||||
| [[2_11]] | [[2_11]] | ||||||
|   | |||||||
| @@ -43,6 +43,8 @@ import org.eclipse.jgit.transport.PushResult; | |||||||
| import org.eclipse.jgit.transport.RemoteRefUpdate; | import org.eclipse.jgit.transport.RemoteRefUpdate; | ||||||
| import org.eclipse.jgit.transport.RemoteRefUpdate.Status; | import org.eclipse.jgit.transport.RemoteRefUpdate.Status; | ||||||
|  |  | ||||||
|  | import java.util.List; | ||||||
|  |  | ||||||
| public class PushOneCommit { | public class PushOneCommit { | ||||||
|   public static final String SUBJECT = "test commit"; |   public static final String SUBJECT = "test commit"; | ||||||
|   public static final String FILE_NAME = "a.txt"; |   public static final String FILE_NAME = "a.txt"; | ||||||
| @@ -179,6 +181,13 @@ public class PushOneCommit { | |||||||
|       .committer(new PersonIdent(i, testRepo.getDate())); |       .committer(new PersonIdent(i, testRepo.getDate())); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   public void setParents(List<RevCommit> parents) throws Exception { | ||||||
|  |     commitBuilder.noParents(); | ||||||
|  |     for (RevCommit p : parents) { | ||||||
|  |       commitBuilder.parent(p); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |  | ||||||
|   public Result to(String ref) throws Exception { |   public Result to(String ref) throws Exception { | ||||||
|     commitBuilder.add(fileName, content); |     commitBuilder.add(fileName, content); | ||||||
|     return execute(ref); |     return execute(ref); | ||||||
| @@ -189,7 +198,7 @@ public class PushOneCommit { | |||||||
|     return execute(ref); |     return execute(ref); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   private Result execute(String ref) throws Exception { |   public Result execute(String ref) throws Exception { | ||||||
|     RevCommit c = commitBuilder.create(); |     RevCommit c = commitBuilder.create(); | ||||||
|     if (changeId == null) { |     if (changeId == null) { | ||||||
|       changeId = GitUtil.getChangeId(testRepo, c).get(); |       changeId = GitUtil.getChangeId(testRepo, c).get(); | ||||||
|   | |||||||
| @@ -103,7 +103,7 @@ public class ActionsIT extends AbstractDaemonTest { | |||||||
|       assertThat(info.label).isEqualTo("Submit whole topic"); |       assertThat(info.label).isEqualTo("Submit whole topic"); | ||||||
|       assertThat(info.method).isEqualTo("POST"); |       assertThat(info.method).isEqualTo("POST"); | ||||||
|       assertThat(info.title).isEqualTo( |       assertThat(info.title).isEqualTo( | ||||||
|           "Clicking the button would fail for other changes"); |           "See the \"Submitted Together\" tab for problems"); | ||||||
|     } else { |     } else { | ||||||
|       noSubmitWholeTopicAssertions(actions, 1); |       noSubmitWholeTopicAssertions(actions, 1); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -19,6 +19,7 @@ import static com.google.common.truth.Truth.assertThat; | |||||||
| import com.google.gerrit.acceptance.AbstractDaemonTest; | import com.google.gerrit.acceptance.AbstractDaemonTest; | ||||||
| import com.google.gerrit.acceptance.RestResponse; | import com.google.gerrit.acceptance.RestResponse; | ||||||
| import com.google.gerrit.reviewdb.client.Project; | import com.google.gerrit.reviewdb.client.Project; | ||||||
|  | import com.google.gerrit.server.config.AllProjectsNameProvider; | ||||||
| import com.google.gerrit.server.project.SetParent; | import com.google.gerrit.server.project.SetParent; | ||||||
|  |  | ||||||
| import org.junit.Test; | import org.junit.Test; | ||||||
| @@ -49,6 +50,19 @@ public class SetParentIT extends AbstractDaemonTest { | |||||||
|         newGson().fromJson(r.getReader(), String.class); |         newGson().fromJson(r.getReader(), String.class); | ||||||
|     assertThat(newParent).isEqualTo(parent); |     assertThat(newParent).isEqualTo(parent); | ||||||
|     r.consume(); |     r.consume(); | ||||||
|  |  | ||||||
|  |     // When the parent name is not explicitly set, it should be | ||||||
|  |     // set to "All-Projects". | ||||||
|  |     r = adminSession.put("/projects/" + project.get() + "/parent", | ||||||
|  |           newParentInput(null)); | ||||||
|  |     r.assertOK(); | ||||||
|  |     r.consume(); | ||||||
|  |  | ||||||
|  |     r = adminSession.get("/projects/" + project.get() + "/parent"); | ||||||
|  |     r.assertOK(); | ||||||
|  |     newParent = newGson().fromJson(r.getReader(), String.class); | ||||||
|  |     assertThat(newParent).isEqualTo(AllProjectsNameProvider.DEFAULT); | ||||||
|  |     r.consume(); | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   @Test |   @Test | ||||||
|   | |||||||
| @@ -136,15 +136,6 @@ public class KeyCommandSet implements KeyPressHandler { | |||||||
|     if (mask == 0) { |     if (mask == 0) { | ||||||
|       mask = event.getNativeEvent().getKeyCode(); |       mask = event.getNativeEvent().getKeyCode(); | ||||||
|     } |     } | ||||||
|     if (event.isAltKeyDown()) { |  | ||||||
|       mask |= KeyCommand.M_ALT; |  | ||||||
|     } |  | ||||||
|     if (event.isControlKeyDown()) { |  | ||||||
|       mask |= KeyCommand.M_CTRL; |  | ||||||
|     } |  | ||||||
|     if (event.isMetaKeyDown()) { |  | ||||||
|       mask |= KeyCommand.M_META; |  | ||||||
|     } |  | ||||||
|     return mask; |     return mask; | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -368,8 +368,8 @@ public class SideBySide extends Screen { | |||||||
|     KeyMap keyMap = KeyMap.create() |     KeyMap keyMap = KeyMap.create() | ||||||
|         .on("A", upToChange(true)) |         .on("A", upToChange(true)) | ||||||
|         .on("U", upToChange(false)) |         .on("U", upToChange(false)) | ||||||
|         .on("[", header.navigate(Direction.PREV)) |         .on("'['", header.navigate(Direction.PREV)) | ||||||
|         .on("]", header.navigate(Direction.NEXT)) |         .on("']'", header.navigate(Direction.NEXT)) | ||||||
|         .on("R", header.toggleReviewed()) |         .on("R", header.toggleReviewed()) | ||||||
|         .on("O", commentManager.toggleOpenBox(cm)) |         .on("O", commentManager.toggleOpenBox(cm)) | ||||||
|         .on("Enter", commentManager.toggleOpenBox(cm)) |         .on("Enter", commentManager.toggleOpenBox(cm)) | ||||||
|   | |||||||
| @@ -85,8 +85,8 @@ public class Submit implements RestModifyView<RevisionResource, SubmitInput>, | |||||||
|       "This change depends on other hidden changes which are not ready"; |       "This change depends on other hidden changes which are not ready"; | ||||||
|   private static final String CLICK_FAILURE_TOOLTIP = |   private static final String CLICK_FAILURE_TOOLTIP = | ||||||
|       "Clicking the button would fail"; |       "Clicking the button would fail"; | ||||||
|   private static final String CLICK_FAILURE_OTHER_TOOLTIP = |   private static final String CHANGES_NOT_MERGEABLE = | ||||||
|       "Clicking the button would fail for other changes"; |       "See the \"Submitted Together\" tab for problems"; | ||||||
|  |  | ||||||
|   public static class Output { |   public static class Output { | ||||||
|     transient Change change; |     transient Change change; | ||||||
| @@ -258,7 +258,7 @@ public class Submit implements RestModifyView<RevisionResource, SubmitInput>, | |||||||
|           return CLICK_FAILURE_TOOLTIP; |           return CLICK_FAILURE_TOOLTIP; | ||||||
|         } |         } | ||||||
|         if (!mergeable) { |         if (!mergeable) { | ||||||
|           return CLICK_FAILURE_OTHER_TOOLTIP; |           return CHANGES_NOT_MERGEABLE; | ||||||
|         } |         } | ||||||
|         MergeOp.checkSubmitRule(c); |         MergeOp.checkSubmitRule(c); | ||||||
|       } |       } | ||||||
|   | |||||||
| @@ -20,11 +20,8 @@ import com.google.gerrit.extensions.registration.DynamicMap.Entry; | |||||||
| import com.google.gerrit.extensions.registration.DynamicSet; | import com.google.gerrit.extensions.registration.DynamicSet; | ||||||
| import com.google.gerrit.reviewdb.client.Branch; | import com.google.gerrit.reviewdb.client.Branch; | ||||||
| import com.google.gerrit.reviewdb.client.PatchSet; | import com.google.gerrit.reviewdb.client.PatchSet; | ||||||
| import com.google.gerrit.reviewdb.client.PatchSetApproval; |  | ||||||
| import com.google.gerrit.reviewdb.client.Project; | import com.google.gerrit.reviewdb.client.Project; | ||||||
| import com.google.gerrit.reviewdb.client.RefNames; | import com.google.gerrit.reviewdb.client.RefNames; | ||||||
| import com.google.gerrit.reviewdb.server.ReviewDb; |  | ||||||
| import com.google.gerrit.server.ApprovalsUtil; |  | ||||||
| import com.google.gerrit.server.IdentifiedUser; | import com.google.gerrit.server.IdentifiedUser; | ||||||
| import com.google.gerrit.server.config.AllProjectsName; | import com.google.gerrit.server.config.AllProjectsName; | ||||||
| import com.google.gerrit.server.config.PluginConfig; | import com.google.gerrit.server.config.PluginConfig; | ||||||
| @@ -97,9 +94,7 @@ public class MergeValidators { | |||||||
|         + "The change must be submitted by a Gerrit administrator."; |         + "The change must be submitted by a Gerrit administrator."; | ||||||
|  |  | ||||||
|     private final AllProjectsName allProjectsName; |     private final AllProjectsName allProjectsName; | ||||||
|     private final ReviewDb db; |  | ||||||
|     private final ProjectCache projectCache; |     private final ProjectCache projectCache; | ||||||
|     private final ApprovalsUtil approvalsUtil; |  | ||||||
|     private final DynamicMap<ProjectConfigEntry> pluginConfigEntries; |     private final DynamicMap<ProjectConfigEntry> pluginConfigEntries; | ||||||
|  |  | ||||||
|     public interface Factory { |     public interface Factory { | ||||||
| @@ -108,13 +103,10 @@ public class MergeValidators { | |||||||
|  |  | ||||||
|     @Inject |     @Inject | ||||||
|     public ProjectConfigValidator(AllProjectsName allProjectsName, |     public ProjectConfigValidator(AllProjectsName allProjectsName, | ||||||
|         ReviewDb db, ProjectCache projectCache, |         ProjectCache projectCache, | ||||||
|         ApprovalsUtil approvalsUtil, |  | ||||||
|         DynamicMap<ProjectConfigEntry> pluginConfigEntries) { |         DynamicMap<ProjectConfigEntry> pluginConfigEntries) { | ||||||
|       this.allProjectsName = allProjectsName; |       this.allProjectsName = allProjectsName; | ||||||
|       this.db = db; |  | ||||||
|       this.projectCache = projectCache; |       this.projectCache = projectCache; | ||||||
|       this.approvalsUtil = approvalsUtil; |  | ||||||
|       this.pluginConfigEntries = pluginConfigEntries; |       this.pluginConfigEntries = pluginConfigEntries; | ||||||
|     } |     } | ||||||
|  |  | ||||||
| @@ -142,11 +134,6 @@ public class MergeValidators { | |||||||
|             } |             } | ||||||
|           } else { |           } else { | ||||||
|             if (!oldParent.equals(newParent)) { |             if (!oldParent.equals(newParent)) { | ||||||
|               PatchSetApproval psa = |  | ||||||
|                   approvalsUtil.getSubmitter(db, commit.notes(), patchSetId); |  | ||||||
|               if (psa == null) { |  | ||||||
|                 throw new MergeValidationException(SET_BY_ADMIN); |  | ||||||
|               } |  | ||||||
|               if (!caller.getCapabilities().canAdministrateServer()) { |               if (!caller.getCapabilities().canAdministrateServer()) { | ||||||
|                 throw new MergeValidationException(SET_BY_ADMIN); |                 throw new MergeValidationException(SET_BY_ADMIN); | ||||||
|               } |               } | ||||||
|   | |||||||
| @@ -150,9 +150,13 @@ public class PatchFile { | |||||||
|     if (tw == null) { |     if (tw == null) { | ||||||
|       return Text.EMPTY; |       return Text.EMPTY; | ||||||
|     } |     } | ||||||
|     if (tw.getFileMode(0).getObjectType() != Constants.OBJ_BLOB) { |     if (tw.getFileMode(0).getObjectType() == Constants.OBJ_BLOB) { | ||||||
|  |       return new Text(repo.open(tw.getObjectId(0), Constants.OBJ_BLOB)); | ||||||
|  |     } else if (tw.getFileMode(0).getObjectType() == Constants.OBJ_COMMIT) { | ||||||
|  |       String str = "Subproject commit " + ObjectId.toString(tw.getObjectId(0)); | ||||||
|  |       return new Text(str.getBytes()); | ||||||
|  |     } else { | ||||||
|       return Text.EMPTY; |       return Text.EMPTY; | ||||||
|     } |     } | ||||||
|     return new Text(repo.open(tw.getObjectId(0), Constants.OBJ_BLOB)); |  | ||||||
|   } |   } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -32,7 +32,6 @@ import com.google.gerrit.reviewdb.client.PatchSet; | |||||||
|  |  | ||||||
| import org.eclipse.jgit.diff.Edit; | import org.eclipse.jgit.diff.Edit; | ||||||
| import org.eclipse.jgit.lib.Constants; | import org.eclipse.jgit.lib.Constants; | ||||||
| import org.eclipse.jgit.lib.FileMode; |  | ||||||
| import org.eclipse.jgit.patch.CombinedFileHeader; | import org.eclipse.jgit.patch.CombinedFileHeader; | ||||||
| import org.eclipse.jgit.patch.FileHeader; | import org.eclipse.jgit.patch.FileHeader; | ||||||
| import org.eclipse.jgit.util.IntList; | import org.eclipse.jgit.util.IntList; | ||||||
| @@ -97,10 +96,7 @@ public class PatchListEntry { | |||||||
|  |  | ||||||
|     header = compact(hdr); |     header = compact(hdr); | ||||||
|  |  | ||||||
|     if (hdr instanceof CombinedFileHeader |     if (hdr instanceof CombinedFileHeader || hdr.getHunks().isEmpty()) { | ||||||
|         || hdr.getHunks().isEmpty() // |  | ||||||
|         || hdr.getOldMode() == FileMode.GITLINK |  | ||||||
|         || hdr.getNewMode() == FileMode.GITLINK) { |  | ||||||
|       edits = Collections.emptyList(); |       edits = Collections.emptyList(); | ||||||
|     } else { |     } else { | ||||||
|       edits = Collections.unmodifiableList(editList); |       edits = Collections.unmodifiableList(editList); | ||||||
|   | |||||||
| @@ -312,14 +312,6 @@ public class PatchListLoader implements Callable<PatchList> { | |||||||
|  |  | ||||||
|   private PatchListEntry newEntry(RevTree aTree, FileHeader fileHeader, |   private PatchListEntry newEntry(RevTree aTree, FileHeader fileHeader, | ||||||
|       long size, long sizeDelta) { |       long size, long sizeDelta) { | ||||||
|     final FileMode oldMode = fileHeader.getOldMode(); |  | ||||||
|     final FileMode newMode = fileHeader.getNewMode(); |  | ||||||
|  |  | ||||||
|     if (oldMode == FileMode.GITLINK || newMode == FileMode.GITLINK) { |  | ||||||
|       return new PatchListEntry(fileHeader, Collections.<Edit> emptyList(), |  | ||||||
|           size, sizeDelta); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     if (aTree == null // want combined diff |     if (aTree == null // want combined diff | ||||||
|         || fileHeader.getPatchType() != PatchType.UNIFIED |         || fileHeader.getPatchType() != PatchType.UNIFIED | ||||||
|         || fileHeader.getHunks().isEmpty()) { |         || fileHeader.getHunks().isEmpty()) { | ||||||
|   | |||||||
| @@ -179,9 +179,7 @@ class PatchScriptBuilder { | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     boolean hugeFile = false; |     boolean hugeFile = false; | ||||||
|     if (a.mode == FileMode.GITLINK || b.mode == FileMode.GITLINK) { |     if (a.src == b.src && a.size() <= context | ||||||
|       // Do nothing |  | ||||||
|     } else if (a.src == b.src && a.size() <= context |  | ||||||
|         && content.getEdits().isEmpty()) { |         && content.getEdits().isEmpty()) { | ||||||
|       // Odd special case; the files are identical (100% rename or copy) |       // Odd special case; the files are identical (100% rename or copy) | ||||||
|       // and the user has asked for context that is larger than the file. |       // and the user has asked for context that is larger than the file. | ||||||
| @@ -471,6 +469,10 @@ class PatchScriptBuilder { | |||||||
|           } else if (mode.getObjectType() == Constants.OBJ_BLOB) { |           } else if (mode.getObjectType() == Constants.OBJ_BLOB) { | ||||||
|             srcContent = Text.asByteArray(db.open(id, Constants.OBJ_BLOB)); |             srcContent = Text.asByteArray(db.open(id, Constants.OBJ_BLOB)); | ||||||
|  |  | ||||||
|  |           } else if (mode.getObjectType() == Constants.OBJ_COMMIT) { | ||||||
|  |             String strContent = "Subproject commit " + ObjectId.toString(id); | ||||||
|  |             srcContent = strContent.getBytes(); | ||||||
|  |  | ||||||
|           } else { |           } else { | ||||||
|             srcContent = Text.NO_BYTES; |             srcContent = Text.NO_BYTES; | ||||||
|           } |           } | ||||||
|   | |||||||
| @@ -44,6 +44,7 @@ import com.google.gerrit.reviewdb.client.RefNames; | |||||||
| import com.google.gerrit.server.CurrentUser; | import com.google.gerrit.server.CurrentUser; | ||||||
| import com.google.gerrit.server.GerritPersonIdent; | import com.google.gerrit.server.GerritPersonIdent; | ||||||
| import com.google.gerrit.server.account.GroupBackend; | import com.google.gerrit.server.account.GroupBackend; | ||||||
|  | import com.google.gerrit.server.config.AllProjectsName; | ||||||
| import com.google.gerrit.server.config.ProjectOwnerGroupsProvider; | import com.google.gerrit.server.config.ProjectOwnerGroupsProvider; | ||||||
| import com.google.gerrit.server.config.RepositoryConfig; | import com.google.gerrit.server.config.RepositoryConfig; | ||||||
| import com.google.gerrit.server.extensions.events.GitReferenceUpdated; | import com.google.gerrit.server.extensions.events.GitReferenceUpdated; | ||||||
| @@ -102,6 +103,7 @@ public class CreateProject implements RestModifyView<TopLevelResource, ProjectIn | |||||||
|   private final PersonIdent serverIdent; |   private final PersonIdent serverIdent; | ||||||
|   private final Provider<CurrentUser> currentUser; |   private final Provider<CurrentUser> currentUser; | ||||||
|   private final Provider<PutConfig> putConfig; |   private final Provider<PutConfig> putConfig; | ||||||
|  |   private final AllProjectsName allProjects; | ||||||
|   private final String name; |   private final String name; | ||||||
|  |  | ||||||
|   @Inject |   @Inject | ||||||
| @@ -120,6 +122,7 @@ public class CreateProject implements RestModifyView<TopLevelResource, ProjectIn | |||||||
|       @GerritPersonIdent PersonIdent serverIdent, |       @GerritPersonIdent PersonIdent serverIdent, | ||||||
|       Provider<CurrentUser> currentUser, |       Provider<CurrentUser> currentUser, | ||||||
|       Provider<PutConfig> putConfig, |       Provider<PutConfig> putConfig, | ||||||
|  |       AllProjectsName allProjects, | ||||||
|       @Assisted String name) { |       @Assisted String name) { | ||||||
|     this.projectsCollection = projectsCollection; |     this.projectsCollection = projectsCollection; | ||||||
|     this.groupsCollection = groupsCollection; |     this.groupsCollection = groupsCollection; | ||||||
| @@ -137,6 +140,7 @@ public class CreateProject implements RestModifyView<TopLevelResource, ProjectIn | |||||||
|     this.serverIdent = serverIdent; |     this.serverIdent = serverIdent; | ||||||
|     this.currentUser = currentUser; |     this.currentUser = currentUser; | ||||||
|     this.putConfig = putConfig; |     this.putConfig = putConfig; | ||||||
|  |     this.allProjects = allProjects; | ||||||
|     this.name = name; |     this.name = name; | ||||||
|   } |   } | ||||||
|  |  | ||||||
| @@ -155,9 +159,9 @@ public class CreateProject implements RestModifyView<TopLevelResource, ProjectIn | |||||||
|     CreateProjectArgs args = new CreateProjectArgs(); |     CreateProjectArgs args = new CreateProjectArgs(); | ||||||
|     args.setProjectName(ProjectUtil.stripGitSuffix(name)); |     args.setProjectName(ProjectUtil.stripGitSuffix(name)); | ||||||
|  |  | ||||||
|     if (!Strings.isNullOrEmpty(input.parent)) { |     String parentName = MoreObjects.firstNonNull( | ||||||
|       args.newParent = projectsCollection.get().parse(input.parent).getControl(); |         Strings.emptyToNull(input.parent), allProjects.get()); | ||||||
|     } |     args.newParent = projectsCollection.get().parse(parentName).getControl(); | ||||||
|     args.createEmptyCommit = input.createEmptyCommit; |     args.createEmptyCommit = input.createEmptyCommit; | ||||||
|     args.permissionsOnly = input.permissionsOnly; |     args.permissionsOnly = input.permissionsOnly; | ||||||
|     args.projectDescription = Strings.emptyToNull(input.description); |     args.projectDescription = Strings.emptyToNull(input.description); | ||||||
|   | |||||||
| @@ -14,6 +14,8 @@ | |||||||
|  |  | ||||||
| package com.google.gerrit.server.project; | package com.google.gerrit.server.project; | ||||||
|  |  | ||||||
|  | import static com.google.common.base.Preconditions.checkNotNull; | ||||||
|  |  | ||||||
| import com.google.common.base.MoreObjects; | import com.google.common.base.MoreObjects; | ||||||
| import com.google.common.base.Predicate; | import com.google.common.base.Predicate; | ||||||
| import com.google.common.base.Strings; | import com.google.common.base.Strings; | ||||||
| @@ -70,18 +72,18 @@ public class SetParent implements RestModifyView<ProjectResource, Input> { | |||||||
|       throws AuthException, ResourceConflictException, |       throws AuthException, ResourceConflictException, | ||||||
|       ResourceNotFoundException, UnprocessableEntityException, IOException { |       ResourceNotFoundException, UnprocessableEntityException, IOException { | ||||||
|     ProjectControl ctl = rsrc.getControl(); |     ProjectControl ctl = rsrc.getControl(); | ||||||
|     validateParentUpdate(ctl, input.parent, checkIfAdmin); |     String parentName = MoreObjects.firstNonNull( | ||||||
|  |         Strings.emptyToNull(input.parent), allProjects.get()); | ||||||
|  |     validateParentUpdate(ctl, parentName, checkIfAdmin); | ||||||
|     try (MetaDataUpdate md = updateFactory.create(rsrc.getNameKey())) { |     try (MetaDataUpdate md = updateFactory.create(rsrc.getNameKey())) { | ||||||
|       ProjectConfig config = ProjectConfig.read(md); |       ProjectConfig config = ProjectConfig.read(md); | ||||||
|       Project project = config.getProject(); |       Project project = config.getProject(); | ||||||
|       project.setParentName(Strings.emptyToNull(input.parent)); |       project.setParentName(parentName); | ||||||
|  |  | ||||||
|       String msg = Strings.emptyToNull(input.commitMessage); |       String msg = Strings.emptyToNull(input.commitMessage); | ||||||
|       if (msg == null) { |       if (msg == null) { | ||||||
|         msg = String.format( |         msg = String.format( | ||||||
|             "Changed parent to %s.\n", |               "Changed parent to %s.\n", parentName); | ||||||
|             MoreObjects.firstNonNull(project.getParentName(), |  | ||||||
|                 allProjects.get())); |  | ||||||
|       } else if (!msg.endsWith("\n")) { |       } else if (!msg.endsWith("\n")) { | ||||||
|         msg += "\n"; |         msg += "\n"; | ||||||
|       } |       } | ||||||
| @@ -90,8 +92,9 @@ public class SetParent implements RestModifyView<ProjectResource, Input> { | |||||||
|       config.commit(md); |       config.commit(md); | ||||||
|       cache.evict(ctl.getProject()); |       cache.evict(ctl.getProject()); | ||||||
|  |  | ||||||
|       Project.NameKey parentName = project.getParent(allProjects); |       Project.NameKey parent = project.getParent(allProjects); | ||||||
|       return parentName != null ? parentName.get() : ""; |       checkNotNull(parent); | ||||||
|  |       return parent.get(); | ||||||
|     } catch (RepositoryNotFoundException notFound) { |     } catch (RepositoryNotFoundException notFound) { | ||||||
|       throw new ResourceNotFoundException(rsrc.getName()); |       throw new ResourceNotFoundException(rsrc.getName()); | ||||||
|     } catch (ConfigInvalidException e) { |     } catch (ConfigInvalidException e) { | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Dave Borowitz
					Dave Borowitz