1 package org.apache.maven.scm.provider.git.jgit.command.diff;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.scm.ScmException;
23 import org.apache.maven.scm.ScmFileSet;
24 import org.apache.maven.scm.ScmVersion;
25 import org.apache.maven.scm.command.diff.AbstractDiffCommand;
26 import org.apache.maven.scm.command.diff.DiffScmResult;
27 import org.apache.maven.scm.provider.ScmProviderRepository;
28 import org.apache.maven.scm.provider.git.command.GitCommand;
29 import org.apache.maven.scm.provider.git.command.diff.GitDiffConsumer;
30 import org.apache.maven.scm.provider.git.jgit.command.JGitUtils;
31 import org.codehaus.plexus.util.StringUtils;
32 import org.eclipse.jgit.api.Git;
33 import org.eclipse.jgit.api.errors.GitAPIException;
34 import org.eclipse.jgit.lib.ObjectId;
35 import org.eclipse.jgit.lib.ObjectReader;
36 import org.eclipse.jgit.lib.Repository;
37 import org.eclipse.jgit.revwalk.RevWalk;
38 import org.eclipse.jgit.treewalk.AbstractTreeIterator;
39 import org.eclipse.jgit.treewalk.CanonicalTreeParser;
40
41 import java.io.ByteArrayOutputStream;
42 import java.io.IOException;
43 import java.io.OutputStream;
44
45
46
47
48
49 public class JGitDiffCommand
50 extends AbstractDiffCommand
51 implements GitCommand
52 {
53
54 @Override
55 protected DiffScmResult executeDiffCommand( ScmProviderRepository repository, ScmFileSet fileSet,
56 ScmVersion startRevision, ScmVersion endRevision )
57 throws ScmException
58 {
59
60 Git git = null;
61 try
62 {
63 git = Git.open( fileSet.getBasedir() );
64 DiffScmResult diff = callDiff( git, startRevision, endRevision );
65 git.getRepository().close();
66 return diff;
67 }
68 catch ( Exception e )
69 {
70 throw new ScmException( "JGit diff failure!", e );
71 }
72 finally
73 {
74 JGitUtils.closeRepo( git );
75 }
76 }
77
78 public DiffScmResult callDiff( Git git, ScmVersion startRevision, ScmVersion endRevision )
79 throws IOException, GitAPIException, ScmException
80 {
81
82 AbstractTreeIterator oldTree = null;
83 if ( startRevision != null && StringUtils.isNotEmpty( startRevision.getName().trim() ) )
84 {
85 String startRev = startRevision.getName().trim();
86 oldTree = getTreeIterator( git.getRepository(), startRev );
87 }
88
89 AbstractTreeIterator newTree = null;
90 if ( endRevision != null && StringUtils.isNotEmpty( endRevision.getName().trim() ) )
91 {
92 String endRev = endRevision.getName().trim();
93 newTree = getTreeIterator( git.getRepository(), endRev );
94 }
95
96 OutputStream out = new ByteArrayOutputStream();
97
98 git.diff().setOutputStream( out ).setOldTree( oldTree ).setNewTree( newTree ).setCached( false ).call();
99 git.diff().setOutputStream( out ).setOldTree( oldTree ).setNewTree( newTree ).setCached( true ).call();
100
101 out.flush();
102
103 GitDiffConsumer consumer = new GitDiffConsumer( getLogger(), null );
104 String fullDiff = out.toString();
105 out.close();
106
107 String[] lines = fullDiff.split( "\n" );
108 for ( String aLine : lines )
109 {
110 consumer.consumeLine( aLine );
111 }
112
113 return new DiffScmResult( "JGit diff", consumer.getChangedFiles(), consumer.getDifferences(),
114 consumer.getPatch() );
115 }
116
117 private AbstractTreeIterator getTreeIterator( Repository repo, String name )
118 throws IOException
119 {
120 final ObjectId id = repo.resolve( name );
121 if ( id == null )
122 {
123 throw new IllegalArgumentException( name );
124 }
125 final CanonicalTreeParser p = new CanonicalTreeParser();
126 final ObjectReader or = repo.newObjectReader();
127 try
128 {
129 p.reset( or, new RevWalk( repo ).parseTree( id ) );
130 return p;
131 }
132 finally
133 {
134 or.release();
135 }
136 }
137 }