diff options
Diffstat (limited to 'org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java')
-rw-r--r-- | org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java | 193 |
1 files changed, 109 insertions, 84 deletions
diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java b/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java index 9690f799c1..2a8d34ed68 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/api/LogCommand.java @@ -1,54 +1,18 @@ /* - * Copyright (C) 2010, Christian Halstrick <christian.halstrick@sap.com> - * and other copyright owners as documented in the project's IP log. + * Copyright (C) 2010, Christian Halstrick <christian.halstrick@sap.com> and others * - * This program and the accompanying materials are made available - * under the terms of the Eclipse Distribution License v1.0 which - * accompanies this distribution, is reproduced below, and is - * available at http://www.eclipse.org/org/documents/edl-v10.php + * This program and the accompanying materials are made available under the + * terms of the Eclipse Distribution License v. 1.0 which is available at + * https://www.eclipse.org/org/documents/edl-v10.php. * - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * - * - Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * - Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * - * - Neither the name of the Eclipse Foundation, Inc. nor the - * names of its contributors may be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND - * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; - * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER - * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * SPDX-License-Identifier: BSD-3-Clause */ package org.eclipse.jgit.api; -import static org.eclipse.jgit.lib.RefDatabase.ALL; - import java.io.IOException; import java.text.MessageFormat; import java.util.ArrayList; import java.util.List; -import java.util.Map; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.api.errors.JGitInternalException; @@ -65,6 +29,7 @@ import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.revwalk.RevWalk; import org.eclipse.jgit.revwalk.filter.AndRevFilter; import org.eclipse.jgit.revwalk.filter.MaxCountRevFilter; +import org.eclipse.jgit.revwalk.filter.RevFilter; import org.eclipse.jgit.revwalk.filter.SkipRevFilter; import org.eclipse.jgit.treewalk.filter.AndTreeFilter; import org.eclipse.jgit.treewalk.filter.PathFilter; @@ -77,7 +42,7 @@ import org.eclipse.jgit.treewalk.filter.TreeFilter; * to finally execute the command. Each instance of this class should only be * used for one invocation of the command (means: one call to {@link #call()}) * <p> - * Examples (<code>git</code> is a {@link Git} instance): + * Examples (<code>git</code> is a {@link org.eclipse.jgit.api.Git} instance): * <p> * Get newest 10 commits, starting from the current branch: * @@ -88,13 +53,11 @@ import org.eclipse.jgit.treewalk.filter.TreeFilter; * </pre> * <p> * - * <p> * Get commits only for a specific file: * * <pre> * git.log().add(head).addPath("dir/filename.txt").call(); * </pre> - * <p> * * @see <a href="http://www.kernel.org/pub/software/scm/git/docs/git-log.html" * >Git documentation about Log</a> @@ -104,14 +67,20 @@ public class LogCommand extends GitCommand<Iterable<RevCommit>> { private boolean startSpecified = false; - private final List<PathFilter> pathFilters = new ArrayList<PathFilter>(); + private RevFilter revFilter; + + private final List<PathFilter> pathFilters = new ArrayList<>(); + private final List<TreeFilter> excludeTreeFilters = new ArrayList<>(); private int maxCount = -1; private int skip = -1; /** + * Constructor for LogCommand. + * * @param repo + * the {@link org.eclipse.jgit.lib.Repository} */ protected LogCommand(Repository repo) { super(repo); @@ -119,21 +88,33 @@ public class LogCommand extends GitCommand<Iterable<RevCommit>> { } /** + * {@inheritDoc} + * <p> * Executes the {@code Log} command with all the options and parameters * collected by the setter methods (e.g. {@link #add(AnyObjectId)}, * {@link #not(AnyObjectId)}, ..) of this class. Each instance of this class * should only be used for one invocation of the command. Don't call this * method twice on an instance. - * - * @return an iteration over RevCommits - * @throws NoHeadException - * of the references ref cannot be resolved */ + @Override public Iterable<RevCommit> call() throws GitAPIException, NoHeadException { checkCallable(); - if (pathFilters.size() > 0) - walk.setTreeFilter(AndTreeFilter.create( - PathFilterGroup.create(pathFilters), TreeFilter.ANY_DIFF)); + List<TreeFilter> filters = new ArrayList<>(); + if (!pathFilters.isEmpty()) { + filters.add(AndTreeFilter.create(PathFilterGroup.create(pathFilters), TreeFilter.ANY_DIFF)); + } + if (!excludeTreeFilters.isEmpty()) { + for (TreeFilter f : excludeTreeFilters) { + filters.add(AndTreeFilter.create(f, TreeFilter.ANY_DIFF)); + } + } + if (!filters.isEmpty()) { + if (filters.size() == 1) { + walk.setTreeFilter(filters.get(0)); + } else { + walk.setTreeFilter(AndTreeFilter.create(filters)); + } + } if (skip > -1 && maxCount > -1) walk.setRevFilter(AndRevFilter.create(SkipRevFilter.create(skip), MaxCountRevFilter.create(maxCount))); @@ -156,6 +137,11 @@ public class LogCommand extends GitCommand<Iterable<RevCommit>> { e); } } + + if (this.revFilter != null) { + walk.setRevFilter(this.revFilter); + } + setCallable(false); return walk; } @@ -165,23 +151,26 @@ public class LogCommand extends GitCommand<Iterable<RevCommit>> { * * @see RevWalk#markStart(RevCommit) * @param start + * the id of the commit to start from * @return {@code this} - * @throws MissingObjectException + * @throws org.eclipse.jgit.errors.MissingObjectException * the commit supplied is not available from the object * database. This usually indicates the supplied commit is * invalid, but the reference was constructed during an earlier - * invocation to {@link RevWalk#lookupCommit(AnyObjectId)}. - * @throws IncorrectObjectTypeException + * invocation to + * {@link org.eclipse.jgit.revwalk.RevWalk#lookupCommit(AnyObjectId)}. + * @throws org.eclipse.jgit.errors.IncorrectObjectTypeException * the object was not parsed yet and it was discovered during * parsing that it is not actually a commit. This usually * indicates the caller supplied a non-commit SHA-1 to - * {@link RevWalk#lookupCommit(AnyObjectId)}. + * {@link org.eclipse.jgit.revwalk.RevWalk#lookupCommit(AnyObjectId)}. * @throws JGitInternalException * a low-level exception of JGit has occurred. The original * exception can be retrieved by calling - * {@link Exception#getCause()}. Expect only + * {@link java.lang.Exception#getCause()}. Expect only * {@code IOException's} to be wrapped. Subclasses of - * {@link IOException} (e.g. {@link MissingObjectException}) are + * {@link java.io.IOException} (e.g. + * {@link org.eclipse.jgit.errors.MissingObjectException}) are * typically not wrapped here but thrown as original exception */ public LogCommand add(AnyObjectId start) throws MissingObjectException, @@ -193,23 +182,26 @@ public class LogCommand extends GitCommand<Iterable<RevCommit>> { * Same as {@code --not start}, or {@code ^start} * * @param start + * a {@link org.eclipse.jgit.lib.AnyObjectId} * @return {@code this} - * @throws MissingObjectException + * @throws org.eclipse.jgit.errors.MissingObjectException * the commit supplied is not available from the object * database. This usually indicates the supplied commit is * invalid, but the reference was constructed during an earlier - * invocation to {@link RevWalk#lookupCommit(AnyObjectId)}. - * @throws IncorrectObjectTypeException + * invocation to + * {@link org.eclipse.jgit.revwalk.RevWalk#lookupCommit(AnyObjectId)}. + * @throws org.eclipse.jgit.errors.IncorrectObjectTypeException * the object was not parsed yet and it was discovered during * parsing that it is not actually a commit. This usually * indicates the caller supplied a non-commit SHA-1 to - * {@link RevWalk#lookupCommit(AnyObjectId)}. + * {@link org.eclipse.jgit.revwalk.RevWalk#lookupCommit(AnyObjectId)}. * @throws JGitInternalException * a low-level exception of JGit has occurred. The original * exception can be retrieved by calling - * {@link Exception#getCause()}. Expect only + * {@link java.lang.Exception#getCause()}. Expect only * {@code IOException's} to be wrapped. Subclasses of - * {@link IOException} (e.g. {@link MissingObjectException}) are + * {@link java.io.IOException} (e.g. + * {@link org.eclipse.jgit.errors.MissingObjectException}) are * typically not wrapped here but thrown as original exception */ public LogCommand not(AnyObjectId start) throws MissingObjectException, @@ -221,24 +213,28 @@ public class LogCommand extends GitCommand<Iterable<RevCommit>> { * Adds the range {@code since..until} * * @param since + * a {@link org.eclipse.jgit.lib.AnyObjectId} object. * @param until + * a {@link org.eclipse.jgit.lib.AnyObjectId} object. * @return {@code this} - * @throws MissingObjectException + * @throws org.eclipse.jgit.errors.MissingObjectException * the commit supplied is not available from the object * database. This usually indicates the supplied commit is * invalid, but the reference was constructed during an earlier - * invocation to {@link RevWalk#lookupCommit(AnyObjectId)}. - * @throws IncorrectObjectTypeException + * invocation to + * {@link org.eclipse.jgit.revwalk.RevWalk#lookupCommit(AnyObjectId)}. + * @throws org.eclipse.jgit.errors.IncorrectObjectTypeException * the object was not parsed yet and it was discovered during * parsing that it is not actually a commit. This usually * indicates the caller supplied a non-commit SHA-1 to - * {@link RevWalk#lookupCommit(AnyObjectId)}. + * {@link org.eclipse.jgit.revwalk.RevWalk#lookupCommit(AnyObjectId)}. * @throws JGitInternalException * a low-level exception of JGit has occurred. The original * exception can be retrieved by calling - * {@link Exception#getCause()}. Expect only + * {@link java.lang.Exception#getCause()}. Expect only * {@code IOException's} to be wrapped. Subclasses of - * {@link IOException} (e.g. {@link MissingObjectException}) are + * {@link java.io.IOException} (e.g. + * {@link org.eclipse.jgit.errors.MissingObjectException}) are * typically not wrapped here but thrown as original exception */ public LogCommand addRange(AnyObjectId since, AnyObjectId until) @@ -251,14 +247,13 @@ public class LogCommand extends GitCommand<Iterable<RevCommit>> { * * @see #add(AnyObjectId) * @return {@code this} - * @throws IOException + * @throws java.io.IOException * the references could not be accessed */ public LogCommand all() throws IOException { - Map<String, Ref> refs = getRepository().getRefDatabase().getRefs(ALL); - for (Ref ref : refs.values()) { + for (Ref ref : getRepository().getRefDatabase().getRefs()) { if(!ref.isPeeled()) - ref = getRepository().peel(ref); + ref = getRepository().getRefDatabase().peel(ref); ObjectId objectId = ref.getPeeledObjectId(); if (objectId == null) @@ -266,13 +261,11 @@ public class LogCommand extends GitCommand<Iterable<RevCommit>> { RevCommit commit = null; try { commit = walk.parseCommit(objectId); - } catch (MissingObjectException e) { - // ignore: the ref points to an object that does not exist; - // it should be ignored as traversal starting point. - } catch (IncorrectObjectTypeException e) { - // ignore: the ref points to an object that is not a commit - // (e.g. a tree or a blob); - // it should be ignored as traversal starting point. + } catch (MissingObjectException | IncorrectObjectTypeException e) { + // ignore as traversal starting point: + // - the ref points to an object that does not exist + // - the ref points to an object that is not a commit (e.g. a + // tree or a blob) } if (commit != null) add(commit); @@ -296,6 +289,24 @@ public class LogCommand extends GitCommand<Iterable<RevCommit>> { } /** + * Show all commits that are not within any of the specified paths. The path + * must either name a file or a directory exactly and use <code>/</code> + * (slash) as separator. Note that regular expressions or wildcards are not + * yet supported. If a path is both added and excluded from the search, then + * the exclusion wins. + * + * @param path + * a repository-relative path (with <code>/</code> as separator) + * @return {@code this} + * @since 5.6 + */ + public LogCommand excludePath(String path) { + checkCallable(); + excludeTreeFilters.add(PathFilter.create(path).negate()); + return this; + } + + /** * Skip the number of commits before starting to show the commit output. * * @param skip @@ -332,9 +343,7 @@ public class LogCommand extends GitCommand<Iterable<RevCommit>> { } else walk.markUninteresting(walk.lookupCommit(start)); return this; - } catch (MissingObjectException e) { - throw e; - } catch (IncorrectObjectTypeException e) { + } catch (MissingObjectException | IncorrectObjectTypeException e) { throw e; } catch (IOException e) { throw new JGitInternalException(MessageFormat.format( @@ -342,4 +351,20 @@ public class LogCommand extends GitCommand<Iterable<RevCommit>> { , start), e); } } + + + /** + * Set a filter for the <code>LogCommand</code>. + * + * @param aFilter + * the filter that this instance of <code>LogCommand</code> + * should use + * @return {@code this} + * @since 4.4 + */ + public LogCommand setRevFilter(RevFilter aFilter) { + checkCallable(); + this.revFilter = aFilter; + return this; + } } |