fix issue with absolute paths while adding files
Project: http://git-wip-us.apache.org/repos/asf/maven-scm/repo Commit: http://git-wip-us.apache.org/repos/asf/maven-scm/commit/6ca4c9c4 Tree: http://git-wip-us.apache.org/repos/asf/maven-scm/tree/6ca4c9c4 Diff: http://git-wip-us.apache.org/repos/asf/maven-scm/diff/6ca4c9c4 Branch: refs/heads/master Commit: 6ca4c9c43b2899ce283bfe2dfb61b943f7c762a5 Parents: aee511f Author: imod <d...@fortysix.ch> Authored: Thu Jun 20 16:45:37 2013 +0200 Committer: imod <d...@fortysix.ch> Committed: Thu Jun 20 16:45:37 2013 +0200 ---------------------------------------------------------------------- .../provider/git/jgit/command/JGitUtils.java | 314 +++++++++---------- .../git/jgit/command/add/JGitAddCommand.java | 84 ++--- .../command/checkin/JGitCheckInCommand.java | 35 +-- 3 files changed, 192 insertions(+), 241 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/maven-scm/blob/6ca4c9c4/src/main/java/org/apache/maven/scm/provider/git/jgit/command/JGitUtils.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/maven/scm/provider/git/jgit/command/JGitUtils.java b/src/main/java/org/apache/maven/scm/provider/git/jgit/command/JGitUtils.java index f272f46..ea9a600 100644 --- a/src/main/java/org/apache/maven/scm/provider/git/jgit/command/JGitUtils.java +++ b/src/main/java/org/apache/maven/scm/provider/git/jgit/command/JGitUtils.java @@ -1,36 +1,43 @@ package org.apache.maven.scm.provider.git.jgit.command; import java.io.File; +import java.io.IOException; +import java.net.URI; import java.util.ArrayList; import java.util.Collection; +import java.util.Iterator; import java.util.List; +import java.util.Set; -import org.apache.maven.scm.ScmBranch; import org.apache.maven.scm.ScmException; import org.apache.maven.scm.ScmFile; import org.apache.maven.scm.ScmFileSet; import org.apache.maven.scm.ScmFileStatus; -import org.apache.maven.scm.ScmTag; -import org.apache.maven.scm.ScmVersion; import org.apache.maven.scm.log.ScmLogger; import org.apache.maven.scm.provider.git.repository.GitScmProviderRepository; import org.codehaus.plexus.util.StringUtils; +import org.eclipse.jgit.api.AddCommand; import org.eclipse.jgit.api.Git; +import org.eclipse.jgit.api.Status; import org.eclipse.jgit.api.errors.GitAPIException; import org.eclipse.jgit.api.errors.InvalidRemoteException; +import org.eclipse.jgit.api.errors.NoFilepatternException; import org.eclipse.jgit.api.errors.TransportException; +import org.eclipse.jgit.diff.DiffEntry.ChangeType; +import org.eclipse.jgit.errors.CorruptObjectException; +import org.eclipse.jgit.errors.IncorrectObjectTypeException; +import org.eclipse.jgit.errors.MissingObjectException; import org.eclipse.jgit.lib.ProgressMonitor; +import org.eclipse.jgit.lib.Repository; import org.eclipse.jgit.lib.StoredConfig; import org.eclipse.jgit.lib.TextProgressMonitor; +import org.eclipse.jgit.revwalk.RevCommit; import org.eclipse.jgit.transport.CredentialsProvider; import org.eclipse.jgit.transport.PushResult; import org.eclipse.jgit.transport.RefSpec; import org.eclipse.jgit.transport.RemoteRefUpdate; -//import org.eclipse.jgit.simple.SimpleRepository; -//import org.eclipse.jgit.simple.StatusEntry; -//import org.eclipse.jgit.simple.StatusEntry.IndexStatus; -//import org.eclipse.jgit.simple.StatusEntry.RepoStatus; import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider; +import org.eclipse.jgit.treewalk.TreeWalk; /* * Licensed to the Apache Software Foundation (ASF) under one @@ -52,9 +59,10 @@ import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider; */ /** - * JGit SimpleRepository utility functions. + * JGit utility functions. * * @author <a href="mailto:strub...@yahoo.de">Mark Struberg</a> + * @author Dominik Bartholdi (imod) * @version $Id: JGitUtils.java 894145 2009-12-28 10:13:39Z struberg $ */ public class JGitUtils { @@ -73,15 +81,42 @@ public class JGitUtils { return new TextProgressMonitor(); } + /** + * Prepares the in memory configuration of git to connect to the configured + * repository. It configures the following settings in memory: <br /> + * <li>push url</li> <li>fetch url</li> + * <p /> + * + * @param logger + * used to log some details + * @param git + * the instance to configure (only in memory, not saved) + * @param repository + * the repo config to be used + * @return {@link CredentialsProvider} in case there are credentials + * informations configured in the repository. + */ public static CredentialsProvider prepareSession(ScmLogger logger, Git git, GitScmProviderRepository repository) { StoredConfig config = git.getRepository().getConfig(); config.setString("remote", "origin", "url", repository.getFetchUrl()); config.setString("remote", "origin", "pushURL", repository.getPushUrl()); + // make sure we do not log any passwords to the output logger.info("fetch url: " + repository.getFetchUrl().replace(repository.getPassword(), "******")); logger.info("push url: " + repository.getPushUrl().replace(repository.getPassword(), "******")); return getCredentials(repository); } + /** + * Creates a credentials provider from the information passed in the + * repository. Current implementation supports: <br /> + * <li>UserName/Password</li> + * <p /> + * + * @param repository + * the config to get the details from + * @return <code>null</code> if there is not enough info to create a + * provider with + */ public static CredentialsProvider getCredentials(GitScmProviderRepository repository) { if (StringUtils.isNotBlank(repository.getUser())) { return new UsernamePasswordCredentialsProvider(repository.getUser(), repository.getPassword()); @@ -101,157 +136,116 @@ public class JGitUtils { return pushResultList; } - // - // /** - // * Translate a {@code FileStatus} in the matching {@code ScmFileStatus}. - // * - // * @param status - // * @return the matching ScmFileStatus - // * @throws ScmException if the given Status cannot be translated - // */ - // public static ScmFileStatus getScmFileStatus( StatusEntry status ) - // throws ScmException - // { - // IndexStatus is = status.getIndexStatus(); - // RepoStatus rs = status.getRepoStatus(); - // - // if ( is.equals( IndexStatus.ADDED ) ) - // { - // return ScmFileStatus.ADDED; - // } - // else if ( is.equals( IndexStatus.UNCHANGED ) && rs.equals( - // RepoStatus.UNCHANGED ) ) - // { - // return ScmFileStatus.CHECKED_IN; - // } - // else if ( is.equals( IndexStatus.MODIFIED ) ) - // { - // return ScmFileStatus.MODIFIED; - // } - // else if ( is.equals( IndexStatus.DELETED ) && rs.equals( - // RepoStatus.REMOVED ) ) - // { - // return ScmFileStatus.DELETED; - // } - // else { - // return ScmFileStatus.UNKNOWN; - // } - // - // /*X - // switch (status) { - // case UNMERGED: - // return ScmFileStatus.CONFLICT; - // case OTHER: - // return ScmFileStatus.ADDED; - // default: - // - // } - // */ - // } - // - // /** - // * Get the branch name from the ScmVersion - // * @param scmVersion - // * @return branch name if the ScmVersion indicates a branch, with taking - // <code>"master"</code> - // * as default branch name. For tags <code>null</code> will be returned. - // */ - // public static String getBranchName( ScmVersion scmVersion ) - // { - // String branchName = "master"; - // - // // we explicitly request branches, since tags will be handled differently - // in git - // if (scmVersion instanceof ScmTag) { - // return null; - // } - // - // if (scmVersion instanceof ScmBranch) - // { - // branchName = scmVersion.getName(); - // } - // - // return branchName; - // } - // - // /** - // * get the tag name from the ScmVersion - // * @param scmVersion - // * @return tag name if the ScmVersion indicates a tag, <code>null</code> - // otherwise - // */ - // public static String getTagName( ScmVersion scmVersion ) - // { - // // we explicitly request branches, since tags will be handled differently - // in git - // if (scmVersion instanceof ScmTag) { - // return scmVersion.getName(); - // } - // - // return null; - // } - // - // /** - // * Add all files of the given fileSet to the SimpleRepository. - // * This will make all relative paths be under the repositories base - // directory. - // * - // * @param srep - // * @param fileSet - // * @throws Exception - // */ - // public static void addAllFiles( SimpleRepository srep, ScmFileSet fileSet - // ) - // throws Exception - // { - // @SuppressWarnings("unchecked") - // List<File> addFiles = fileSet.getFileList(); - // if ( addFiles != null ) - // { - // for ( File addFile : addFiles ) - // { - // if ( !addFile.isAbsolute() ) - // { - // addFile = new File( fileSet.getBasedir(), addFile.getPath() ); - // } - // - // srep.add( addFile, false ); - // } - // - // } - // } - // - // - // /** - // * Convert from List<StatusEntry> to List<ScmFile> - // * @param statusEntries - // * @param addUnknown if <code>false</code>, this function will not add - // files with 'unknown' status to the returned list - // * @return list with ScmFiles ready for use in ScmResult and other - // maven-scm APIs - // * @throws ScmException - // */ - // public static List<ScmFile> getChangedFiles( List<StatusEntry> - // statusEntries, boolean addUnknown ) - // throws ScmException - // { - // if ( statusEntries == null ) - // { - // return null; - // } - // - // List<ScmFile> changedFiles = new ArrayList<ScmFile>(); - // - // for ( StatusEntry statusEntry : statusEntries ) - // { - // ScmFileStatus status = getScmFileStatus( statusEntry ); - // if ( addUnknown || !status.equals( ScmFileStatus.UNKNOWN ) ) - // { - // changedFiles.add( new ScmFile( statusEntry.getFilePath(), status ) ); - // } - // - // } - // return changedFiles; - // } + /** + * Does the Repository have any commits? + * + * @param repo + * @return false if there are no commits + */ + public static boolean hasCommits(Repository repo) { + if (repo != null && repo.getDirectory().exists()) { + return (new File(repo.getDirectory(), "objects").list().length > 2) || (new File(repo.getDirectory(), "objects/pack").list().length > 0); + } + return false; + } + + /** + * get a list of all files in the given commit + * + * @param repository + * the repo + * @param commit + * the commit to get the files from + * @return a list of files included in the commit + * @throws MissingObjectException + * @throws IncorrectObjectTypeException + * @throws CorruptObjectException + * @throws IOException + */ + public static List<ScmFile> getFilesInCommit(Repository repository, RevCommit commit) throws MissingObjectException, IncorrectObjectTypeException, CorruptObjectException, IOException { + List<ScmFile> list = new ArrayList<ScmFile>(); + if (JGitUtils.hasCommits(repository)) { + TreeWalk tw = new TreeWalk(repository); + tw.reset(); + tw.setRecursive(true); + tw.addTree(commit.getTree()); + while (tw.next()) { + list.add(new ScmFile(tw.getPathString(), ScmFileStatus.CHECKED_IN)); + } + tw.release(); + } + return list; + } + /** + * Translate a {@code FileStatus} in the matching {@code ScmFileStatus}. + * + * @param status + * @return the matching ScmFileStatus + * @throws ScmException + * if the given Status cannot be translated + */ + public static ScmFileStatus getScmFileStatus(ChangeType changeType) throws ScmException { + switch (changeType) { + case ADD: + return ScmFileStatus.ADDED; + case MODIFY: + return ScmFileStatus.MODIFIED; + case DELETE: + return ScmFileStatus.DELETED; + case RENAME: + return ScmFileStatus.RENAMED; + case COPY: + return ScmFileStatus.COPIED; + default: + return ScmFileStatus.UNKNOWN; + } + } + + /** + * Adds all files in the given fileSet to the repository. + * + * @param git + * the repo to add the files to + * @param fileSet + * the set of files within the workspace, the files are added + * relative to the basedir of this fileset + * @return a list of files changed + * @throws GitAPIException + * @throws NoFilepatternException + */ + public static List<ScmFile> addAllFiles(Git git, ScmFileSet fileSet) throws GitAPIException, NoFilepatternException { + URI baseUri = fileSet.getBasedir().toURI(); + AddCommand add = git.add(); + for (File file : fileSet.getFileList()) { + if (file.exists()) { + String path = file.getPath(); + if (file.isAbsolute()) { + path = baseUri.relativize(new File(path).toURI()).getPath(); + } + add.addFilepattern(path); + } + } + add.call(); + + Status status = git.status().call(); + Set<String> changed = status.getChanged(); + + List<ScmFile> changedFiles = new ArrayList<ScmFile>(); + + // rewrite all detected files to now have status 'checked_in' + for (String entry : changed) { + ScmFile scmfile = new ScmFile(entry, ScmFileStatus.MODIFIED); + + // if a specific fileSet is given, we have to check if the file is + // really tracked + for (Iterator<File> itfl = fileSet.getFileList().iterator(); itfl.hasNext();) { + File f = (File) itfl.next(); + if (f.toString().equals(scmfile.getPath())) { + changedFiles.add(scmfile); + } + } + } + return changedFiles; + } } http://git-wip-us.apache.org/repos/asf/maven-scm/blob/6ca4c9c4/src/main/java/org/apache/maven/scm/provider/git/jgit/command/add/JGitAddCommand.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/maven/scm/provider/git/jgit/command/add/JGitAddCommand.java b/src/main/java/org/apache/maven/scm/provider/git/jgit/command/add/JGitAddCommand.java index 6737ba9..2c3692b 100644 --- a/src/main/java/org/apache/maven/scm/provider/git/jgit/command/add/JGitAddCommand.java +++ b/src/main/java/org/apache/maven/scm/provider/git/jgit/command/add/JGitAddCommand.java @@ -19,88 +19,48 @@ package org.apache.maven.scm.provider.git.jgit.command.add; * under the License. */ -import java.io.File; -import java.util.ArrayList; -import java.util.Iterator; import java.util.List; -import java.util.Set; import org.apache.maven.scm.ScmException; import org.apache.maven.scm.ScmFile; import org.apache.maven.scm.ScmFileSet; -import org.apache.maven.scm.ScmFileStatus; import org.apache.maven.scm.ScmResult; import org.apache.maven.scm.command.add.AbstractAddCommand; import org.apache.maven.scm.command.add.AddScmResult; import org.apache.maven.scm.provider.ScmProviderRepository; import org.apache.maven.scm.provider.git.command.GitCommand; -import org.apache.maven.scm.provider.git.repository.GitScmProviderRepository; -import org.eclipse.jgit.api.AddCommand; +import org.apache.maven.scm.provider.git.jgit.command.JGitUtils; import org.eclipse.jgit.api.Git; -import org.eclipse.jgit.api.Status; /** * @author <a href="mailto:strub...@yahoo.de">Mark Struberg</a> + * @author Dominik Bartholdi (imod) * @version $Id: JGitAddCommand.java 894145 2009-12-28 10:13:39Z struberg $ */ -public class JGitAddCommand - extends AbstractAddCommand - implements GitCommand -{ - /** {@inheritDoc} */ - protected ScmResult executeAddCommand( ScmProviderRepository repo, ScmFileSet fileSet, String message, - boolean binary ) - throws ScmException - { - GitScmProviderRepository repository = (GitScmProviderRepository) repo; +public class JGitAddCommand extends AbstractAddCommand implements GitCommand { + /** {@inheritDoc} */ + protected ScmResult executeAddCommand(ScmProviderRepository repo, ScmFileSet fileSet, String message, boolean binary) throws ScmException { - if ( fileSet.getFileList().isEmpty() ) - { - throw new ScmException( "You must provide at least one file/directory to add (e.g. -Dincludes=...)" ); - } - try - { - Git git = Git.open(fileSet.getBasedir()); - AddCommand add = git.add(); - for (File file : fileSet.getFileList()) { - add.addFilepattern(file.getPath()); + if (fileSet.getFileList().isEmpty()) { + throw new ScmException("You must provide at least one file/directory to add (e.g. -Dincludes=...)"); + } + try { + Git git = Git.open(fileSet.getBasedir()); + + List<ScmFile> addedFiles = JGitUtils.addAllFiles(git, fileSet); + + if (getLogger().isDebugEnabled()) { + for (ScmFile scmFile : addedFiles) { + getLogger().info("added file: " + scmFile); + } } - add.call(); - - - // git-add doesn't show single files, but only summary - // so we must run git-status - - Status status = git.status().call(); - Set<String> changed = status.getChanged(); -// List<StatusEntry> entries = srep.status(); - - List<ScmFile> changedFiles = new ArrayList<ScmFile>(); + return new AddScmResult("JGit add", addedFiles); - // rewrite all detected files to now have status 'checked_in' - for ( String entry : changed ) - { - ScmFile scmfile = new ScmFile( entry, ScmFileStatus.MODIFIED ); + } catch (Exception e) { + throw new ScmException("JGit add failure!", e); + } - // if a specific fileSet is given, we have to check if the file is really tracked - for ( Iterator<File> itfl = fileSet.getFileList().iterator(); itfl.hasNext(); ) - { - File f = (File) itfl.next(); - if ( f.toString().equals( scmfile.getPath() ) ) - { - changedFiles.add( scmfile ); - } - } - } - return new AddScmResult( "JGit add", changedFiles ); - - } - catch ( Exception e ) - { - throw new ScmException("JGit add failure!", e ); - } - - } + } } http://git-wip-us.apache.org/repos/asf/maven-scm/blob/6ca4c9c4/src/main/java/org/apache/maven/scm/provider/git/jgit/command/checkin/JGitCheckInCommand.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/maven/scm/provider/git/jgit/command/checkin/JGitCheckInCommand.java b/src/main/java/org/apache/maven/scm/provider/git/jgit/command/checkin/JGitCheckInCommand.java index ae42d19..006db40 100644 --- a/src/main/java/org/apache/maven/scm/provider/git/jgit/command/checkin/JGitCheckInCommand.java +++ b/src/main/java/org/apache/maven/scm/provider/git/jgit/command/checkin/JGitCheckInCommand.java @@ -20,7 +20,7 @@ package org.apache.maven.scm.provider.git.jgit.command.checkin; */ import java.io.File; -import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Set; @@ -37,17 +37,12 @@ import org.apache.maven.scm.provider.git.repository.GitScmProviderRepository; import org.codehaus.plexus.util.StringUtils; import org.eclipse.jgit.api.AddCommand; import org.eclipse.jgit.api.Git; -import org.eclipse.jgit.api.PushCommand; -import org.eclipse.jgit.lib.StoredConfig; import org.eclipse.jgit.revwalk.RevCommit; -import org.eclipse.jgit.transport.CredentialsProvider; import org.eclipse.jgit.transport.RefSpec; -import org.eclipse.jgit.transport.RemoteConfig; -import org.eclipse.jgit.transport.URIish; -import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider; /** * @author <a href="mailto:strub...@yahoo.de">Mark Struberg</a> + * @author Dominik Bartholdi (imod) * @version $Id: JGitCheckInCommand.java 894145 2009-12-28 10:13:39Z struberg $ */ public class JGitCheckInCommand extends AbstractCheckInCommand implements GitCommand { @@ -55,16 +50,13 @@ public class JGitCheckInCommand extends AbstractCheckInCommand implements GitCom protected CheckInScmResult executeCheckInCommand(ScmProviderRepository repo, ScmFileSet fileSet, String message, ScmVersion version) throws ScmException { try { - Git git = Git.open(fileSet.getBasedir()); + File basedir = fileSet.getBasedir(); + Git git = Git.open(basedir); boolean doCommit = false; + if (!fileSet.getFileList().isEmpty()) { - AddCommand add = git.add(); - for (File file : fileSet.getFileList()) { - doCommit = true; - add.addFilepattern(file.getPath()); - } - add.call(); + doCommit = JGitUtils.addAllFiles(git, fileSet).size() > 0; } else { // add all tracked files which are modified manually Set<String> changeds = git.status().call().getModified(); @@ -75,6 +67,7 @@ public class JGitCheckInCommand extends AbstractCheckInCommand implements GitCom } else { AddCommand add = git.add(); for (String changed : changeds) { + getLogger().debug("add manualy: " + changed); add.addFilepattern(changed); doCommit = true; } @@ -82,9 +75,16 @@ public class JGitCheckInCommand extends AbstractCheckInCommand implements GitCom } } + List<ScmFile> checkedInFiles = Collections.emptyList(); if (doCommit) { - RevCommit call = git.commit().setMessage(message).call(); - getLogger().info("commit done: " + call.getShortMessage()); + RevCommit commitRev = git.commit().setMessage(message).call(); + getLogger().info("commit done: " + commitRev.getShortMessage()); + checkedInFiles = JGitUtils.getFilesInCommit(git.getRepository(), commitRev); + if (getLogger().isDebugEnabled()) { + for (ScmFile scmFile : checkedInFiles) { + getLogger().debug("in commit: " + scmFile); + } + } } if (repo.isPushChanges()) { @@ -97,9 +97,6 @@ public class JGitCheckInCommand extends AbstractCheckInCommand implements GitCom JGitUtils.push(getLogger(), git, (GitScmProviderRepository) repo, refSpec); } - List<ScmFile> checkedInFiles = new ArrayList<ScmFile>(); - // TODO get a list of the commited files - return new CheckInScmResult("JGit checkin", checkedInFiles); } catch (Exception e) { throw new ScmException("JGit checkin failure!", e);