1 /* 2 * Copyright (C) 2010, Google Inc. and others 3 * 4 * This program and the accompanying materials are made available under the 5 * terms of the Eclipse Distribution License v. 1.0 which is available at 6 * https://www.eclipse.org/org/documents/edl-v10.php. 7 * 8 * SPDX-License-Identifier: BSD-3-Clause 9 */ 10 11 package org.eclipse.jgit.revwalk; 12 13 import java.io.IOException; 14 15 import org.eclipse.jgit.diff.DiffConfig; 16 import org.eclipse.jgit.errors.IncorrectObjectTypeException; 17 import org.eclipse.jgit.errors.MissingObjectException; 18 import org.eclipse.jgit.treewalk.TreeWalk; 19 import org.eclipse.jgit.treewalk.filter.PathFilter; 20 import org.eclipse.jgit.treewalk.filter.TreeFilter; 21 22 /** 23 * Updates the internal path filter to follow copy/renames. 24 * <p> 25 * This is a special filter that performs {@code AND(path, ANY_DIFF)}, but also 26 * triggers rename detection so that the path node is updated to include a prior 27 * file name as the RevWalk traverses history. 28 * 29 * The renames found will be reported to a 30 * {@link org.eclipse.jgit.revwalk.RenameCallback} if one is set. 31 * <p> 32 * Results with this filter are unpredictable if the path being followed is a 33 * subdirectory. 34 */ 35 public class FollowFilter extends TreeFilter { 36 /** 37 * Create a new tree filter for a user supplied path. 38 * <p> 39 * Path strings are relative to the root of the repository. If the user's 40 * input should be assumed relative to a subdirectory of the repository the 41 * caller must prepend the subdirectory's path prior to creating the filter. 42 * <p> 43 * Path strings use '/' to delimit directories on all platforms. 44 * 45 * @param path 46 * the path to filter on. Must not be the empty string. All 47 * trailing '/' characters will be trimmed before string's length 48 * is checked or is used as part of the constructed filter. 49 * @param cfg 50 * diff config specifying rename detection options. 51 * @return a new filter for the requested path. 52 * @throws java.lang.IllegalArgumentException 53 * the path supplied was the empty string. 54 * @since 3.0 55 */ 56 public static FollowFilter create(String path, DiffConfig cfg) { 57 return new FollowFilter(PathFilter.create(path), cfg); 58 } 59 60 private final PathFilter path; 61 final DiffConfig cfg; 62 63 private RenameCallback renameCallback; 64 65 FollowFilter(PathFilter path, DiffConfig cfg) { 66 this.path = path; 67 this.cfg = cfg; 68 } 69 70 /** @return the path this filter matches. */ 71 /** 72 * Get the path this filter matches. 73 * 74 * @return the path this filter matches. 75 */ 76 public String getPath() { 77 return path.getPath(); 78 } 79 80 /** {@inheritDoc} */ 81 @Override 82 public boolean include(TreeWalk walker) 83 throws MissingObjectException, IncorrectObjectTypeException, 84 IOException { 85 return path.include(walker) && ANY_DIFF.include(walker); 86 } 87 88 /** {@inheritDoc} */ 89 @Override 90 public boolean shouldBeRecursive() { 91 return path.shouldBeRecursive() || ANY_DIFF.shouldBeRecursive(); 92 } 93 94 /** {@inheritDoc} */ 95 @Override 96 public TreeFilter clone() { 97 return new FollowFilter(path.clone(), cfg); 98 } 99 100 /** {@inheritDoc} */ 101 @SuppressWarnings("nls") 102 @Override 103 public String toString() { 104 return "(FOLLOW(" + path.toString() + ")" // 105 + " AND " // 106 + ANY_DIFF.toString() + ")"; 107 } 108 109 /** 110 * Get the callback to which renames are reported. 111 * 112 * @return the callback to which renames are reported, or <code>null</code> 113 * if none 114 */ 115 public RenameCallback getRenameCallback() { 116 return renameCallback; 117 } 118 119 /** 120 * Sets the callback to which renames shall be reported. 121 * 122 * @param callback 123 * the callback to use 124 */ 125 public void setRenameCallback(RenameCallback callback) { 126 renameCallback = callback; 127 } 128 }