@@ -44,6 +44,8 @@ def initialize_(self, action):
44
44
Returns:
45
45
bool: True if successfully initialized
46
46
"""
47
+ self .fileFilters = action .applies_to
48
+ self .directory = self .getGlobals ().directory
47
49
return True
48
50
49
51
def gather_ (self , cachedContributors = []):
@@ -99,41 +101,53 @@ def gather_(self, cachedContributors=[]):
99
101
##################################################################################
100
102
101
103
def execGit (self ):
102
- cmd = [
104
+ fileFilterStr = " " .join (
105
+ [
106
+ "--exclude %s" % contributionTarget .target
107
+ for contributionTarget in self .fileFilters
108
+ ]
109
+ )
110
+ cmds = [
103
111
"git" ,
104
112
"ls-files" ,
105
- "|" ,
106
- "while read f;" ,
107
- 'do echo "%s$f";' % self .GITBLAMESEPERATOR ,
108
- "git blame -CCC --line-porcelain $f;" ,
109
- "done" ,
113
+ "--directory" , ### directory to look for files
114
+ self .directory ,
115
+ "--ignored" , ### only ls files matching the excluded files (via --exclude)
116
+ fileFilterStr , ### string containing patterns for all files that should be searched for
110
117
]
111
-
118
+ cmd = " " . join ( cmds )
112
119
ps = subprocess .Popen (
113
- " " . join ( cmd ) , shell = True , stdout = subprocess .PIPE , stderr = subprocess .STDOUT
120
+ cmd , shell = True , stdout = subprocess .PIPE , stderr = subprocess .STDOUT
114
121
)
115
122
stdout , stderr = ps .communicate ()
116
-
117
- fileContributions = {}
118
123
if not stderr :
124
+ ### encode output
119
125
encoded = stdout .decode ("utf-8" )
120
- ### split output for each file (we added "\n" manually to seperate each file output)
121
- fileblames = encoded .split (self .GITBLAMESEPERATOR )[
122
- 1 :
123
- ] ### 0 entry is empty because reasons ... :D
124
- for blame in fileblames :
125
- ### seperate lines into array
126
- lines = blame .split ("\n " )
127
- filename = lines [0 ]
128
- lines = lines [1 :]
129
- ### put lines through blameParser
130
- fileContributorDict = self .parseBlame (lines )
131
- ### filter out unwanted users, for example the one git blame adds
132
- ### in case there are uncommitted changes
133
- ### "<not.committed.yet>", "Not Committed Yet"
134
- if "not.committed.yet" in fileContributorDict :
135
- del fileContributorDict ["not.committed.yet" ]
136
- fileContributions [filename ] = fileContributorDict
126
+ fileList = encoded .split ("\n " )
127
+ ### exec git blame for each file
128
+ fileContributions = {}
129
+ for file in fileList :
130
+ cmd = "git blame -CCC --line-porcelain %s" % file
131
+ ps = subprocess .Popen (
132
+ cmd , shell = True , stdout = subprocess .PIPE , stderr = subprocess .STDOUT
133
+ )
134
+ stdout , stderr = ps .communicate ()
135
+ if not stderr :
136
+ try :
137
+ ### this can fail when blaming binary files for example, we skip those
138
+ encoded = stdout .decode ("utf-8" )
139
+ except UnicodeDecodeError as e :
140
+ continue
141
+ ### seperate lines into array
142
+ lines = encoded .split ("\n " )
143
+ ### put lines through blameParser
144
+ fileContributorDict = self .parseBlame (lines )
145
+ ### filter out unwanted users, for example the one git blame adds
146
+ ### in case there are uncommitted changes
147
+ ### "<not.committed.yet>", "Not Committed Yet"
148
+ if "not.committed.yet" in fileContributorDict :
149
+ del fileContributorDict ["not.committed.yet" ]
150
+ fileContributions [file ] = fileContributorDict
137
151
return fileContributions
138
152
139
153
def processFileContributorDict (self , fcDict ):
0 commit comments