/** * This file is part of git-as-svn. It is subject to the license terms * in the LICENSE file found in the top-level directory of this distribution * and at http://www.gnu.org/licenses/gpl-2.0.html. No part of git-as-svn, * including this file, may be copied, modified, propagated, or distributed * except according to the terms contained in the LICENSE file. */ package svnserver.repository.git; import org.eclipse.jgit.lib.ObjectId; import org.eclipse.jgit.lib.PersonIdent; import org.eclipse.jgit.revwalk.RevCommit; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.tmatesoft.svn.core.SVNException; import org.tmatesoft.svn.core.SVNRevisionProperty; import svnserver.SvnConstants; import svnserver.repository.VcsCopyFrom; import svnserver.repository.VcsRevision; import java.io.IOException; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.TreeMap; import java.util.concurrent.TimeUnit; /** * Git revision. * * @author Artem V. Navrotskiy <bozaro@users.noreply.github.com> */ public final class GitRevision implements VcsRevision { @NotNull private final GitRepository repo; @NotNull private final ObjectId cacheCommit; @Nullable private final RevCommit gitOldCommit; @Nullable private final RevCommit gitNewCommit; @NotNull private final Map<String, VcsCopyFrom> renames; private final long date; private final int revision; public GitRevision(@NotNull GitRepository repo, @NotNull ObjectId cacheCommit, int revision, @NotNull Map<String, VcsCopyFrom> renames, @Nullable RevCommit gitOldCommit, @Nullable RevCommit gitNewCommit, int commitTimeSec) { this.repo = repo; this.cacheCommit = cacheCommit; this.revision = revision; this.renames = renames; this.gitOldCommit = gitOldCommit; this.gitNewCommit = gitNewCommit; this.date = TimeUnit.SECONDS.toMillis(commitTimeSec); } @NotNull public ObjectId getCacheCommit() { return cacheCommit; } @Override public int getId() { return revision; } @Nullable public RevCommit getGitNewCommit() { return gitNewCommit; } @NotNull @Override public Map<String, GitLogEntry> getChanges() throws IOException, SVNException { if (gitNewCommit == null) { return Collections.emptyMap(); } final GitFile oldTree = gitOldCommit == null ? new GitFileEmptyTree(repo, "", revision - 1) : GitFileTreeEntry.create(repo, gitOldCommit.getTree(), revision - 1); final GitFile newTree = GitFileTreeEntry.create(repo, gitNewCommit.getTree(), revision); final Map<String, GitLogEntry> changes = new TreeMap<>(); for (Map.Entry<String, GitLogPair> entry : ChangeHelper.collectChanges(oldTree, newTree, false).entrySet()) { changes.put(entry.getKey(), new GitLogEntry(entry.getValue(), renames)); } return changes; } @NotNull @Override public Map<String, String> getProperties(boolean includeInternalProps) { final Map<String, String> props = new HashMap<>(); if (includeInternalProps) { putProperty(props, SVNRevisionProperty.AUTHOR, getAuthor()); putProperty(props, SVNRevisionProperty.LOG, getLog()); putProperty(props, SVNRevisionProperty.DATE, getDateString()); } if (gitNewCommit != null) { props.put(SvnConstants.PROP_GIT, gitNewCommit.name()); } return props; } private void putProperty(@NotNull Map<String, String> props, @NotNull String name, @Nullable String value) { if (value != null) { props.put(name, value); } } @Override public long getDate() { return date; } @Nullable @Override public String getAuthor() { if (gitNewCommit == null) return null; final PersonIdent ident = gitNewCommit.getAuthorIdent(); return String.format("%s <%s>", ident.getName(), ident.getEmailAddress()); } @Nullable @Override public String getLog() { return gitNewCommit == null ? null : gitNewCommit.getFullMessage().trim(); } @Nullable @Override public GitFile getFile(@NotNull String fullPath) throws IOException, SVNException { if (gitNewCommit == null) { return new GitFileEmptyTree(repo, "", revision); } GitFile result = GitFileTreeEntry.create(repo, gitNewCommit.getTree(), revision); for (String pathItem : fullPath.split("/")) { if (pathItem.isEmpty()) { continue; } result = result.getEntry(pathItem); if (result == null) { return null; } } return result; } @Nullable @Override public VcsCopyFrom getCopyFrom(@NotNull String fullPath) { return renames.get(fullPath); } }