8000 Merge pull request #1050 from onee-only/fix-empty-commit · go-git/go-git@c7feada · GitHub
[go: up one dir, main page]

Skip to content

Commit c7feada

Browse files
authored
Merge pull request #1050 from onee-only/fix-empty-commit
git: worktree_commit, Modify checking empty commit. Fixes #723
2 parents 7ff5a5d + 746141e commit c7feada

File tree

4 files changed

+159
-24
lines changed

4 files changed

+159
-24
lines changed

repository_test.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,10 @@ func createCommit(c *C, r *Repository) plumbing.Hash {
103103
}
104104

105105
h, err := wt.Commit("test commit message", &CommitOptions{
106-
All: true,
107-
Author: &author,
108-
Committer: &author,
106+
All: true,
107+
Author: &author,
108+
Committer: &author,
109+
AllowEmptyCommits: true,
109110
})
110111
c.Assert(err, IsNil)
111112
return h

worktree_commit.go

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,6 @@ func (w *Worktree) Commit(msg string, opts *CommitOptions) (plumbing.Hash, error
3838
}
3939
}
4040

41-
var treeHash plumbing.Hash
42-
4341
if opts.Amend {
4442
head, err := w.r.Head()
4543
if err != nil {
@@ -61,16 +59,34 @@ func (w *Worktree) Commit(msg string, opts *CommitOptions) (plumbing.Hash, error
6159
return plumbing.ZeroHash, err
6260
}
6361

62+
// First handle the case of the first commit in the repository being empty.
63+
if len(opts.Parents) == 0 && len(idx.Entries) == 0 && !opts.AllowEmptyCommits {
64+
return plumbing.ZeroHash, ErrEmptyCommit
65+
}
66+
6467
h := &buildTreeHelper{
6568
fs: w.Filesystem,
6669
s: w.r.Storer,
6770
}
6871

69-
treeHash, err = h.BuildTree(idx, opts)
72+
treeHash, err := h.BuildTree(idx, opts)
7073
if err != nil {
7174
return plumbing.ZeroHash, err
7275
}
7376

77+
previousTree := plumbing.ZeroHash
78+
if len(opts.Parents) > 0 {
79+
parentCommit, err := w.r.CommitObject(opts.Parents[0])
80+
if err != nil {
81+
return plumbing.ZeroHash, err
82+
}
83+
previousTree = parentCommit.TreeHash
84+
}
85+
86+
if treeHash == previousTree && !opts.AllowEmptyCommits {
87+
return plumbing.ZeroHash, ErrEmptyCommit
88+
}
89+
7490
commit, err := w.buildCommitObject(msg, opts, treeHash)
7591
if err != nil {
7692
return plumbing.ZeroHash, err
@@ -175,10 +191,6 @@ type buildTreeHelper struct {
175191
// BuildTree builds the tree objects and push its to the storer, the hash
176192
// of the root tree is returned.
177193
func (h *buildTreeHelper) BuildTree(idx *index.Index, opts *CommitOptions) (plumbing.Hash, error) {
178-
if len(idx.Entries) == 0 && (opts == nil || !opts.AllowEmptyCommits) {
179-
return plumbing.ZeroHash, ErrEmptyCommit
180-
}
181-
182194
const rootNode = ""
183195
h.trees = map[string]*object.Tree{rootNode: {}}
184196
h.entries = map[string]*object.TreeEntry{}

worktree_commit_test.go

Lines changed: 118 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,56 @@ func (s *WorktreeSuite) TestNothingToCommit(c *C) {
8989
c.Assert(err, IsNil)
9090
}
9191

92+
func (s *WorktreeSuite) TestNothingToCommitNonEmptyRepo(c *C) {
93+
fs := memfs.New()
94+
r, err := Init(memory.NewStorage(), fs)
95+
c.Assert(err, IsNil)
96+
97+
w, err := r.Worktree()
98+
c.Assert(err, IsNil)
99+
100+
err = util.WriteFile(fs, "foo", []byte("foo"), 0644)
101+
c.Assert(err, IsNil)
102+
103+
w.Add("foo")
104+
_, err = w.Commit("previous commit\n", &CommitOptions{Author: defaultSignature()})
105+
c.Assert(err, IsNil)
106+
107+
hash, err := w.Commit("failed empty commit\n", &CommitOptions{Author: defaultSignature()})
108+
c.Assert(hash, Equals, plumbing.ZeroHash)
109+
c.Assert(err, Equals, ErrEmptyCommit)
110+
111+
_, err = w.Commit("enable empty commits\n", &CommitOptions{Author: defaultSignature(), AllowEmptyCommits: true})
112+
c.Assert(err, IsNil)
113+
}
114+
115+
func (s *WorktreeSuite) TestRemoveAndCommitToMakeEmptyRepo(c *C) {
116+
fs := memfs.New()
117+
r, err := Init(memory.NewStorage(), fs)
118+
c.Assert(err, IsNil)
119+
120+
w, err := r.Worktree()
121+
c.Assert(err, IsNil)
122+
123+
err = util.WriteFile(fs, "foo", []byte("foo"), 0644)
124+
c.Assert(err, IsNil)
125+
126+
_, err = w.Add("foo")
127+
c.Assert(err, IsNil)
128+
129+
_, err = w.Commit("Add in Repo\n", &CommitOptions{Author: defaultSignature()})
130+
c.Assert(err, IsNil)
131+
132+
err = fs.Remove("foo")
133+
c.Assert(err, IsNil)
134+
135+
_, err = w.Add("foo")
136+
c.Assert(err, IsNil)
137+
138+
_, err = w.Commit("Remove foo\n", &CommitOptions{Author: defaultSignature()})
139+
c.Assert(err, IsNil)
140+
}
141+
92142
func (s *WorktreeSuite) TestCommitParent(c *C) {
93143
expected := plumbing.NewHash("ef3ca05477530b37f48564be33ddd48063fc7a22")
94144

@@ -101,7 +151,8 @@ func (s *WorktreeSuite) TestCommitParent(c *C) {
101151
err := w.Checkout(&CheckoutOptions{})
102152
c.Assert(err, IsNil)
103153

104-
util.WriteFile(fs, "foo", []byte("foo"), 0644)
154+
err = util.WriteFile(fs, "foo", []byte("foo"), 0644)
155+
c.Assert(err, IsNil)
105156

106157
_, err = w.Add("foo")
107158
c.Assert(err, IsNil)
@@ -113,7 +164,42 @@ func (s *WorktreeSuite) TestCommitParent(c *C) {
113164
assertStorageStatus(c, s.Repository, 13, 11, 10, expected)
114165
}
115166

116-
func (s *WorktreeSuite) TestCommitAmend(c *C) {
167+
func (s *WorktreeSuite) TestCommitAmendWithoutChanges(c *C) {
168+
fs := memfs.New()
169+
w := &Worktree{
170+
r: s.Repository,
171+
Filesystem: fs,
172+
}
173+
174+
err := w.Checkout(&CheckoutOptions{})
175+
c.Assert(err, IsNil)
176+
177+
err = util.WriteFile(fs, "foo", []byte("foo"), 0644)
178+
c.Assert(err, IsNil)
179+
180+
_, err = w.Add("foo")
181+
c.Assert(err, IsNil)
182+
183+
prevHash, err := w.Commit("foo\n", &CommitOptions{Author: defaultSignature()})
184+
c.Assert(err, IsNil)
185+
186+
amendedHash, err := w.Commit("foo\n", &CommitOptions{Author: defaultSignature(), Amend: true})
187+
c.Assert(err, IsNil)
188+
189+
headRef, err := w.r.Head()
190+
c.Assert(err, IsNil)
191+
192+
c.Assert(amendedHash, Equals, headRef.Hash())
193+
c.Assert(amendedHash, Equals, prevHash)
194+
195+
commit, err := w.r.CommitObject(headRef.Hash())
196+
c.Assert(err, IsNil)
197+
c.Assert(commit.Message, Equals, "foo\n")
198+
199+
assertStorageStatus(c, s.Repository, 13, 11, 10, amendedHash)
200+
}
201+
202+
func (s *WorktreeSuite) TestCommitAmendWithChanges(c *C) {
117203
fs := memfs.New()
118204
w := &Worktree{
119205
r: s.Repository,
@@ -164,6 +250,34 @@ func (s *WorktreeSuite) TestCommitAmend(c *C) {
164250
assertStorageStatus(c, s.Repository, 14, 12, 11, amendedHash)
165251
}
166252

253+
func (s *WorktreeSuite) TestCommitAmendNothingToCommit(c *C) {
254+
fs := memfs.New()
255+
w := &Worktree{
256+
r: s.Repository,
257+
Filesystem: fs,
258+
}
259+
260+
err := w.Checkout(&CheckoutOptions{})
261+
c.Assert(err, IsNil)
262+
263+
err = util.WriteFile(fs, "foo", []byte("foo"), 0644)
264+
c.Assert(err, IsNil)
265+
266+
_, err = w.Add("foo")
267+
c.Assert(err, IsNil)
268+
269+
prevHash, err := w.Commit("foo\n", &CommitOptions{Author: defaultSignature()})
270+
c.Assert(err, IsNil)
271+
272+
_, err = w.Commit("bar\n", &CommitOptions{Author: defaultSignature(), AllowEmptyCommits: true})
273+
c.Assert(err, IsNil)
274+
275+
amendedHash, err := w.Commit("foo\n", &CommitOptions{Author: defaultSignature(), Amend: true})
276+
c.Log(prevHash, amendedHash)
277+
c.Assert(err, Equals, ErrEmptyCommit)
278+
c.Assert(amendedHash, Equals, plumbing.ZeroHash)
279+
}
280+
167281
func (s *WorktreeSuite) TestAddAndCommitWithSkipStatus(c *C) {
168282
expected := plumbing.NewHash("375a3808ffde7f129cdd3c8c252fd0fe37cfd13b")
169283

@@ -258,7 +372,8 @@ func (s *WorktreeSuite) TestAddAndCommitWithSkipStatusPathNotModified(c *C) {
258372
c.Assert(foo.Worktree, Equals, Untracked)
259373

260374
hash, err = w.Commit("commit with no changes\n", &CommitOptions{
261-
Author: defaultSignature(),
375+
Author: defaultSignature(),
376+
AllowEmptyCommits: true,
262377
})
263378
c.Assert(hash, Equals, expected2)
264379
c.Assert(err, IsNil)

worktree_test.go

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,11 @@ import (
3232
. "gopkg.in/check.v1"
3333
)
3434

35-
var (
36-
defaultTestCommitOptions = &CommitOptions{Author: &object.Signature{Name: "testuser", Email: "testemail"}}
37-
)
35+
func defaultTestCommitOptions() *CommitOptions {
36+
return &CommitOptions{
37+
Author: &object.Signature{Name: "testuser", Email: "testemail"},
38+
}
39+
}
3840

3941
type WorktreeSuite struct {
4042
BaseSuite
@@ -87,8 +89,9 @@ func (s *WorktreeSuite) TestPullFastForward(c *C) {
8789

8890
w, err := server.Worktree()
8991
c.Assert(err, IsNil)
90-
err = os.WriteFile(filepath.Join(path, "foo"), []byte("foo"), 0755)
92+
err = os.WriteFile(filepath.Join(url, "foo"), []byte("foo"), 0755)
9193
c.Assert(err, IsNil)
94+
w.Add("foo")
9295
hash, err := w.Commit("foo", &CommitOptions{Author: defaultSignature()})
9396
c.Assert(err, IsNil)
9497

@@ -124,15 +127,17 @@ func (s *WorktreeSuite) TestPullNonFastForward(c *C) {
124127

125128
w, err := server.Worktree()
126129
c.Assert(err, IsNil)
127-
err = os.WriteFile(filepath.Join(path, "foo"), []byte("foo"), 0755)
130+
err = os.WriteFile(filepath.Join(url, "foo"), []byte("foo"), 0755)
128131
c.Assert(err, IsNil)
132+
w.Add("foo")
129133
_, err = w.Commit("foo", &CommitOptions{Author: defaultSignature()})
130134
c.Assert(err, IsNil)
131135

132136
w, err = r.Worktree()
133137
c.Assert(err, IsNil)
134-
err = os.WriteFile(filepath.Join(path, "bar"), []byte("bar"), 0755)
138+
err = os.WriteFile(filepath.Join(dir, "bar"), []byte("bar"), 0755)
135139
c.Assert(err, IsNil)
140+
w.Add("bar")
136141
_, err = w.Commit("bar", &CommitOptions{Author: defaultSignature()})
137142
c.Assert(err, IsNil)
138143

@@ -285,16 +290,18 @@ func (s *RepositorySuite) TestPullAdd(c *C) {
285290
func (s *WorktreeSuite) TestPullAlreadyUptodate(c *C) {
286291
path := fixtures.Basic().ByTag("worktree").One().Worktree().Root()
287292

288-
r, err := Clone(memory.NewStorage(), memfs.New(), &CloneOptions{
293+
fs := memfs.New()
294+
r, err := Clone(memory.NewStorage(), fs, &CloneOptions{
289295
URL: filepath.Join(path, ".git"),
290296
})
291297

292298
c.Assert(err, IsNil)
293299

294300
w, err := r.Worktree()
295301
c.Assert(err, IsNil)
296-
err = os.WriteFile(filepath.Join(path, "bar"), []byte("bar"), 0755)
302+
err = util.WriteFile(fs, "bar", []byte("bar"), 0755)
297303
c.Assert(err, IsNil)
304+
w.Add("bar")
298305
_, err = w.Commit("bar", &CommitOptions{Author: defaultSignature()})
299306
c.Assert(err, IsNil)
300307

@@ -1001,14 +1008,14 @@ func (s *WorktreeSuite) TestStatusCheckedInBeforeIgnored(c *C) {
10011008
_, err = w.Add("fileToIgnore")
10021009
c.Assert(err, IsNil)
10031010

1004-
_, err = w.Commit("Added file that will be ignored later", defaultTestCommitOptions)
1011+
_, err = w.Commit("Added file that will be ignored later", defaultTestCommitOptions())
10051012
c.Assert(err, IsNil)
10061013

10071014
err = util.WriteFile(fs, ".gitignore", []byte("fileToIgnore\nsecondIgnoredFile"), 0755)
10081015
c.Assert(err, IsNil)
10091016
_, err = w.Add(".gitignore")
10101017
c.Assert(err, IsNil)
1011-
_, err = w.Commit("Added .gitignore", defaultTestCommitOptions)
1018+
_, err = w.Commit("Added .gitignore", defaultTestCommitOptions())
10121019
c.Assert(err, IsNil)
10131020
status, err := w.Status()
10141021
c.Assert(err, IsNil)
@@ -2056,7 +2063,7 @@ func (s *WorktreeSuite) TestAddSkipStatusWithIgnoredPath(c *C) {
20562063
c.Assert(err, IsNil)
20572064
_, err = w.Add(".gitignore")
20582065
c.Assert(err, IsNil)
2059-
_, err = w.Commit("Added .gitignore", defaultTestCommitOptions)
2066+
_, err = w.Commit("Added .gitignore", defaultTestCommitOptions())
20602067
c.Assert(err, IsNil)
20612068

20622069
err = util.WriteFile(fs, "fileToIgnore", []byte("file to ignore"), 0644)

0 commit comments

Comments
 (0)
0