aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--plumbing/object/commit.go12
-rw-r--r--plumbing/object/commit_test.go12
-rw-r--r--plumbing/transport/http/receive_pack_test.go112
-rw-r--r--utils/merkletrie/filesystem/node.go4
-rw-r--r--utils/merkletrie/filesystem/node_test.go36
5 files changed, 116 insertions, 60 deletions
diff --git a/plumbing/object/commit.go b/plumbing/object/commit.go
index fad3dac..b2f1f15 100644
--- a/plumbing/object/commit.go
+++ b/plumbing/object/commit.go
@@ -3,6 +3,7 @@ package object
import (
"bufio"
"bytes"
+ "errors"
"fmt"
"io"
"strings"
@@ -98,6 +99,17 @@ func (c *Commit) NumParents() int {
return len(c.ParentHashes)
}
+var ErrParentNotFound = errors.New("commit parent not found")
+
+// Parent returns the ith parent of a commit.
+func (c *Commit) Parent(i int) (*Commit, error) {
+ if len(c.ParentHashes) == 0 || i > len(c.ParentHashes)-1 {
+ return nil, ErrParentNotFound
+ }
+
+ return GetCommit(c.s, c.ParentHashes[i])
+}
+
// File returns the file with the specified "path" in the commit and a
// nil error if the file exists. If the file does not exist, it returns
// a nil file and the ErrFileNotFound error.
diff --git a/plumbing/object/commit_test.go b/plumbing/object/commit_test.go
index e84160b..f0792e6 100644
--- a/plumbing/object/commit_test.go
+++ b/plumbing/object/commit_test.go
@@ -67,6 +67,18 @@ func (s *SuiteCommit) TestParents(c *C) {
i.Close()
}
+func (s *SuiteCommit) TestParent(c *C) {
+ commit, err := s.Commit.Parent(1)
+ c.Assert(err, IsNil)
+ c.Assert(commit.Hash.String(), Equals, "a5b8b09e2f8fcb0bb99d3ccb0958157b40890d69")
+}
+
+func (s *SuiteCommit) TestParentNotFound(c *C) {
+ commit, err := s.Commit.Parent(42)
+ c.Assert(err, Equals, ErrParentNotFound)
+ c.Assert(commit, IsNil)
+}
+
func (s *SuiteCommit) TestPatch(c *C) {
from := s.commit(c, plumbing.NewHash("918c48b83bd081e863dbe1b80f8998f058cd8294"))
to := s.commit(c, plumbing.NewHash("6ecf0ef2c2dffb796033e5a02219af86ec6584e5"))
diff --git a/plumbing/transport/http/receive_pack_test.go b/plumbing/transport/http/receive_pack_test.go
index d870e5d..970121d 100644
--- a/plumbing/transport/http/receive_pack_test.go
+++ b/plumbing/transport/http/receive_pack_test.go
@@ -25,6 +25,8 @@ type ReceivePackSuite struct {
fixtures.Suite
base string
+ host string
+ port int
}
var _ = Suite(&ReceivePackSuite{})
@@ -32,52 +34,35 @@ var _ = Suite(&ReceivePackSuite{})
func (s *ReceivePackSuite) SetUpTest(c *C) {
s.ReceivePackSuite.Client = DefaultClient
- port, err := freePort()
+ l, err := net.Listen("tcp", "localhost:0")
c.Assert(err, IsNil)
base, err := ioutil.TempDir(os.TempDir(), "go-git-http-backend-test")
c.Assert(err, IsNil)
- s.base = base
- host := fmt.Sprintf("localhost_%d", port)
- interpolatedBase := filepath.Join(base, host)
- err = os.MkdirAll(interpolatedBase, 0755)
- c.Assert(err, IsNil)
-
- dotgit := fixtures.Basic().One().DotGit().Root()
- prepareRepo(c, dotgit)
- err = os.Rename(dotgit, filepath.Join(interpolatedBase, "basic.git"))
- c.Assert(err, IsNil)
-
- ep, err := transport.NewEndpoint(fmt.Sprintf("http://localhost:%d/basic.git", port))
- c.Assert(err, IsNil)
- s.ReceivePackSuite.Endpoint = ep
-
- dotgit = fixtures.ByTag("empty").One().DotGit().Root()
- prepareRepo(c, dotgit)
- err = os.Rename(dotgit, filepath.Join(interpolatedBase, "empty.git"))
- c.Assert(err, IsNil)
+ s.port = l.Addr().(*net.TCPAddr).Port
+ s.host = fmt.Sprintf("localhost_%d", s.port)
+ s.base = filepath.Join(base, s.host)
- ep, err = transport.NewEndpoint(fmt.Sprintf("http://localhost:%d/empty.git", port))
+ err = os.MkdirAll(s.base, 0755)
c.Assert(err, IsNil)
- s.ReceivePackSuite.EmptyEndpoint = ep
- ep, err = transport.NewEndpoint(fmt.Sprintf("http://localhost:%d/non-existent.git", port))
- c.Assert(err, IsNil)
- s.ReceivePackSuite.NonExistentEndpoint = ep
+ s.ReceivePackSuite.Endpoint = s.prepareRepository(c, fixtures.Basic().One(), "basic.git")
+ s.ReceivePackSuite.EmptyEndpoint = s.prepareRepository(c, fixtures.ByTag("empty").One(), "empty.git")
+ s.ReceivePackSuite.NonExistentEndpoint = s.newEndpoint(c, "non-existent.git")
cmd := exec.Command("git", "--exec-path")
out, err := cmd.CombinedOutput()
c.Assert(err, IsNil)
- p := filepath.Join(strings.Trim(string(out), "\n"), "git-http-backend")
- h := &cgi.Handler{
- Path: p,
- Env: []string{"GIT_HTTP_EXPORT_ALL=true", fmt.Sprintf("GIT_PROJECT_ROOT=%s", interpolatedBase)},
+ server := &http.Server{
+ Handler: &cgi.Handler{
+ Path: filepath.Join(strings.Trim(string(out), "\n"), "git-http-backend"),
+ Env: []string{"GIT_HTTP_EXPORT_ALL=true", fmt.Sprintf("GIT_PROJECT_ROOT=%s", s.base)},
+ },
}
-
go func() {
- log.Fatal(http.ListenAndServe(fmt.Sprintf(":%d", port), h))
+ log.Fatal(server.Serve(l))
}()
}
@@ -86,37 +71,44 @@ func (s *ReceivePackSuite) TearDownTest(c *C) {
c.Assert(err, IsNil)
}
-func freePort() (int, error) {
- addr, err := net.ResolveTCPAddr("tcp", "localhost:0")
- if err != nil {
- return 0, err
- }
+func (s *ReceivePackSuite) prepareRepository(c *C, f *fixtures.Fixture, name string) transport.Endpoint {
+ path := filepath.Join(s.base, name)
- l, err := net.ListenTCP("tcp", addr)
- if err != nil {
- return 0, err
- }
+ err := os.Rename(f.DotGit().Root(), path)
+ c.Assert(err, IsNil)
- return l.Addr().(*net.TCPAddr).Port, l.Close()
+ s.setConfigToRepository(c, path)
+ return s.newEndpoint(c, name)
}
-const bareConfig = `[core]
-repositoryformatversion = 0
-filemode = true
-bare = true
-[http]
-receivepack = true`
-
-func prepareRepo(c *C, path string) {
- // git-receive-pack refuses to update refs/heads/master on non-bare repo
- // so we ensure bare repo config.
- config := filepath.Join(path, "config")
- if _, err := os.Stat(config); err == nil {
- f, err := os.OpenFile(config, os.O_TRUNC|os.O_WRONLY, 0)
- c.Assert(err, IsNil)
- content := strings.NewReader(bareConfig)
- _, err = io.Copy(f, content)
- c.Assert(err, IsNil)
- c.Assert(f.Close(), IsNil)
- }
+// git-receive-pack refuses to update refs/heads/master on non-bare repo
+// so we ensure bare repo config.
+func (s *ReceivePackSuite) setConfigToRepository(c *C, path string) {
+ cfgPath := filepath.Join(path, "config")
+ _, err := os.Stat(cfgPath)
+ c.Assert(err, IsNil)
+
+ cfg, err := os.OpenFile(cfgPath, os.O_TRUNC|os.O_WRONLY, 0)
+ c.Assert(err, IsNil)
+
+ content := strings.NewReader("" +
+ "[core]\n" +
+ "repositoryformatversion = 0\n" +
+ "filemode = true\n" +
+ "bare = true\n" +
+ "[http]\n" +
+ "receivepack = true\n",
+ )
+
+ _, err = io.Copy(cfg, content)
+ c.Assert(err, IsNil)
+
+ c.Assert(cfg.Close(), IsNil)
+}
+
+func (s *ReceivePackSuite) newEndpoint(c *C, name string) transport.Endpoint {
+ ep, err := transport.NewEndpoint(fmt.Sprintf("http://localhost:%d/%s", s.port, name))
+ c.Assert(err, IsNil)
+
+ return ep
}
diff --git a/utils/merkletrie/filesystem/node.go b/utils/merkletrie/filesystem/node.go
index f763e08..42a58a3 100644
--- a/utils/merkletrie/filesystem/node.go
+++ b/utils/merkletrie/filesystem/node.go
@@ -77,6 +77,10 @@ func (n *node) NumChildren() (int, error) {
}
func (n *node) calculateChildren() error {
+ if !n.IsDir() {
+ return nil
+ }
+
if len(n.children) != 0 {
return nil
}
diff --git a/utils/merkletrie/filesystem/node_test.go b/utils/merkletrie/filesystem/node_test.go
index 42dd82e..7aa0d97 100644
--- a/utils/merkletrie/filesystem/node_test.go
+++ b/utils/merkletrie/filesystem/node_test.go
@@ -82,6 +82,42 @@ func (s *NoderSuite) TestDiffChangeContent(c *C) {
c.Assert(ch, HasLen, 1)
}
+func (s *NoderSuite) TestDiffSymlinkDirOnA(c *C) {
+ fsA := memfs.New()
+ WriteFile(fsA, "qux/qux", []byte("foo"), 0644)
+
+ fsB := memfs.New()
+ fsB.Symlink("qux", "foo")
+ WriteFile(fsB, "qux/qux", []byte("foo"), 0644)
+
+ ch, err := merkletrie.DiffTree(
+ NewRootNode(fsA, nil),
+ NewRootNode(fsB, nil),
+ IsEquals,
+ )
+
+ c.Assert(err, IsNil)
+ c.Assert(ch, HasLen, 1)
+}
+
+func (s *NoderSuite) TestDiffSymlinkDirOnB(c *C) {
+ fsA := memfs.New()
+ fsA.Symlink("qux", "foo")
+ WriteFile(fsA, "qux/qux", []byte("foo"), 0644)
+
+ fsB := memfs.New()
+ WriteFile(fsB, "qux/qux", []byte("foo"), 0644)
+
+ ch, err := merkletrie.DiffTree(
+ NewRootNode(fsA, nil),
+ NewRootNode(fsB, nil),
+ IsEquals,
+ )
+
+ c.Assert(err, IsNil)
+ c.Assert(ch, HasLen, 1)
+}
+
func (s *NoderSuite) TestDiffChangeMissing(c *C) {
fsA := memfs.New()
WriteFile(fsA, "foo", []byte("foo"), 0644)