aboutsummaryrefslogtreecommitdiffstats
path: root/config
diff options
context:
space:
mode:
authorJeremy Stribling <strib@alum.mit.edu>2017-09-10 20:59:31 -0700
committerJeremy Stribling <strib@alum.mit.edu>2017-09-11 08:56:54 -0700
commit52c1f982ea0004de419d1a7f69d7eaf8b8d6b659 (patch)
tree582a03b677b2a4c34c46c83f6511ad141c7b3ccb /config
parentbb3217ce5d5ed682a5c830c40ea031d3c92a8a7e (diff)
downloadgo-git-52c1f982ea0004de419d1a7f69d7eaf8b8d6b659.tar.gz
config: support a configurable, and turn-off-able, pack.window
One use of go-git is to transfer git data from a non-standard git repo (not stored in a file system, for example) to a "remote" backed by a standard, local .git repo. In this scenario, delta compression is not needed to reduce transfer time over the "network", because there is no network. The underlying storage layer has already taken care of the data tranfer, and sending the objects to local .git storage doesn't require compression. So this PR gives the user the option to turn off compression when it isn't needed. Of course, this results in a larger, uncompressed local .git repo, but the user can then run git gc or git repack on that repo if they care about the storage costs. Turning the pack window to 0 on reduces total push time of a 36K repo by 50 seconds (out of a pre-PR total of 3m26s).
Diffstat (limited to 'config')
-rw-r--r--config/config.go39
-rw-r--r--config/config_test.go8
2 files changed, 47 insertions, 0 deletions
diff --git a/config/config.go b/config/config.go
index 475045e..477eb35 100644
--- a/config/config.go
+++ b/config/config.go
@@ -6,6 +6,7 @@ import (
"errors"
"fmt"
"sort"
+ "strconv"
format "gopkg.in/src-d/go-git.v4/plumbing/format/config"
)
@@ -40,6 +41,14 @@ type Config struct {
// Worktree is the path to the root of the working tree.
Worktree string
}
+
+ Pack struct {
+ // Window controls the size of the sliding window for delta
+ // compression. The default is 10. A value of 0 turns off
+ // delta compression entirely.
+ Window uint
+ }
+
// Remotes list of repository remotes, the key of the map is the name
// of the remote, should equal to RemoteConfig.Name.
Remotes map[string]*RemoteConfig
@@ -81,10 +90,14 @@ const (
remoteSection = "remote"
submoduleSection = "submodule"
coreSection = "core"
+ packSection = "pack"
fetchKey = "fetch"
urlKey = "url"
bareKey = "bare"
worktreeKey = "worktree"
+ windowKey = "window"
+
+ defaultPackWindow = uint(10)
)
// Unmarshal parses a git-config file and stores it.
@@ -98,6 +111,9 @@ func (c *Config) Unmarshal(b []byte) error {
}
c.unmarshalCore()
+ if err := c.unmarshalPack(); err != nil {
+ return err
+ }
c.unmarshalSubmodules()
return c.unmarshalRemotes()
}
@@ -111,6 +127,21 @@ func (c *Config) unmarshalCore() {
c.Core.Worktree = s.Options.Get(worktreeKey)
}
+func (c *Config) unmarshalPack() error {
+ s := c.Raw.Section(packSection)
+ window := s.Options.Get(windowKey)
+ if window == "" {
+ c.Pack.Window = defaultPackWindow
+ } else {
+ winUint, err := strconv.ParseUint(window, 10, 32)
+ if err != nil {
+ return err
+ }
+ c.Pack.Window = uint(winUint)
+ }
+ return nil
+}
+
func (c *Config) unmarshalRemotes() error {
s := c.Raw.Section(remoteSection)
for _, sub := range s.Subsections {
@@ -138,6 +169,7 @@ func (c *Config) unmarshalSubmodules() {
// Marshal returns Config encoded as a git-config file.
func (c *Config) Marshal() ([]byte, error) {
c.marshalCore()
+ c.marshalPack()
c.marshalRemotes()
c.marshalSubmodules()
@@ -158,6 +190,13 @@ func (c *Config) marshalCore() {
}
}
+func (c *Config) marshalPack() {
+ s := c.Raw.Section(packSection)
+ if c.Pack.Window != defaultPackWindow {
+ s.SetOption(windowKey, fmt.Sprintf("%d", c.Pack.Window))
+ }
+}
+
func (c *Config) marshalRemotes() {
s := c.Raw.Section(remoteSection)
newSubsections := make(format.Subsections, 0, len(c.Remotes))
diff --git a/config/config_test.go b/config/config_test.go
index c27ee26..019cee6 100644
--- a/config/config_test.go
+++ b/config/config_test.go
@@ -10,6 +10,8 @@ func (s *ConfigSuite) TestUnmarshall(c *C) {
input := []byte(`[core]
bare = true
worktree = foo
+[pack]
+ window = 20
[remote "origin"]
url = git@github.com:mcuadros/go-git.git
fetch = +refs/heads/*:refs/remotes/origin/*
@@ -33,6 +35,7 @@ func (s *ConfigSuite) TestUnmarshall(c *C) {
c.Assert(cfg.Core.IsBare, Equals, true)
c.Assert(cfg.Core.Worktree, Equals, "foo")
+ c.Assert(cfg.Pack.Window, Equals, uint(20))
c.Assert(cfg.Remotes, HasLen, 2)
c.Assert(cfg.Remotes["origin"].Name, Equals, "origin")
c.Assert(cfg.Remotes["origin"].URLs, DeepEquals, []string{"git@github.com:mcuadros/go-git.git"})
@@ -51,6 +54,8 @@ func (s *ConfigSuite) TestMarshall(c *C) {
output := []byte(`[core]
bare = true
worktree = bar
+[pack]
+ window = 20
[remote "alt"]
url = git@github.com:mcuadros/go-git.git
url = git@github.com:src-d/go-git.git
@@ -65,6 +70,7 @@ func (s *ConfigSuite) TestMarshall(c *C) {
cfg := NewConfig()
cfg.Core.IsBare = true
cfg.Core.Worktree = "bar"
+ cfg.Pack.Window = 20
cfg.Remotes["origin"] = &RemoteConfig{
Name: "origin",
URLs: []string{"git@github.com:mcuadros/go-git.git"},
@@ -92,6 +98,8 @@ func (s *ConfigSuite) TestUnmarshallMarshall(c *C) {
bare = true
worktree = foo
custom = ignored
+[pack]
+ window = 20
[remote "origin"]
url = git@github.com:mcuadros/go-git.git
fetch = +refs/heads/*:refs/remotes/origin/*