Allow filtering of the status. Only files which match given paths are inspected and only their state is reported. Change-Id: I3c4b1b46bf297cd4ebdb4997cfa14c8752a36411 Signed-off-by: Christian Halstrick <christian.halstrick@sap.com> Signed-off-by: Chris Aniszczyk <caniszczyk@gmail.com>tags/v3.1.0.201309270735-rc1
import java.util.Map; | import java.util.Map; | ||||
import org.eclipse.jgit.api.Git; | import org.eclipse.jgit.api.Git; | ||||
import org.eclipse.jgit.api.StatusCommand; | |||||
import org.eclipse.jgit.lib.Constants; | import org.eclipse.jgit.lib.Constants; | ||||
import org.eclipse.jgit.lib.IndexDiff.StageState; | import org.eclipse.jgit.lib.IndexDiff.StageState; | ||||
import org.eclipse.jgit.lib.Ref; | import org.eclipse.jgit.lib.Ref; | ||||
import org.eclipse.jgit.lib.Repository; | import org.eclipse.jgit.lib.Repository; | ||||
import org.eclipse.jgit.pgm.internal.CLIText; | import org.eclipse.jgit.pgm.internal.CLIText; | ||||
import org.kohsuke.args4j.Option; | |||||
@Command(usage = "usage_Status", common = true) | @Command(usage = "usage_Status", common = true) | ||||
class Status extends TextBuiltin { | class Status extends TextBuiltin { | ||||
protected final String statusFileListFormatUnmerged = CLIText.get().statusFileListFormatUnmerged; | protected final String statusFileListFormatUnmerged = CLIText.get().statusFileListFormatUnmerged; | ||||
@Option(name = "--", metaVar = "metaVar_path", multiValued = true) | |||||
protected List<String> filterPaths; | |||||
@Override | @Override | ||||
protected void run() throws Exception { | protected void run() throws Exception { | ||||
// Print current branch name | // Print current branch name | ||||
} else | } else | ||||
outw.println(CLIText.formatLine(CLIText.get().notOnAnyBranch)); | outw.println(CLIText.formatLine(CLIText.get().notOnAnyBranch)); | ||||
// List changes | // List changes | ||||
org.eclipse.jgit.api.Status status = new Git(db).status().call(); | |||||
StatusCommand statusCommand = new Git(db).status(); | |||||
if (filterPaths != null && filterPaths.size() > 0) | |||||
for (String path : filterPaths) | |||||
statusCommand.addPath(path); | |||||
org.eclipse.jgit.api.Status status = statusCommand.call(); | |||||
Collection<String> added = status.getAdded(); | Collection<String> added = status.getAdded(); | ||||
Collection<String> changed = status.getChanged(); | Collection<String> changed = status.getChanged(); | ||||
Collection<String> removed = status.getRemoved(); | Collection<String> removed = status.getRemoved(); |
assertTrue(stat.getUntrackedFolders().contains("sub")); | assertTrue(stat.getUntrackedFolders().contains("sub")); | ||||
} | } | ||||
@Test | |||||
public void testDifferentStatesWithPaths() throws IOException, | |||||
NoFilepatternException, GitAPIException { | |||||
Git git = new Git(db); | |||||
writeTrashFile("a", "content of a"); | |||||
writeTrashFile("D/b", "content of b"); | |||||
writeTrashFile("D/c", "content of c"); | |||||
writeTrashFile("D/D/d", "content of d"); | |||||
git.add().addFilepattern(".").call(); | |||||
writeTrashFile("a", "new content of a"); | |||||
writeTrashFile("D/b", "new content of b"); | |||||
writeTrashFile("D/D/d", "new content of d"); | |||||
// filter on an not existing path | |||||
Status stat = git.status().addPath("x").call(); | |||||
assertEquals(0, stat.getModified().size()); | |||||
// filter on an existing file | |||||
stat = git.status().addPath("a").call(); | |||||
assertEquals(set("a"), stat.getModified()); | |||||
// filter on an existing folder | |||||
stat = git.status().addPath("D").call(); | |||||
assertEquals(set("D/b", "D/D/d"), stat.getModified()); | |||||
// filter on an existing folder and file | |||||
stat = git.status().addPath("D/D").addPath("a").call(); | |||||
assertEquals(set("a", "D/D/d"), stat.getModified()); | |||||
// do not filter at all | |||||
stat = git.status().call(); | |||||
assertEquals(set("a", "D/b", "D/D/d"), stat.getModified()); | |||||
} | |||||
public static Set<String> set(String... elements) { | public static Set<String> set(String... elements) { | ||||
Set<String> ret = new HashSet<String>(); | Set<String> ret = new HashSet<String>(); | ||||
for (String element : elements) | for (String element : elements) |
package org.eclipse.jgit.api; | package org.eclipse.jgit.api; | ||||
import java.io.IOException; | import java.io.IOException; | ||||
import java.util.LinkedList; | |||||
import java.util.List; | |||||
import org.eclipse.jgit.api.errors.GitAPIException; | import org.eclipse.jgit.api.errors.GitAPIException; | ||||
import org.eclipse.jgit.api.errors.JGitInternalException; | import org.eclipse.jgit.api.errors.JGitInternalException; | ||||
import org.eclipse.jgit.lib.Repository; | import org.eclipse.jgit.lib.Repository; | ||||
import org.eclipse.jgit.treewalk.FileTreeIterator; | import org.eclipse.jgit.treewalk.FileTreeIterator; | ||||
import org.eclipse.jgit.treewalk.WorkingTreeIterator; | import org.eclipse.jgit.treewalk.WorkingTreeIterator; | ||||
import org.eclipse.jgit.treewalk.filter.PathFilterGroup; | |||||
/** | /** | ||||
* A class used to execute a {@code Status} command. It has setters for all | * A class used to execute a {@code Status} command. It has setters for all | ||||
*/ | */ | ||||
public class StatusCommand extends GitCommand<Status> { | public class StatusCommand extends GitCommand<Status> { | ||||
private WorkingTreeIterator workingTreeIt; | private WorkingTreeIterator workingTreeIt; | ||||
private List<String> paths = null; | |||||
/** | /** | ||||
* @param repo | * @param repo | ||||
super(repo); | super(repo); | ||||
} | } | ||||
/** | |||||
* Show only the status of files which match the given paths. The path must | |||||
* either name a file or a directory exactly. All paths are always relative | |||||
* to the repository root. If a directory is specified all files recursively | |||||
* underneath that directory are matched. If this method is called multiple | |||||
* times then the status of those files is reported which match at least one | |||||
* of the given paths. Note that regex expressions or wildcards are not | |||||
* supported. | |||||
* | |||||
* @param path | |||||
* a path is relative to the top level of the repository | |||||
* @return {@code this} | |||||
*/ | |||||
public StatusCommand addPath(String path) { | |||||
if (paths == null) | |||||
paths = new LinkedList<String>(); | |||||
paths.add(path); | |||||
return this; | |||||
} | |||||
/** | |||||
* Returns the paths filtering this status. | |||||
* | |||||
* @return the paths for which the status is shown or <code>null</code> if | |||||
* the complete status for the whole repo is shown. | |||||
*/ | |||||
public List<String> getPaths() { | |||||
return paths; | |||||
} | |||||
/** | /** | ||||
* Executes the {@code Status} command with all the options and parameters | * Executes the {@code Status} command with all the options and parameters | ||||
* collected by the setter methods of this class. Each instance of this | * collected by the setter methods of this class. Each instance of this | ||||
try { | try { | ||||
IndexDiff diff = new IndexDiff(repo, Constants.HEAD, workingTreeIt); | IndexDiff diff = new IndexDiff(repo, Constants.HEAD, workingTreeIt); | ||||
if (paths != null) | |||||
diff.setFilter(PathFilterGroup.createFromStrings(paths)); | |||||
diff.diff(); | diff.diff(); | ||||
return new Status(diff); | return new Status(diff); | ||||
} catch (IOException e) { | } catch (IOException e) { |