@@ -108,8 +108,10 @@ type DiffFile struct {
108
108
// The type of the file.
109
109
Type DiffFileType
110
110
// The index (SHA1 hash) of the file. For a changed/new file, it is the new SHA,
111
- // and for a deleted file it is the old SHA .
111
+ // and for a deleted file it becomes "000000" .
112
112
Index string
113
+ // OldIndex is the old index (SHA1 hash) of the file.
114
+ OldIndex string
113
115
// The sections in the file.
114
116
Sections []* DiffSection
115
117
@@ -118,6 +120,9 @@ type DiffFile struct {
118
120
119
121
oldName string
120
122
123
+ mode EntryMode
124
+ oldMode EntryMode
125
+
121
126
isBinary bool
122
127
isSubmodule bool
123
128
isIncomplete bool
@@ -158,6 +163,16 @@ func (f *DiffFile) OldName() string {
158
163
return f .oldName
159
164
}
160
165
166
+ // Mode returns the mode of the file.
167
+ func (f * DiffFile ) Mode () EntryMode {
168
+ return f .mode
169
+ }
170
+
171
+ // OldMode returns the old mode of the file if it's changed.
172
+ func (f * DiffFile ) OldMode () EntryMode {
173
+ return f .oldMode
174
+ }
175
+
161
176
// IsBinary returns true if the file is in binary format.
162
177
func (f * DiffFile ) IsBinary () bool {
163
178
return f .isBinary
@@ -268,8 +283,9 @@ func (p *diffParser) parseFileHeader() (*DiffFile, error) {
268
283
}
269
284
270
285
file := & DiffFile {
271
- Name : a ,
272
- Type : DiffFileChange ,
286
+ Name : a ,
287
+ oldName : b ,
288
+ Type : DiffFileChange ,
273
289
}
274
290
275
291
// Check file diff type and submodule
@@ -291,20 +307,38 @@ checkType:
291
307
case strings .HasPrefix (line , "new file" ):
292
308
file .Type = DiffFileAdd
293
309
file .isSubmodule = strings .HasSuffix (line , " 160000" )
310
+ fields := strings .Fields (line )
311
+ if len (fields ) > 0 {
312
+ mode , _ := strconv .ParseUint (fields [len (fields )- 1 ], 8 , 64 )
313
+ file .mode = EntryMode (mode )
314
+ if file .oldMode == 0 {
315
+ file .oldMode = file .mode
316
+ }
317
+ }
294
318
case strings .HasPrefix (line , "deleted" ):
295
319
file .Type = DiffFileDelete
296
320
file .isSubmodule = strings .HasSuffix (line , " 160000" )
321
+ fields := strings .Fields (line )
322
+ if len (fields ) > 0 {
323
+ mode , _ := strconv .ParseUint (fields [len (fields )- 1 ], 8 , 64 )
324
+ file .mode = EntryMode (mode )
325
+ if file .oldMode == 0 {
326
+ file .oldMode = file .mode
327
+ }
328
+ }
297
329
case strings .HasPrefix (line , "index" ): // e.g. index ee791be..9997571 100644
298
330
fields := strings .Fields (line [6 :])
299
331
shas := strings .Split (fields [0 ], ".." )
300
332
if len (shas ) != 2 {
301
333
return nil , errors .New ("malformed index: expect two SHAs in the form of <old>..<new>" )
302
334
}
303
335
304
- if file .IsDeleted () {
305
- file .Index = shas [0 ]
306
- } else {
307
- file .Index = shas [1 ]
336
+ file .OldIndex = shas [0 ]
337
+ file .Index = shas [1 ]
338
+ if len (fields ) > 1 {
339
+ mode , _ := strconv .ParseUint (fields [1 ], 8 , 64 )
340
+ file .mode = EntryMode (mode )
341
+ file .oldMode = EntryMode (mode )
308
342
}
309
343
break checkType
310
344
case strings .HasPrefix (line , "similarity index " ):
@@ -316,8 +350,18 @@ checkType:
316
350
if strings .HasSuffix (line , "100%" ) {
317
351
break checkType
318
352
}
353
+ case strings .HasPrefix (line , "new mode" ):
354
+ fields := strings .Fields (line )
355
+ if len (fields ) > 0 {
356
+ mode , _ := strconv .ParseUint (fields [len (fields )- 1 ], 8 , 64 )
357
+ file .mode = EntryMode (mode )
358
+ }
319
359
case strings .HasPrefix (line , "old mode" ):
320
- break checkType
360
+ fields := strings .Fields (line )
361
+ if len (fields ) > 0 {
362
+ mode , _ := strconv .ParseUint (fields [len (fields )- 1 ], 8 , 64 )
363
+ file .oldMode = EntryMode (mode )
364
+ }
321
365
}
322
366
}
323
367
0 commit comments