diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/LocalDiskRepositoryManager.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/LocalDiskRepositoryManager.java index f5ec96280f..633c3bb8d6 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/git/LocalDiskRepositoryManager.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/LocalDiskRepositoryManager.java @@ -20,6 +20,7 @@ import com.google.common.base.MoreObjects; import com.google.gerrit.extensions.events.LifecycleListener; import com.google.gerrit.lifecycle.LifecycleModule; import com.google.gerrit.reviewdb.client.Project; +import com.google.gerrit.reviewdb.client.RefNames; import com.google.gerrit.server.config.GerritServerConfig; import com.google.gerrit.server.config.SitePaths; import com.google.gerrit.server.notedb.NotesMigration; @@ -246,6 +247,18 @@ public class LocalDiskRepositoryManager implements GitRepositoryManager { null, ConfigConstants.CONFIG_KEY_LOGALLREFUPDATES, true); config.save(); + // JGit only writes to the reflog for refs/meta/config if the log file + // already exists. + // + File metaConfigLog = + new File(db.getDirectory(), "logs/" + RefNames.REFS_CONFIG); + if (!metaConfigLog.getParentFile().mkdirs() + || !metaConfigLog.createNewFile()) { + log.error(String.format( + "Failed to create ref log for %s in repository %s", + RefNames.REFS_CONFIG, name)); + } + onCreateProject(name); return db; diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/git/VersionedMetaData.java b/gerrit-server/src/main/java/com/google/gerrit/server/git/VersionedMetaData.java index 09846d6305..7f07e232b2 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/git/VersionedMetaData.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/git/VersionedMetaData.java @@ -45,7 +45,9 @@ import org.eclipse.jgit.transport.ReceiveCommand; import org.eclipse.jgit.treewalk.TreeWalk; import org.eclipse.jgit.util.RawParseUtils; +import java.io.BufferedReader; import java.io.IOException; +import java.io.StringReader; import java.util.Objects; /** @@ -342,7 +344,12 @@ public abstract class VersionedMetaData { RefUpdate ru = db.updateRef(refName); ru.setExpectedOldObjectId(oldId); ru.setNewObjectId(src); - ru.disableRefLog(); + ru.setRefLogIdent(update.getCommitBuilder().getAuthor()); + try (BufferedReader reader = new BufferedReader( + new StringReader(update.getCommitBuilder().getMessage()))) { + // read the subject line and use it as reflog message + ru.setRefLogMessage("commit: " + reader.readLine(), true); + } inserter.flush(); RefUpdate.Result result = ru.update(); switch (result) { diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/schema/SchemaVersion.java b/gerrit-server/src/main/java/com/google/gerrit/server/schema/SchemaVersion.java index ba2350fc48..50b3d88cc8 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/schema/SchemaVersion.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/schema/SchemaVersion.java @@ -32,7 +32,7 @@ import java.util.List; /** A version of the database schema. */ public abstract class SchemaVersion { /** The current schema version. */ - public static final Class C = Schema_105.class; + public static final Class C = Schema_106.class; public static int getBinaryVersion() { return guessVersion(C); diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_106.java b/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_106.java new file mode 100644 index 0000000000..ef7e291b8d --- /dev/null +++ b/gerrit-server/src/main/java/com/google/gerrit/server/schema/Schema_106.java @@ -0,0 +1,104 @@ +// Copyright (C) 2015 The Android Open Source Project +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package com.google.gerrit.server.schema; + +import static java.nio.charset.StandardCharsets.UTF_8; + +import com.google.gerrit.reviewdb.client.Project; +import com.google.gerrit.reviewdb.client.RefNames; +import com.google.gerrit.reviewdb.server.ReviewDb; +import com.google.gerrit.server.GerritPersonIdent; +import com.google.gerrit.server.git.GitRepositoryManager; +import com.google.gerrit.server.git.LocalDiskRepositoryManager; +import com.google.gwtorm.server.OrmException; +import com.google.inject.Inject; +import com.google.inject.Provider; + +import org.eclipse.jgit.lib.ObjectId; +import org.eclipse.jgit.lib.PersonIdent; +import org.eclipse.jgit.lib.Repository; + +import java.io.File; +import java.io.IOException; +import java.io.PrintWriter; +import java.util.SortedSet; + +public class Schema_106 extends SchemaVersion { + private final GitRepositoryManager repoManager; + private final PersonIdent serverUser; + + @Inject + Schema_106(Provider prior, + GitRepositoryManager repoManager, + @GerritPersonIdent PersonIdent serverUser) { + super(prior); + this.repoManager = repoManager; + this.serverUser = serverUser; + } + + @Override + protected void migrateData(ReviewDb db, UpdateUI ui) throws OrmException { + if (!(repoManager instanceof LocalDiskRepositoryManager)) { + return; + } + + ui.message("listing all repositories ..."); + SortedSet repoList = repoManager.list(); + ui.message("done"); + + ui.message(String.format("creating reflog files for %s branches ...", + RefNames.REFS_CONFIG)); + for (Project.NameKey project : repoList) { + try { + Repository repo = repoManager.openRepository(project); + try { + File metaConfigLog = + new File(repo.getDirectory(), "logs/" + RefNames.REFS_CONFIG); + if (metaConfigLog.exists()) { + continue; + } + + if (!metaConfigLog.getParentFile().mkdirs() + || !metaConfigLog.createNewFile()) { + throw new IOException(String.format( + "Failed to create reflog for %s in repository %s", + RefNames.REFS_CONFIG, project)); + } + + ObjectId metaConfigId = repo.resolve(RefNames.REFS_CONFIG); + if (metaConfigId != null) { + try (PrintWriter writer = + new PrintWriter(metaConfigLog, UTF_8.name())) { + writer.print(ObjectId.zeroId().name()); + writer.print(" "); + writer.print(metaConfigId.name()); + writer.print(" "); + writer.print(serverUser.toExternalString()); + writer.print("\t"); + writer.print("create reflog"); + writer.println(); + } + } + } finally { + repo.close(); + } + } catch (IOException e) { + ui.message(String.format("ERROR: Failed to create reflog file for the" + + " %s branch in repository %s", RefNames.REFS_CONFIG, project.get())); + } + } + ui.message("done"); + } +}