View Javadoc
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 }