@@ -8,6 +8,8 @@ import * as _ from 'lodash';
88
99const blameMatcher = / ^ ( [ \^ 0 - 9 a - f A - F ] { 8 } ) \s ( [ \S ] * ) \s + ( [ 0 - 9 \S ] + ) \s \( ( .* ) \s ( [ 0 - 9 ] { 4 } - [ 0 - 9 ] { 2 } - [ 0 - 9 ] { 2 } \s [ 0 - 9 ] { 2 } : [ 0 - 9 ] { 2 } : [ 0 - 9 ] { 2 } \s [ - | + ] [ 0 - 9 ] { 4 } ) \s + ( [ 0 - 9 ] + ) \) ( .* ) $ / gm;
1010const commitMessageMatcher = / ^ ( [ \^ 0 - 9 a - f A - F ] { 7 } ) \s ( .* ) $ / gm;
11+ const blamePorcelainMatcher = / ^ ( [ \^ 0 - 9 a - f A - F ] { 40 } ) \s ( [ 0 - 9 ] + ) \s ( [ 0 - 9 ] + ) (?: \s ( [ 0 - 9 ] + ) ) ? $ \n (?: ^ a u t h o r \s ( .* ) $ \n ^ a u t h o r - m a i l \s ( .* ) $ \n ^ a u t h o r - t i m e \s ( .* ) $ \n ^ a u t h o r - t z \s ( .* ) $ \n ^ c o m m i t t e r \s ( .* ) $ \n ^ c o m m i t t e r - m a i l \s ( .* ) $ \n ^ c o m m i t t e r - t i m e \s ( .* ) $ \n ^ c o m m i t t e r - t z \s ( .* ) $ \n ^ s u m m a r y \s ( .* ) $ \n (?: ^ p r e v i o u s \s ( .* ) ? \s ( .* ) $ \n ) ? ^ f i l e n a m e \s ( .* ) $ \n ) ? ^ ( .* ) $ / gm;
12+ const blameLinePorcelainMatcher = / ^ ( [ \^ 0 - 9 a - f A - F ] { 40 } ) \s ( [ 0 - 9 ] + ) \s ( [ 0 - 9 ] + ) (?: \s ( [ 0 - 9 ] + ) ) ? $ \n ^ a u t h o r \s ( .* ) $ \n ^ a u t h o r - m a i l \s ( .* ) $ \n ^ a u t h o r - t i m e \s ( .* ) $ \n ^ a u t h o r - t z \s ( .* ) $ \n ^ c o m m i t t e r \s ( .* ) $ \n ^ c o m m i t t e r - m a i l \s ( .* ) $ \n ^ c o m m i t t e r - t i m e \s ( .* ) $ \n ^ c o m m i t t e r - t z \s ( .* ) $ \n ^ s u m m a r y \s ( .* ) $ \n (?: ^ p r e v i o u s \s ( .* ) ? \s ( .* ) $ \n ) ? ^ f i l e n a m e \s ( .* ) $ \n ^ ( .* ) $ / gm;
1113
1214export default class GitProvider extends Disposable {
1315 public repoPath : string ;
@@ -43,53 +45,138 @@ export default class GitProvider extends Disposable {
4345 return Git . repoPath ( cwd ) ;
4446 }
4547
48+ // getBlameForFile(fileName: string) {
49+ // fileName = Git.normalizePath(fileName, this.repoPath);
50+
51+ // let blame = this._blames.get(fileName);
52+ // if (blame !== undefined) return blame;
53+
54+ // blame = Git.blame(fileName, this.repoPath)
55+ // .then(data => {
56+ // const authors: Map<string, IGitAuthor> = new Map();
57+ // const commits: Map<string, IGitCommit> = new Map();
58+ // const lines: Array<IGitCommitLine> = [];
59+
60+ // let m: Array<string>;
61+ // while ((m = blameMatcher.exec(data)) != null) {
62+ // const authorName = m[4].trim();
63+ // let author = authors.get(authorName);
64+ // if (!author) {
65+ // author = {
66+ // name: authorName,
67+ // lineCount: 0
68+ // };
69+ // authors.set(authorName, author);
70+ // }
71+
72+ // const sha = m[1];
73+ // let commit = commits.get(sha);
74+ // if (!commit) {
75+ // commit = {
76+ // sha,
77+ // fileName: fileName,
78+ // author: authorName,
79+ // date: new Date(m[5]),
80+ // lines: []
81+ // };
82+
83+ // const file = m[2].trim();
84+ // if (!fileName.toLowerCase().endsWith(file.toLowerCase())) {
85+ // commit.originalFileName = file;
86+ // }
87+
88+ // commits.set(sha, commit);
89+ // }
90+
91+ // const line: IGitCommitLine = {
92+ // sha,
93+ // line: parseInt(m[6], 10) - 1,
94+ // originalLine: parseInt(m[3], 10) - 1
95+ // //code: m[7]
96+ // }
97+
98+ // commit.lines.push(line);
99+ // lines.push(line);
100+ // }
101+
102+ // commits.forEach(c => authors.get(c.author).lineCount += c.lines.length);
103+
104+ // const sortedAuthors: Map<string, IGitAuthor> = new Map();
105+ // const values = Array.from(authors.values())
106+ // .sort((a, b) => b.lineCount - a.lineCount)
107+ // .forEach(a => sortedAuthors.set(a.name, a));
108+
109+ // const sortedCommits = new Map();
110+ // Array.from(commits.values())
111+ // .sort((a, b) => b.date.getTime() - a.date.getTime())
112+ // .forEach(c => sortedCommits.set(c.sha, c));
113+
114+ // return {
115+ // authors: sortedAuthors,
116+ // commits: sortedCommits,
117+ // lines: lines
118+ // };
119+ // });
120+
121+ // this._blames.set(fileName, blame);
122+ // return blame;
123+ // }
124+
46125 getBlameForFile ( fileName : string ) {
47126 fileName = Git . normalizePath ( fileName , this . repoPath ) ;
48127
49128 let blame = this . _blames . get ( fileName ) ;
50129 if ( blame !== undefined ) return blame ;
51130
52- blame = Git . blame ( fileName , this . repoPath )
131+ blame = Git . blamePorcelain ( fileName , this . repoPath )
53132 . then ( data => {
54133 const authors : Map < string , IGitAuthor > = new Map ( ) ;
55134 const commits : Map < string , IGitCommit > = new Map ( ) ;
56135 const lines : Array < IGitCommitLine > = [ ] ;
57136
58137 let m : Array < string > ;
59- while ( ( m = blameMatcher . exec ( data ) ) != null ) {
60- const authorName = m [ 4 ] . trim ( ) ;
61- let author = authors . get ( authorName ) ;
62- if ( ! author ) {
63- author = {
64- name : authorName ,
65- lineCount : 0
66- } ;
67- authors . set ( authorName , author ) ;
68- }
69-
70- const sha = m [ 1 ] ;
138+ while ( ( m = blamePorcelainMatcher . exec ( data ) ) != null ) {
139+ const sha = m [ 1 ] . substring ( 0 , 8 ) ;
71140 let commit = commits . get ( sha ) ;
72141 if ( ! commit ) {
142+ const authorName = m [ 5 ] . trim ( ) ;
143+ let author = authors . get ( authorName ) ;
144+ if ( ! author ) {
145+ author = {
146+ name : authorName ,
147+ lineCount : 0
148+ } ;
149+ authors . set ( authorName , author ) ;
150+ }
151+
73152 commit = {
74153 sha,
75154 fileName : fileName ,
76- author : m [ 4 ] . trim ( ) ,
77- date : new Date ( m [ 5 ] ) ,
155+ author : authorName ,
156+ date : moment ( `${ m [ 7 ] } ${ m [ 8 ] } ` , 'X Z' ) . toDate ( ) ,
157+ message : m [ 13 ] ,
78158 lines : [ ]
79159 } ;
160+
161+ const originalFileName = m [ 16 ] ;
162+ if ( ! fileName . toLowerCase ( ) . endsWith ( originalFileName . toLowerCase ( ) ) ) {
163+ commit . originalFileName = originalFileName ;
164+ }
165+
166+ const previousSha = m [ 14 ] ;
167+ if ( previousSha ) {
168+ commit . previousSha = previousSha . substring ( 0 , 8 ) ;
169+ commit . previousFileName = m [ 15 ] ;
170+ }
171+
80172 commits . set ( sha , commit ) ;
81173 }
82174
83175 const line : IGitCommitLine = {
84176 sha,
85- line : parseInt ( m [ 6 ] , 10 ) - 1 ,
86- originalLine : parseInt ( m [ 3 ] , 10 ) - 1
87- //code: m[7]
88- }
89-
90- const file = m [ 2 ] . trim ( ) ;
91- if ( ! fileName . toLowerCase ( ) . endsWith ( file . toLowerCase ( ) ) ) {
92- line . originalFileName = file ;
177+ line : parseInt ( m [ 3 ] , 10 ) - 1 ,
178+ originalLine : parseInt ( m [ 2 ] , 10 ) - 1
179+ //code: m[17]
93180 }
94181
95182 commit . lines . push ( line ) ;
@@ -116,8 +203,7 @@ export default class GitProvider extends Disposable {
116203 } ) ;
117204
118205 this . _blames . set ( fileName , blame ) ;
119- return blame ;
120- }
206+ return blame ; }
121207
122208 getBlameForLine ( fileName : string , line : number ) : Promise < IGitBlameLine > {
123209 return this . getBlameForFile ( fileName ) . then ( blame => {
@@ -192,8 +278,8 @@ export default class GitProvider extends Disposable {
192278 Array . from ( blame . commits . values ( ) )
193279 . forEach ( ( c , i ) => {
194280 const uri = this . toBlameUri ( c , i + 1 , commitCount , range ) ;
195- c . lines . forEach ( l => locations . push ( new Location ( l . originalFileName
196- ? this . toBlameUri ( c , i + 1 , commitCount , range , l . originalFileName )
281+ c . lines . forEach ( l => locations . push ( new Location ( c . originalFileName
282+ ? this . toBlameUri ( c , i + 1 , commitCount , range , c . originalFileName )
197283 : uri ,
198284 new Position ( l . originalLine , 0 ) ) ) ) ;
199285 } ) ;
@@ -202,6 +288,24 @@ export default class GitProvider extends Disposable {
202288 } ) ;
203289 }
204290
291+ // getHistoryLocations(fileName: string, range: Range) {
292+ // return this.getBlameForRange(fileName, range).then(blame => {
293+ // const commitCount = blame.commits.size;
294+
295+ // const locations: Array<Location> = [];
296+ // Array.from(blame.commits.values())
297+ // .forEach((c, i) => {
298+ // const uri = this.toBlameUri(c, i + 1, commitCount, range);
299+ // c.lines.forEach(l => locations.push(new Location(c.originalFileName
300+ // ? this.toBlameUri(c, i + 1, commitCount, range, c.originalFileName)
301+ // : uri,
302+ // new Position(l.originalLine, 0))));
303+ // });
304+
305+ // return locations;
306+ // });
307+ // }
308+
205309 getCommitMessage ( sha : string ) {
206310 return Git . getCommitMessage ( sha , this . repoPath ) ;
207311 }
@@ -303,15 +407,17 @@ export interface IGitCommit {
303407 fileName : string ;
304408 author : string ;
305409 date : Date ;
410+ message : string ;
306411 lines : IGitCommitLine [ ] ;
307- message ?: string ;
412+ originalFileName ?: string ;
413+ previousSha ?: string ;
414+ previousFileName ?: string ;
308415}
309416
310417export interface IGitCommitLine {
311418 sha : string ;
312419 line : number ;
313420 originalLine : number ;
314- originalFileName ?: string ;
315421 code ?: string ;
316422}
317423
0 commit comments