Skip to content

Commit db559f1

Browse files
nicholasSUSEpjbgf
andauthored
plumbing: filemode, Remove check for setting size of .git/index file (go-git#1159)
* plumbing: filemode, Remove check for setting size of .git/index file on staging. Fixes go-git#1003 Co-authored-by: Paulo Gomes <[email protected]>
1 parent b430952 commit db559f1

File tree

2 files changed

+94
-3
lines changed

2 files changed

+94
-3
lines changed

worktree_status.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -559,9 +559,11 @@ func (w *Worktree) doUpdateFileToIndex(e *index.Entry, filename string, h plumbi
559559
return err
560560
}
561561

562-
if e.Mode.IsRegular() {
563-
e.Size = uint32(info.Size())
564-
}
562+
// The entry size must always reflect the current state, otherwise
563+
// it will cause go-git's Worktree.Status() to divert from "git status".
564+
// The size of a symlink is the length of the path to the target.
565+
// The size of Regular and Executable files is the size of the files.
566+
e.Size = uint32(info.Size())
565567

566568
fillSystemInfo(e, info.Sys())
567569
return nil

worktree_status_test.go

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package git
2+
3+
import (
4+
"os"
5+
"path/filepath"
6+
"strings"
7+
"testing"
8+
9+
"github.com/go-git/go-billy/v5/osfs"
10+
"github.com/go-git/go-git/v5/plumbing/cache"
11+
"github.com/go-git/go-git/v5/storage/filesystem"
12+
"github.com/stretchr/testify/assert"
13+
"github.com/stretchr/testify/require"
14+
)
15+
16+
// For additional context: #1159.
17+
func TestIndexEntrySizeUpdatedForNonRegularFiles(t *testing.T) {
18+
w := osfs.New(t.TempDir(), osfs.WithBoundOS())
19+
dot, err := w.Chroot(GitDirName)
20+
require.NoError(t, err)
21+
22+
s := filesystem.NewStorage(dot, cache.NewObjectLRUDefault())
23+
r, err := Init(s, w)
24+
require.NoError(t, err)
25+
require.NotNil(t, r)
26+
27+
wt, err := r.Worktree()
28+
require.NoError(t, err)
29+
require.NotNil(t, wt)
30+
31+
file := "LICENSE"
32+
f, err := w.OpenFile(file, os.O_CREATE|os.O_WRONLY, 0o666)
33+
require.NoError(t, err)
34+
require.NotNil(t, f)
35+
36+
content := []byte(strings.Repeat("a\n", 1000))
37+
_, err = f.Write(content)
38+
require.NoError(t, err)
39+
err = f.Close()
40+
require.NoError(t, err)
41+
42+
_, err = wt.Add(file)
43+
require.NoError(t, err)
44+
45+
_, err = wt.Commit("add file", &CommitOptions{})
46+
require.NoError(t, err)
47+
48+
st, err := wt.StatusWithOptions(StatusOptions{Strategy: Preload})
49+
require.NoError(t, err)
50+
assert.Equal(t,
51+
&FileStatus{Worktree: Unmodified, Staging: Unmodified},
52+
st.File(file))
53+
54+
// Make the file not regular. The same would apply to a transition
55+
// from regular file to symlink.
56+
err = os.Chmod(filepath.Join(w.Root(), file), 0o777)
57+
require.NoError(t, err)
58+
59+
f, err = w.OpenFile(file, os.O_APPEND|os.O_RDWR, 0o777)
60+
require.NoError(t, err)
61+
require.NotNil(t, f)
62+
63+
_, err = f.Write([]byte("\n\n"))
64+
require.NoError(t, err)
65+
err = f.Close()
66+
require.NoError(t, err)
67+
68+
_, err = wt.Add(file)
69+
assert.NoError(t, err)
70+
71+
// go-git's Status diverges from "git status", so this check does not
72+
// fail, even when the issue is present. As at this point "git status"
73+
// reports the unstaged file was modified while "git diff" would return
74+
// empty, as the files are the same but the index has the incorrect file
75+
// size.
76+
st, err = wt.StatusWithOptions(StatusOptions{Strategy: Preload})
77+
assert.NoError(t, err)
78+
assert.Equal(t,
79+
&FileStatus{Worktree: Unmodified, Staging: Modified},
80+
st.File(file))
81+
82+
idx, err := wt.r.Storer.Index()
83+
assert.NoError(t, err)
84+
require.NotNil(t, idx)
85+
require.Len(t, idx.Entries, 1)
86+
87+
// Check whether the index was updated with the two new line breaks.
88+
assert.Equal(t, uint32(len(content)+2), idx.Entries[0].Size)
89+
}

0 commit comments

Comments
 (0)