Skip to content

Commit 28cccf3

Browse files
committed
tree: use filenames only as tree entry keys
The Merge() function should only use filenames as the keys of a tree object's entries, not filenames combined with file modes, which at present can result in duplicate file entries reported by "git fsck" as errors. We therefore change to use only the entry's names as keys when merging new and existing tree entries together, and adjust the basic tree merge test such that it would fail without this change.
1 parent 57c3fe4 commit 28cccf3

File tree

2 files changed

+5
-9
lines changed

2 files changed

+5
-9
lines changed

tree.go

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -115,22 +115,18 @@ func (t *Tree) Encode(to io.Writer) (n int, err error) {
115115
func (t *Tree) Merge(others ...*TreeEntry) *Tree {
116116
unseen := make(map[string]*TreeEntry)
117117

118-
// Build a cache of name+filemode to *TreeEntry.
118+
// Build a cache of name to *TreeEntry.
119119
for _, other := range others {
120-
key := fmt.Sprintf("%s\x00%o", other.Name, other.Filemode)
121-
122-
unseen[key] = other
120+
unseen[other.Name] = other
123121
}
124122

125123
// Map the existing entries ("t.Entries") into a new set by either
126124
// copying an existing entry, or replacing it with a new one.
127125
entries := make([]*TreeEntry, 0, len(t.Entries))
128126
for _, entry := range t.Entries {
129-
key := fmt.Sprintf("%s\x00%o", entry.Name, entry.Filemode)
130-
131-
if other, ok := unseen[key]; ok {
127+
if other, ok := unseen[entry.Name]; ok {
132128
entries = append(entries, other)
133-
delete(unseen, key)
129+
delete(unseen, entry.Name)
134130
} else {
135131
oid := make([]byte, len(entry.Oid))
136132
copy(oid, entry.Oid)

tree_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ func TestTreeDecodingShaBoundary(t *testing.T) {
123123
func TestTreeMergeReplaceElements(t *testing.T) {
124124
e1 := &TreeEntry{Name: "a", Filemode: 0100644, Oid: []byte{0x1}}
125125
e2 := &TreeEntry{Name: "b", Filemode: 0100644, Oid: []byte{0x2}}
126-
e3 := &TreeEntry{Name: "c", Filemode: 0100644, Oid: []byte{0x3}}
126+
e3 := &TreeEntry{Name: "c", Filemode: 0100755, Oid: []byte{0x3}}
127127

128128
e4 := &TreeEntry{Name: "b", Filemode: 0100644, Oid: []byte{0x4}}
129129
e5 := &TreeEntry{Name: "c", Filemode: 0100644, Oid: []byte{0x5}}

0 commit comments

Comments
 (0)