Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use .lfsconfig (with fallback to .gitconfig) #837

Merged
merged 7 commits into from
Nov 18, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions commands/command_env.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ var (
)

func envCommand(cmd *cobra.Command, args []string) {
lfs.ShowConfigWarnings = true
config := lfs.Config
endpoint := config.Endpoint()

Expand Down
8 changes: 4 additions & 4 deletions docs/spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,10 @@ of rules that Git LFS uses to determine a repository's Git LFS server:
Git LFS runs two `git config` commands to build up the list of values that it
uses:

1. `git config -l -f .gitconfig` - This file is checked into the repository and
can set defaults for every user that clones the repository.
1. `git config -l -f .lfsconfig` - This file is checked into the repository and
can set defaults for every user that clones the repository. Note: Git LFS used
".gitconfig" instead of ".lfsconfig" until Git LFS v1.1. Git LFS will continue
to read ".gitconfig" if ".lfsconfig" does not exist until Git LFS v2.0.
2. `git config -l` - A user's local git configuration can override any settings
from `.gitconfig`.

Expand Down Expand Up @@ -201,5 +203,3 @@ $ cat .gitattributes
```

Use the `git lfs track` command to view and add to `.gitattributes`.


3 changes: 0 additions & 3 deletions git/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -280,9 +280,6 @@ func (c *gitConfig) List() (string, error) {

// ListFromFile lists all of the git config values in the given config file
func (c *gitConfig) ListFromFile(f string) (string, error) {
if _, err := os.Stat(f); os.IsNotExist(err) {
return "", nil
}
return simpleExec("git", "config", "-l", "-f", f)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

837

}

Expand Down
66 changes: 50 additions & 16 deletions lfs/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,9 @@ import (
)

var (
Config = NewConfig()
defaultRemote = "origin"
Config = NewConfig()
defaultRemote = "origin"
ShowConfigWarnings = false
)

// FetchPruneConfig collects together the config options that control fetching and pruning
Expand Down Expand Up @@ -327,28 +328,22 @@ func (c *Configuration) loadGitConfig() bool {

c.gitConfig = make(map[string]string)
c.extensions = make(map[string]Extension)
uniqRemotes := make(map[string]bool)

listOutput, err := git.Config.List()
if err != nil {
panic(fmt.Errorf("Error listing git config: %s", err))
}
configFiles := []string{
filepath.Join(LocalWorkingDir, ".lfsconfig"),

configFile := filepath.Join(LocalWorkingDir, ".gitconfig")
fileOutput, err := git.Config.ListFromFile(configFile)
if err != nil {
panic(fmt.Errorf("Error listing git config from %s: %s", configFile, err))
// TODO: remove .gitconfig support for Git LFS v2.0 https://github.com/github/git-lfs/issues/839
filepath.Join(LocalWorkingDir, ".gitconfig"),
}
c.readGitConfigFromFiles(configFiles, 0, uniqRemotes)

localConfig := filepath.Join(LocalGitDir, "config")
localOutput, err := git.Config.ListFromFile(localConfig)
listOutput, err := git.Config.List()
if err != nil {
panic(fmt.Errorf("Error listing git config from %s: %s", localConfig, err))
panic(fmt.Errorf("Error listing git config: %s", err))
}

uniqRemotes := make(map[string]bool)
c.readGitConfig(fileOutput, uniqRemotes, true)
c.readGitConfig(listOutput, uniqRemotes, false)
c.readGitConfig(localOutput, uniqRemotes, false)

c.remotes = make([]string, 0, len(uniqRemotes))
for remote, isOrigin := range uniqRemotes {
Expand All @@ -361,8 +356,39 @@ func (c *Configuration) loadGitConfig() bool {
return true
}

func (c *Configuration) readGitConfigFromFiles(filenames []string, filenameIndex int, uniqRemotes map[string]bool) {
filename := filenames[filenameIndex]
_, err := os.Stat(filename)
if err == nil {
if filenameIndex > 0 && ShowConfigWarnings {
expected := ".lfsconfig"
fmt.Fprintf(os.Stderr, "WARNING: Reading LFS config from %q, not %q. Rename to %q before Git LFS v2.0 to remove this warning.\n",
filepath.Base(filename), expected, expected)
}

fileOutput, err := git.Config.ListFromFile(filename)
if err != nil {
panic(fmt.Errorf("Error listing git config from %s: %s", filename, err))
}
c.readGitConfig(fileOutput, uniqRemotes, true)
return
}

if os.IsNotExist(err) {
newIndex := filenameIndex + 1
if len(filenames) > newIndex {
c.readGitConfigFromFiles(filenames, newIndex, uniqRemotes)
}
return
}

panic(fmt.Errorf("Error listing git config from %s: %s", filename, err))
}

func (c *Configuration) readGitConfig(output string, uniqRemotes map[string]bool, onlySafe bool) {
lines := strings.Split(output, "\n")
uniqKeys := make(map[string]string)

for _, line := range lines {
pieces := strings.SplitN(line, "=", 2)
if len(pieces) < 2 {
Expand All @@ -373,6 +399,14 @@ func (c *Configuration) readGitConfig(output string, uniqRemotes map[string]bool
key := strings.ToLower(pieces[0])
value := pieces[1]

if origKey, ok := uniqKeys[key]; ok && c.gitConfig[key] != value {
fmt.Fprintf(os.Stderr, "WARNING: These git config values clash:\n")
fmt.Fprintf(os.Stderr, " git config %q = %q\n", origKey, c.gitConfig[key])
fmt.Fprintf(os.Stderr, " git config %q = %q\n", pieces[0], value)
} else {
uniqKeys[key] = pieces[0]
}

keyParts := strings.Split(key, ".")
if len(keyParts) == 4 && keyParts[0] == "lfs" && keyParts[1] == "extension" {
name := keyParts[2]
Expand Down
72 changes: 70 additions & 2 deletions test/test-config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,74 @@ begin_test "default config"
git lfs env | tee env.log
grep "Endpoint=$GITSERVER/$reponame.git/info/lfs (auth=none)" env.log

git config --file=.gitconfig lfs.url http://gitconfig-file-ignored
git config --file=.lfsconfig lfs.url http://lfsconfig-file
git lfs env | tee env.log
grep "Endpoint=http://lfsconfig-file (auth=none)" env.log

git config lfs.url http://local-lfsconfig
git lfs env | tee env.log
grep "Endpoint=http://local-lfsconfig (auth=none)" env.log
)
end_test

begin_test "extension config"
(
set -e

git config --global lfs.extension.env-test.clean "env-test-clean"
git config --global lfs.extension.env-test.smudge "env-test-smudge"
git config --global lfs.extension.env-test.priority 0

reponame="extension-config"
mkdir $reponame
cd $reponame
git init

expected0="Extension: env-test
clean = env-test-clean
smudge = env-test-smudge
priority = 0"

[ "$expected0" = "$(git lfs ext)" ]

# any git config takes precedence over .lfsconfig
git config --global --unset lfs.extension.env-test.priority

git config --file=.lfsconfig lfs.extension.env-test.clean "file-env-test-clean"
git config --file=.lfsconfig lfs.extension.env-test.smudge "file-env-test-smudge"
git config --file=.lfsconfig lfs.extension.env-test.priority 1
cat .lfsconfig
expected1="Extension: env-test
clean = env-test-clean
smudge = env-test-smudge
priority = 1"

[ "$expected1" = "$(GIT_TRACE=5 git lfs ext)" ]

git config lfs.extension.env-test.clean "local-env-test-clean"
git config lfs.extension.env-test.smudge "local-env-test-smudge"
git config lfs.extension.env-test.priority 2
expected2="Extension: env-test
clean = local-env-test-clean
smudge = local-env-test-smudge
priority = 2"

[ "$expected2" = "$(git lfs ext)" ]
)
end_test

begin_test "default config (with gitconfig)"
(
set -e
reponame="default-config-with-gitconfig"
mkdir $reponame
cd $reponame
git init
git remote add origin "$GITSERVER/$reponame"
git lfs env | tee env.log
grep "Endpoint=$GITSERVER/$reponame.git/info/lfs (auth=none)" env.log

git config --file=.gitconfig lfs.url http://gitconfig-file
git lfs env | tee env.log
grep "Endpoint=http://gitconfig-file (auth=none)" env.log
Expand All @@ -23,15 +91,15 @@ begin_test "default config"
)
end_test

begin_test "extension config"
begin_test "extension config (with gitconfig)"
(
set -e

git config --global lfs.extension.env-test.clean "env-test-clean"
git config --global lfs.extension.env-test.smudge "env-test-smudge"
git config --global lfs.extension.env-test.priority 0

reponame="extension-config"
reponame="extension-config-with-gitconfig"
mkdir $reponame
cd $reponame
git init
Expand Down
52 changes: 52 additions & 0 deletions test/test-env.sh
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,58 @@ BatchTransfer=false
)
end_test

begin_test "env with .lfsconfig"
(
set -e
reponame="env-with-lfsconfig"

git init $reponame
cd $reponame

git remote add origin "$GITSERVER/env-origin-remote"
echo '[remote "origin"]
lfsurl = http://foobar:8080/
[lfs]
batch = false
concurrenttransfers = 5
' > .lfsconfig
echo '[remote "origin"]
lfsurl = http://foobar:5050/
[lfs]
batch = true
concurrenttransfers = 50
' > .gitconfig

localwd=$(native_path "$TRASHDIR/$reponame")
localgit=$(native_path "$TRASHDIR/$reponame/.git")
localgitstore=$(native_path "$TRASHDIR/$reponame/.git")
localmedia=$(native_path "$TRASHDIR/$reponame/.git/lfs/objects")
tempdir=$(native_path "$TRASHDIR/$reponame/.git/lfs/tmp")
envVars=$(printf "%s" "$(env | grep "^GIT")")
expected=$(printf '%s
%s

Endpoint=http://foobar:8080/ (auth=none)
LocalWorkingDir=%s
LocalGitDir=%s
LocalGitStorageDir=%s
LocalMediaDir=%s
TempDir=%s
ConcurrentTransfers=3
BatchTransfer=true
%s
%s
' "$(git lfs version)" "$(git version)" "$localwd" "$localgit" "$localgitstore" "$localmedia" "$tempdir" "$envVars" "$envInitConfig")
actual=$(git lfs env)
contains_same_elements "$expected" "$actual"

mkdir a
cd a
actual2=$(git lfs env)
contains_same_elements "$expected" "$actual2"
)
end_test

begin_test "env with .gitconfig"
(
set -e
Expand Down