diff --git a/Documentation/rest-api-projects.txt b/Documentation/rest-api-projects.txt index 351f766a32..fc8ccba929 100644 --- a/Documentation/rest-api-projects.txt +++ b/Documentation/rest-api-projects.txt @@ -832,6 +832,14 @@ Query the last 25 reflog entries. GET /projects/gerrit/branches/master/reflog?n=25 HTTP/1.0 ---- +The reflog can also be filtered by timestamp by specifying the `from` +and `to` parameters. The timestamp for `from` and `to` must be given as +UTC in the following format: `yyyyMMdd_HHmm`. + +---- + GET /projects/gerrit/branches/master/reflog?from=20130101_0000&to=20140101_0000=25 HTTP/1.0 +---- + [[child-project-endpoints]] == Child Project Endpoints diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/CmdLineParserModule.java b/gerrit-server/src/main/java/com/google/gerrit/server/CmdLineParserModule.java index 0e86d341ae..d10366eb34 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/CmdLineParserModule.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/CmdLineParserModule.java @@ -26,6 +26,7 @@ import com.google.gerrit.server.args4j.ObjectIdHandler; import com.google.gerrit.server.args4j.PatchSetIdHandler; import com.google.gerrit.server.args4j.ProjectControlHandler; import com.google.gerrit.server.args4j.SocketAddressHandler; +import com.google.gerrit.server.args4j.TimestampHandler; import com.google.gerrit.server.config.FactoryModule; import com.google.gerrit.server.project.ProjectControl; import com.google.gerrit.util.cli.CmdLineParser; @@ -35,6 +36,7 @@ import org.eclipse.jgit.lib.ObjectId; import org.kohsuke.args4j.spi.OptionHandler; import java.net.SocketAddress; +import java.sql.Timestamp; public class CmdLineParserModule extends FactoryModule { public CmdLineParserModule() { @@ -53,6 +55,7 @@ public class CmdLineParserModule extends FactoryModule { registerOptionHandler(PatchSet.Id.class, PatchSetIdHandler.class); registerOptionHandler(ProjectControl.class, ProjectControlHandler.class); registerOptionHandler(SocketAddress.class, SocketAddressHandler.class); + registerOptionHandler(Timestamp.class, TimestampHandler.class); } private void registerOptionHandler(Class type, diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/args4j/TimestampHandler.java b/gerrit-server/src/main/java/com/google/gerrit/server/args4j/TimestampHandler.java new file mode 100644 index 0000000000..8dd42703e1 --- /dev/null +++ b/gerrit-server/src/main/java/com/google/gerrit/server/args4j/TimestampHandler.java @@ -0,0 +1,61 @@ +// Copyright (C) 2014 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.args4j; + +import com.google.inject.Inject; +import com.google.inject.assistedinject.Assisted; + +import org.kohsuke.args4j.CmdLineException; +import org.kohsuke.args4j.CmdLineParser; +import org.kohsuke.args4j.OptionDef; +import org.kohsuke.args4j.spi.OptionHandler; +import org.kohsuke.args4j.spi.Parameters; +import org.kohsuke.args4j.spi.Setter; + +import java.sql.Timestamp; +import java.text.DateFormat; +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.TimeZone; + +public class TimestampHandler extends OptionHandler { + public final static String TIMESTAMP_FORMAT = "yyyyMMdd_HHmm"; + + @Inject + public TimestampHandler(@Assisted CmdLineParser parser, + @Assisted OptionDef option, @Assisted Setter setter) { + super(parser, option, setter); + } + + @Override + public int parseArguments(Parameters params) throws CmdLineException { + String timestamp = params.getParameter(0); + try { + DateFormat fmt = new SimpleDateFormat(TIMESTAMP_FORMAT); + fmt.setTimeZone(TimeZone.getTimeZone("UTC")); + setter.addValue(new Timestamp(fmt.parse(timestamp).getTime())); + return 1; + } catch (ParseException e) { + throw new CmdLineException(owner, + String.format("Invalid timestamp: %s; expected format: %s", + timestamp, TIMESTAMP_FORMAT), e); + } + } + + @Override + public String getDefaultMetaVariable() { + return "TIMESTAMP"; + } +} diff --git a/gerrit-server/src/main/java/com/google/gerrit/server/project/GetReflog.java b/gerrit-server/src/main/java/com/google/gerrit/server/project/GetReflog.java index b5308f83d8..b6415b5eaa 100644 --- a/gerrit-server/src/main/java/com/google/gerrit/server/project/GetReflog.java +++ b/gerrit-server/src/main/java/com/google/gerrit/server/project/GetReflog.java @@ -20,6 +20,7 @@ import com.google.gerrit.extensions.common.GitPerson; import com.google.gerrit.extensions.restapi.AuthException; import com.google.gerrit.extensions.restapi.ResourceNotFoundException; import com.google.gerrit.extensions.restapi.RestReadView; +import com.google.gerrit.server.args4j.TimestampHandler; import com.google.gerrit.server.git.GitRepositoryManager; import com.google.inject.Inject; @@ -32,6 +33,7 @@ import org.kohsuke.args4j.Option; import java.io.IOException; import java.sql.Timestamp; +import java.util.ArrayList; import java.util.List; public class GetReflog implements RestReadView { @@ -44,7 +46,25 @@ public class GetReflog implements RestReadView { return this; } + @Option(name = "--from", metaVar = "TIMESTAMP", + usage = "timestamp from which the reflog entries should be listed (UTC, format: " + + TimestampHandler.TIMESTAMP_FORMAT + ")") + public GetReflog setFrom(Timestamp from) { + this.from = from; + return this; + } + + @Option(name = "--to", metaVar = "TIMESTAMP", + usage = "timestamp until which the reflog entries should be listed (UTC, format: " + + TimestampHandler.TIMESTAMP_FORMAT + ")") + public GetReflog setTo(Timestamp to) { + this.to = to; + return this; + } + private int limit; + private Timestamp from; + private Timestamp to; @Inject public GetReflog(GitRepositoryManager repoManager) { @@ -64,8 +84,25 @@ public class GetReflog implements RestReadView { if (r == null) { throw new ResourceNotFoundException(rsrc.getRef()); } - List entries = - limit > 0 ? r.getReverseEntries(limit) : r.getReverseEntries(); + List entries; + if (from == null && to == null) { + entries = + limit > 0 ? r.getReverseEntries(limit) : r.getReverseEntries(); + } else { + entries = limit > 0 + ? new ArrayList(limit) + : new ArrayList(); + for (ReflogEntry e : r.getReverseEntries()) { + Timestamp timestamp = new Timestamp(e.getWho().getWhen().getTime()); + if ((from == null || from.before(timestamp)) && + (to == null || to.after(timestamp))) { + entries.add(e); + } + if (limit > 0 && entries.size() >= limit) { + break; + } + } + } return Lists.transform(entries, new Function() { @Override public ReflogEntryInfo apply(ReflogEntry e) {