33import static hudson .Util .fixEmpty ;
44
55import hudson .MarkupText ;
6- import hudson .Util ;
7- import hudson .model .Hudson ;
86import hudson .model .User ;
97import hudson .scm .ChangeLogAnnotator ;
108import hudson .scm .ChangeLogSet ;
3028 * @author Nigel Magnay
3129 */
3230public class GitChangeSet extends ChangeLogSet .Entry {
31+
32+ private static final String PREFIX_AUTHOR = "author " ;
33+ private static final String PREFIX_COMMITTER = "committer " ;
34+ private static final String IDENTITY = "(.*)<(.*)> (.*) (.*)" ;
35+
3336
3437 private static final Pattern FILE_LOG_ENTRY = Pattern .compile ("^:[0-9]{6} [0-9]{6} ([0-9a-f]{40}) ([0-9a-f]{40}) ([ACDMRTUX])(?>[0-9]+)?\t (.*)$" );
35- private static final Pattern AUTHOR_ENTRY = Pattern .compile ("^author (.*) <(.*)> (.*) (.*)$" );
36- private static final Pattern COMMITTER_ENTRY = Pattern .compile ("^committer (.*) <(.*)> (.*) (.*)$" );
38+ private static final Pattern AUTHOR_ENTRY = Pattern .compile ("^"
39+ + PREFIX_AUTHOR + IDENTITY + "$" );
40+ private static final Pattern COMMITTER_ENTRY = Pattern .compile ("^"
41+ + PREFIX_COMMITTER + IDENTITY + "$" );
3742 private static final Pattern RENAME_SPLIT = Pattern .compile ("^(.*?)\t (.*)$" );
3843
3944 private static final String NULL_HASH = "0000000000000000000000000000000000000000" ;
@@ -52,6 +57,12 @@ public class GitChangeSet extends ChangeLogSet.Entry {
5257 private Collection <Path > paths = new HashSet <Path >();
5358 private boolean authorOrCommitter ;
5459
60+ /**
61+ * Create Git change set using information in given lines
62+ *
63+ * @param lines
64+ * @param authorOrCommitter
65+ */
5566 public GitChangeSet (List <String > lines , boolean authorOrCommitter ) {
5667 this .authorOrCommitter = authorOrCommitter ;
5768 if (lines .size () > 0 ) {
@@ -61,78 +72,77 @@ public GitChangeSet(List<String> lines, boolean authorOrCommitter) {
6172
6273 private void parseCommit (List <String > lines ) {
6374
64- String message = "" ;
75+ StringBuilder message = new StringBuilder () ;
6576
6677 for (String line : lines ) {
67- if (line .length () > 0 ) {
68- if (line .startsWith ("commit " )) {
69- this .id = line .split (" " )[1 ];
70- } else if (line .startsWith ("tree " )) {
71- } else if (line .startsWith ("parent " )) {
72- this .parentCommit = line .split (" " )[1 ];
73- } else if (line .startsWith ("committer " )) {
74- Matcher committerMatcher = COMMITTER_ENTRY .matcher (line );
75- if (committerMatcher .matches () && committerMatcher .groupCount () >= 4 ) {
76- this .committer = committerMatcher .group (1 );
77- this .committerEmail = committerMatcher .group (2 );
78- this .committerTime = committerMatcher .group (3 );
79- this .committerTz = committerMatcher .group (4 );
80- }
81- } else if (line .startsWith ("author " )) {
82- Matcher authorMatcher = AUTHOR_ENTRY .matcher (line );
83- if (authorMatcher .matches () && authorMatcher .groupCount () >= 4 ) {
84- this .author = authorMatcher .group (1 );
85- this .authorEmail = authorMatcher .group (2 );
86- this .authorTime = authorMatcher .group (3 );
87- this .authorTz = authorMatcher .group (4 );
88- }
89- } else if (line .startsWith (" " )) {
90- message += line .substring (4 ) + "\n " ;
91- } else if (':' == line .charAt (0 )) {
92- Matcher fileMatcher = FILE_LOG_ENTRY .matcher (line );
93- if (fileMatcher .matches () && fileMatcher .groupCount () >= 4 ) {
94- String mode = fileMatcher .group (3 );
95- if (mode .length () == 1 ) {
96- String src = null ;
97- String dst = null ;
98- String path = fileMatcher .group (4 );
99- char editMode = mode .charAt (0 );
100- if (editMode == 'M' || editMode == 'A' || editMode == 'D'
101- || editMode == 'R' || editMode == 'C' ) {
102- src = parseHash (fileMatcher .group (1 ));
103- dst = parseHash (fileMatcher .group (2 ));
104- }
78+ if ( line .length () < 1 )
79+ continue ;
80+ if (line .startsWith ("commit " )) {
81+ this .id = line .split (" " )[1 ];
82+ } else if (line .startsWith ("tree " )) {
83+ } else if (line .startsWith ("parent " )) {
84+ this .parentCommit = line .split (" " )[1 ];
85+ } else if (line .startsWith (PREFIX_COMMITTER )) {
86+ Matcher committerMatcher = COMMITTER_ENTRY .matcher (line );
87+ if (committerMatcher .matches ()
88+ && committerMatcher .groupCount () >= 4 ) {
89+ this .committer = committerMatcher .group (1 ).trim ();
90+ this .committerEmail = committerMatcher .group (2 );
91+ this .committerTime = committerMatcher .group (3 );
92+ this .committerTz = committerMatcher .group (4 );
93+ }
94+ } else if (line .startsWith (PREFIX_AUTHOR )) {
95+ Matcher authorMatcher = AUTHOR_ENTRY .matcher (line );
96+ if (authorMatcher .matches () && authorMatcher .groupCount () >= 4 ) {
97+ this .author = authorMatcher .group (1 ).trim ();
98+ this .authorEmail = authorMatcher .group (2 );
99+ this .authorTime = authorMatcher .group (3 );
100+ this .authorTz = authorMatcher .group (4 );
101+ }
102+ } else if (line .startsWith (" " )) {
103+ message .append (line .substring (4 )).append ('\n' );
104+ } else if (':' == line .charAt (0 )) {
105+ Matcher fileMatcher = FILE_LOG_ENTRY .matcher (line );
106+ if (fileMatcher .matches () && fileMatcher .groupCount () >= 4 ) {
107+ String mode = fileMatcher .group (3 );
108+ if (mode .length () == 1 ) {
109+ String src = null ;
110+ String dst = null ;
111+ String path = fileMatcher .group (4 );
112+ char editMode = mode .charAt (0 );
113+ if (editMode == 'M' || editMode == 'A' || editMode == 'D'
114+ || editMode == 'R' || editMode == 'C' ) {
115+ src = parseHash (fileMatcher .group (1 ));
116+ dst = parseHash (fileMatcher .group (2 ));
117+ }
105118
106- // Handle rename as two operations - a delete and an add
107- if (editMode == 'R' ) {
108- Matcher renameSplitMatcher = RENAME_SPLIT .matcher (path );
109- if (renameSplitMatcher .matches () && renameSplitMatcher .groupCount () >= 2 ) {
110- String oldPath = renameSplitMatcher .group (1 );
111- String newPath = renameSplitMatcher .group (2 );
112- this .paths .add (new Path (src , dst , 'D' , oldPath , this ));
113- this .paths .add (new Path (src , dst , 'A' , newPath , this ));
114- }
115- }
116- // Handle copy as an add
117- else if (editMode == 'C' ) {
118- Matcher copySplitMatcher = RENAME_SPLIT .matcher (path );
119- if (copySplitMatcher .matches () && copySplitMatcher .groupCount () >= 2 ) {
120- String newPath = copySplitMatcher .group (2 );
121- this .paths .add (new Path (src , dst , 'A' , newPath , this ));
122- }
119+ // Handle rename as two operations - a delete and an add
120+ if (editMode == 'R' ) {
121+ Matcher renameSplitMatcher = RENAME_SPLIT .matcher (path );
122+ if (renameSplitMatcher .matches () && renameSplitMatcher .groupCount () >= 2 ) {
123+ String oldPath = renameSplitMatcher .group (1 );
124+ String newPath = renameSplitMatcher .group (2 );
125+ this .paths .add (new Path (src , dst , 'D' , oldPath , this ));
126+ this .paths .add (new Path (src , dst , 'A' , newPath , this ));
123127 }
124- else {
125- this .paths .add (new Path (src , dst , editMode , path , this ));
128+ }
129+ // Handle copy as an add
130+ else if (editMode == 'C' ) {
131+ Matcher copySplitMatcher = RENAME_SPLIT .matcher (path );
132+ if (copySplitMatcher .matches () && copySplitMatcher .groupCount () >= 2 ) {
133+ String newPath = copySplitMatcher .group (2 );
134+ this .paths .add (new Path (src , dst , 'A' , newPath , this ));
126135 }
127136 }
137+ else {
138+ this .paths .add (new Path (src , dst , editMode , path , this ));
139+ }
128140 }
129- } else {
130- // Ignore
131141 }
132142 }
133143 }
134144
135- this .comment = message ;
145+ this .comment = message . toString () ;
136146
137147 int endOfFirstLine = this .comment .indexOf ('\n' );
138148 if (endOfFirstLine == -1 ) {
@@ -227,7 +237,7 @@ public User getAuthor() {
227237 }
228238
229239 if (csAuthor == null ) {
230- throw new RuntimeException ("No author in this changeset!" );
240+ throw new RuntimeException ("No author in changeset " + id );
231241 }
232242
233243 User user = User .get (csAuthor , false );
@@ -251,25 +261,14 @@ public User getAuthor() {
251261 * Gets the author name for this changeset - note that this is mainly here
252262 * so that we can test authorOrCommitter without needing a fully instantiated
253263 * Hudson (which is needed for User.get in getAuthor()).
264+ *
265+ * @return author name
254266 */
255267 public String getAuthorName () {
256- String csAuthor ;
257- String csAuthorEmail ;
258-
259268 // If true, use the author field from git log rather than the committer.
260- if (authorOrCommitter ) {
261- csAuthor = this .author ;
262- csAuthorEmail = this .authorEmail ;
263- }
264- else {
265- csAuthor = this .committer ;
266- csAuthorEmail = this .committerEmail ;
267- }
268-
269- if (csAuthor == null ) {
270- throw new RuntimeException ("No author in this changeset!" );
271- }
272-
269+ String csAuthor = authorOrCommitter ? author : committer ;
270+ if (csAuthor == null )
271+ throw new RuntimeException ("No author in changeset " + id );
273272 return csAuthor ;
274273 }
275274
0 commit comments