11import { Disposable , ExtensionContext , Location , Position , Range , Uri , workspace } from 'vscode' ;
22import { DocumentSchemes , WorkspaceState } from './constants' ;
3- import { gitBlame } from './git' ;
4- import { basename , dirname , extname , join } from 'path' ;
3+ import { gitBlame , gitNormalizePath } from './git' ;
4+ import { basename , dirname , extname } from 'path' ;
55import * as moment from 'moment' ;
66import * as _ from 'lodash' ;
77
@@ -29,46 +29,53 @@ export default class GitBlameProvider extends Disposable {
2929 super . dispose ( ) ;
3030 }
3131
32- blameFile ( fileName : string ) {
32+ blameFile ( fileName : string , repoPath : string ) {
33+ fileName = gitNormalizePath ( fileName , repoPath ) ;
34+
3335 let blame = this . _files . get ( fileName ) ;
3436 if ( blame !== undefined ) return blame ;
3537
36- blame = gitBlame ( fileName )
38+ blame = gitBlame ( fileName , repoPath )
3739 . then ( data => {
3840 const commits : Map < string , IGitBlameCommit > = new Map ( ) ;
3941 const lines : Array < IGitBlameLine > = [ ] ;
4042 let m : Array < string > ;
4143 while ( ( m = blameMatcher . exec ( data ) ) != null ) {
4244 let sha = m [ 1 ] ;
45+
4346 if ( ! commits . has ( sha ) ) {
4447 commits . set ( sha , {
4548 sha,
46- fileName : m [ 2 ] . trim ( ) ,
49+ fileName : fileName ,
4750 author : m [ 4 ] . trim ( ) ,
4851 date : new Date ( m [ 5 ] )
4952 } ) ;
5053 }
5154
52- lines . push ( {
55+ const line : IGitBlameLine = {
5356 sha,
57+ line : parseInt ( m [ 6 ] , 10 ) - 1 ,
5458 originalLine : parseInt ( m [ 3 ] , 10 ) - 1 ,
55- line : parseInt ( m [ 6 ] , 10 ) - 1
5659 //code: m[7]
57- } ) ;
60+ }
61+
62+ let file = m [ 2 ] . trim ( ) ;
63+ if ( ! fileName . toLowerCase ( ) . endsWith ( file . toLowerCase ( ) ) ) {
64+ line . originalFileName = file ;
65+ }
66+
67+ lines . push ( line ) ;
5868 }
5969
6070 return { commits, lines } ;
6171 } ) ;
62- // .catch(ex => {
63- // console.error(ex);
64- // });
6572
6673 this . _files . set ( fileName , blame ) ;
6774 return blame ;
6875 }
6976
70- getBlameForRange ( fileName : string , range : Range ) : Promise < IGitBlame > {
71- return this . blameFile ( fileName ) . then ( blame => {
77+ getBlameForRange ( fileName : string , repoPath : string , range : Range ) : Promise < IGitBlame > {
78+ return this . blameFile ( fileName , repoPath ) . then ( blame => {
7279 if ( ! blame . lines . length ) return blame ;
7380
7481 const lines = blame . lines . slice ( range . start . line , range . end . line + 1 ) ;
@@ -79,17 +86,17 @@ export default class GitBlameProvider extends Disposable {
7986 } ) ;
8087 }
8188
82- getBlameForShaRange ( fileName : string , sha : string , range : Range ) : Promise < { commit : IGitBlameCommit , lines : IGitBlameLine [ ] } > {
83- return this . blameFile ( fileName ) . then ( blame => {
89+ getBlameForShaRange ( fileName : string , repoPath : string , sha : string , range : Range ) : Promise < { commit : IGitBlameCommit , lines : IGitBlameLine [ ] } > {
90+ return this . blameFile ( fileName , repoPath ) . then ( blame => {
8491 return {
8592 commit : blame . commits . get ( sha ) ,
8693 lines : blame . lines . slice ( range . start . line , range . end . line + 1 ) . filter ( l => l . sha === sha )
8794 } ;
8895 } ) ;
8996 }
9097
91- getBlameLocations ( fileName : string , range : Range ) {
92- return this . getBlameForRange ( fileName , range ) . then ( blame => {
98+ getBlameLocations ( fileName : string , repoPath : string , range : Range ) {
99+ return this . getBlameForRange ( fileName , repoPath , range ) . then ( blame => {
93100 const commitCount = blame . commits . size ;
94101
95102 const locations : Array < Location > = [ ] ;
@@ -99,7 +106,10 @@ export default class GitBlameProvider extends Disposable {
99106 const uri = GitBlameProvider . toBlameUri ( this . repoPath , c , range , i + 1 , commitCount ) ;
100107 blame . lines
101108 . filter ( l => l . sha === c . sha )
102- . forEach ( l => locations . push ( new Location ( uri , new Position ( l . originalLine , 0 ) ) ) ) ;
109+ . forEach ( l => locations . push ( new Location ( l . originalFileName
110+ ? GitBlameProvider . toBlameUri ( this . repoPath , c , range , i + 1 , commitCount , l . originalFileName )
111+ : uri ,
112+ new Position ( l . originalLine , 0 ) ) ) ) ;
103113 } ) ;
104114
105115 return locations ;
@@ -110,12 +120,16 @@ export default class GitBlameProvider extends Disposable {
110120 this . _files . delete ( fileName ) ;
111121 }
112122
113- static toBlameUri ( repoPath : string , commit : IGitBlameCommit , range : Range , index : number , commitCount : number ) {
123+ static toBlameUri ( repoPath : string , commit : IGitBlameCommit , range : Range , index : number , commitCount : number , originalFileName ?: string ) {
114124 const pad = n => ( "0000000" + n ) . slice ( - ( "" + commitCount ) . length ) ;
115125
116- const ext = extname ( commit . fileName ) ;
117- const path = `${ dirname ( commit . fileName ) } /${ commit . sha } : ${ basename ( commit . fileName , ext ) } ${ ext } ` ;
118- const data : IGitBlameUriData = { fileName : join ( repoPath , commit . fileName ) , sha : commit . sha , range : range , index : index } ;
126+ const fileName = originalFileName || commit . fileName ;
127+ const ext = extname ( fileName ) ;
128+ const path = `${ dirname ( fileName ) } /${ commit . sha } : ${ basename ( fileName , ext ) } ${ ext } ` ;
129+ const data : IGitBlameUriData = { fileName : commit . fileName , sha : commit . sha , range : range , index : index } ;
130+ if ( originalFileName ) {
131+ data . originalFileName = originalFileName ;
132+ }
119133 // NOTE: Need to specify an index here, since I can't control the sort order -- just alphabetic or by file location
120134 return Uri . parse ( `${ DocumentSchemes . GitBlame } :${ pad ( index ) } . ${ commit . author } , ${ moment ( commit . date ) . format ( 'MMM D, YYYY hh:MMa' ) } - ${ path } ?${ JSON . stringify ( data ) } ` ) ;
121135 }
@@ -140,12 +154,14 @@ export interface IGitBlameCommit {
140154}
141155export interface IGitBlameLine {
142156 sha : string ;
143- originalLine : number ;
144157 line : number ;
158+ originalLine : number ;
159+ originalFileName ?: string ;
145160 code ?: string ;
146161}
147162export interface IGitBlameUriData {
148163 fileName : string ,
164+ originalFileName ?: string ;
149165 sha : string ,
150166 range : Range ,
151167 index : number
0 commit comments