Skip to content

Commit 2a8fce5

Browse files
diff: capture both old and new of index and mode (#73)
Co-authored-by: Joe Chen <[email protected]>
1 parent 93f85f8 commit 2a8fce5

File tree

4 files changed

+186
-73
lines changed

4 files changed

+186
-73
lines changed

diff.go

+52-8
Original file line numberDiff line numberDiff line change
@@ -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.
162177
func (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

Comments
 (0)