@@ -108,8 +108,10 @@ type DiffFile struct {
108108 // The type of the file.
109109 Type DiffFileType
110110 // 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" .
112112 Index string
113+ // OldIndex is the old index (SHA1 hash) of the file.
114+ OldIndex string
113115 // The sections in the file.
114116 Sections []* DiffSection
115117
@@ -118,6 +120,9 @@ type DiffFile struct {
118120
119121 oldName string
120122
123+ mode EntryMode
124+ oldMode EntryMode
125+
121126 isBinary bool
122127 isSubmodule bool
123128 isIncomplete bool
@@ -158,6 +163,16 @@ func (f *DiffFile) OldName() string {
158163 return f .oldName
159164}
160165
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+
161176// IsBinary returns true if the file is in binary format.
162177func (f * DiffFile ) IsBinary () bool {
163178 return f .isBinary
@@ -268,8 +283,9 @@ func (p *diffParser) parseFileHeader() (*DiffFile, error) {
268283 }
269284
270285 file := & DiffFile {
271- Name : a ,
272- Type : DiffFileChange ,
286+ Name : a ,
287+ oldName : b ,
288+ Type : DiffFileChange ,
273289 }
274290
275291 // Check file diff type and submodule
@@ -291,20 +307,38 @@ checkType:
291307 case strings .HasPrefix (line , "new file" ):
292308 file .Type = DiffFileAdd
293309 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+ }
294318 case strings .HasPrefix (line , "deleted" ):
295319 file .Type = DiffFileDelete
296320 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+ }
297329 case strings .HasPrefix (line , "index" ): // e.g. index ee791be..9997571 100644
298330 fields := strings .Fields (line [6 :])
299331 shas := strings .Split (fields [0 ], ".." )
300332 if len (shas ) != 2 {
301333 return nil , errors .New ("malformed index: expect two SHAs in the form of <old>..<new>" )
302334 }
303335
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 )
308342 }
309343 break checkType
310344 case strings .HasPrefix (line , "similarity index " ):
@@ -316,8 +350,18 @@ checkType:
316350 if strings .HasSuffix (line , "100%" ) {
317351 break checkType
318352 }
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+ }
319359 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+ }
321365 }
322366 }
323367
0 commit comments