Signed-off-by: Florian Koeberle <florianskarten@xxxxxx> --- .../jgit/lib/fileiteration/AddRuleListFactory.java | 128 ++++++++++++++++++++ 1 files changed, 128 insertions(+), 0 deletions(-) create mode 100644 org.spearce.jgit/src/org/spearce/jgit/lib/fileiteration/AddRuleListFactory.java diff --git a/org.spearce.jgit/src/org/spearce/jgit/lib/fileiteration/AddRuleListFactory.java b/org.spearce.jgit/src/org/spearce/jgit/lib/fileiteration/AddRuleListFactory.java new file mode 100644 index 0000000..9d2f942 --- /dev/null +++ b/org.spearce.jgit/src/org/spearce/jgit/lib/fileiteration/AddRuleListFactory.java @@ -0,0 +1,128 @@ +/* + * Copyright (C) 2008 Florian Köberle + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License, version 2, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 + */ +package org.spearce.jgit.lib.fileiteration; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +import org.spearce.jgit.errors.InvalidPatternException; +import org.spearce.jgit.errors.PathNotInProjectDirectoryException; + +class AddRuleListFactory { + /* + * The add command of git 1.5.2.5 behaves a little bit stange: "git add + * a/\*z" adds the file "a/b/xyz" but "git add a/x\*" does not. + * + * The first is parsed as pattern "*z" for whole directory tree "a". The + * second is parsed as an path. + * + */ + + private static List<String> getRelativePath(File projectDirectory, File file) + throws PathNotInProjectDirectoryException, IOException { + File currentFile = file.getCanonicalFile(); + final LinkedList<String> relativePath = new LinkedList<String>(); + while (!currentFile.equals(projectDirectory)) { + relativePath.addFirst(currentFile.getName()); + currentFile = currentFile.getParentFile(); + if (currentFile == null) { + throw new PathNotInProjectDirectoryException(); + } + } + return relativePath; + } + + List<Rule> createRuleList(File projectDirectory, File workingDirectory, + List<String> filePatternsOfAddCommand) + throws InvalidPatternException, PathNotInProjectDirectoryException, + IOException { + + final List<String> pathPrefix = getRelativePath(projectDirectory, + workingDirectory); + + final List<Rule> ruleList = new ArrayList<Rule>( + filePatternsOfAddCommand.size()); + for (String pattern : filePatternsOfAddCommand) { + final boolean matchDirectoriesOnly; + if (pattern.endsWith(File.separator)) { + pattern = pattern.substring(0, pattern.length() - 1); + matchDirectoriesOnly = true; + } else { + matchDirectoriesOnly = false; + } + + final String[] relativePath = pattern.split("[" + File.separator + + "]"); + final List<String> path = new ArrayList<String>(); + path.addAll(pathPrefix); + path.addAll(Arrays.asList(relativePath)); + assert (!path.isEmpty()); + + final FilePattern filePattern = createFilePattern(pattern, + matchDirectoriesOnly, path); + final Rule rule = new Rule(false, filePattern); + ruleList.add(rule); + + } + return ruleList; + } + + private static FilePattern createFilePattern(String pattern, + boolean matchDirectoriesOnly, List<String> path) + throws InvalidPatternException { + /* + * I did several tests with the git-add command, and it seems that it + * handles a pattern as a fileGlob, if it has only one star at the + * beginning of the latest part of the path. Otherwise it handle it as + * file pattern. + */ + + final String lastPathElement = path.get(path.size() - 1); + final boolean isFileGlob = lastPathElement.startsWith("*"); + final FilePattern filePattern; + if (isFileGlob) { + filePattern = createGlobalOrTreeFilePattern(matchDirectoriesOnly, + path, lastPathElement); + } else { + for (String pathElement : path) { + if (pathElement.contains("*")) { + throw new InvalidPatternException( + "Stars are not allowed here", pattern); + } + } + filePattern = new ComplexFilePattern(path, matchDirectoriesOnly); + } + return filePattern; + } + + private static FilePattern createGlobalOrTreeFilePattern( + final boolean matchDirectoriesOnly, final List<String> path, + final String lastPathElement) { + final GlobalFilePattern globalFilePatternForTree = new GlobalFilePattern( + lastPathElement, matchDirectoriesOnly); + final List<String> targetTree = path.subList(0, path.size() - 1); + if (targetTree.isEmpty()) { + return globalFilePatternForTree; + } else { + return new TreeFilePattern(targetTree, globalFilePatternForTree); + } + } +} -- 1.5.2.5 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html