From 21f3812bebe85bff102bb82e848b1e9bf63d327d Mon Sep 17 00:00:00 2001 From: Steve Streeting Date: Tue, 22 Mar 2016 10:38:10 +0000 Subject: [PATCH 1/3] Add git.GetTrackedFiles for reporting list of files tracked in git --- git/git.go | 27 ++++++++++++++ git/git_test.go | 98 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 125 insertions(+) diff --git a/git/git.go b/git/git.go index a177e900..79e14485 100644 --- a/git/git.go +++ b/git/git.go @@ -753,3 +753,30 @@ func RemoteRefs(remoteName string) ([]*Ref, error) { } return ret, nil } + +// GetTrackedFiles returns a list of files which are tracked in Git which match +// the pattern specified (standard wildcard form) +// Both pattern and the results are relative to the current working directory, not +// the root of the repository +func GetTrackedFiles(pattern string) ([]string, error) { + var ret []string + cmd := subprocess.ExecCommand("git", + "-c", "core.quotepath=false", // handle special chars in filenames + "ls-files", + "--cached", // include things which are staged but not committed right now + "--", // no ambiguous patterns + pattern) + + outp, err := cmd.StdoutPipe() + if err != nil { + return nil, fmt.Errorf("Failed to call git ls-files: %v", err) + } + cmd.Start() + scanner := bufio.NewScanner(outp) + for scanner.Scan() { + line := scanner.Text() + ret = append(ret, strings.TrimSpace(line)) + } + return ret, nil + +} diff --git a/git/git_test.go b/git/git_test.go index 19de3c0f..c0e9000a 100644 --- a/git/git_test.go +++ b/git/git_test.go @@ -1,6 +1,8 @@ package git_test // to avoid import cycles import ( + "io/ioutil" + "os" "path/filepath" "sort" "testing" @@ -280,3 +282,99 @@ func TestGitAndRootDirs(t *testing.T) { assert.Equal(t, git, filepath.Join(root, ".git")) } + +func TestGetTrackedFiles(t *testing.T) { + repo := test.NewRepo(t) + repo.Pushd() + defer func() { + repo.Popd() + repo.Cleanup() + }() + + // test commits; we'll just modify the same file each time since we're + // only interested in branches + inputs := []*test.CommitInput{ + { // 0 + Files: []*test.FileInput{ + {Filename: "file1.txt", Size: 20}, + {Filename: "file2.txt", Size: 20}, + {Filename: "folder1/file10.txt", Size: 20}, + {Filename: "folder1/anotherfile.txt", Size: 20}, + }, + }, + { // 1 + Files: []*test.FileInput{ + {Filename: "file3.txt", Size: 20}, + {Filename: "file4.txt", Size: 20}, + {Filename: "folder2/something.txt", Size: 20}, + {Filename: "folder2/folder3/deep.txt", Size: 20}, + }, + }, + } + repo.AddCommits(inputs) + + tracked, err := GetTrackedFiles("*.txt") + assert.Equal(t, nil, err) + sort.Strings(tracked) // for direct comparison + fulllist := []string{"file1.txt", "file2.txt", "file3.txt", "file4.txt", "folder1/anotherfile.txt", "folder1/file10.txt", "folder2/folder3/deep.txt", "folder2/something.txt"} + assert.Equal(t, fulllist, tracked) + + tracked, err = GetTrackedFiles("*file*.txt") + assert.Equal(t, nil, err) + sort.Strings(tracked) + sublist := []string{"file1.txt", "file2.txt", "file3.txt", "file4.txt", "folder1/anotherfile.txt", "folder1/file10.txt"} + assert.Equal(t, sublist, tracked) + + tracked, err = GetTrackedFiles("folder1/*") + assert.Equal(t, nil, err) + sort.Strings(tracked) + sublist = []string{"folder1/anotherfile.txt", "folder1/file10.txt"} + assert.Equal(t, sublist, tracked) + + tracked, err = GetTrackedFiles("folder2/*") + assert.Equal(t, nil, err) + sort.Strings(tracked) + sublist = []string{"folder2/folder3/deep.txt", "folder2/something.txt"} + assert.Equal(t, sublist, tracked) + + // relative dir + os.Chdir("folder1") + tracked, err = GetTrackedFiles("*.txt") + assert.Equal(t, nil, err) + sort.Strings(tracked) + sublist = []string{"anotherfile.txt", "file10.txt"} + assert.Equal(t, sublist, tracked) + os.Chdir("..") + + // Test includes staged but uncommitted files + ioutil.WriteFile("z_newfile.txt", []byte("Hello world"), 0644) + test.RunGitCommand(t, true, "add", "z_newfile.txt") + tracked, err = GetTrackedFiles("*.txt") + assert.Equal(t, nil, err) + sort.Strings(tracked) + fulllist = append(fulllist, "z_newfile.txt") + assert.Equal(t, fulllist, tracked) + + // Test includes modified files (not staged) + ioutil.WriteFile("file1.txt", []byte("Modifications"), 0644) + tracked, err = GetTrackedFiles("*.txt") + assert.Equal(t, nil, err) + sort.Strings(tracked) + assert.Equal(t, fulllist, tracked) + + // Test includes modified files (staged) + test.RunGitCommand(t, true, "add", "file1.txt") + tracked, err = GetTrackedFiles("*.txt") + assert.Equal(t, nil, err) + sort.Strings(tracked) + assert.Equal(t, fulllist, tracked) + + // Test excludes deleted files (not committed) + test.RunGitCommand(t, true, "rm", "file2.txt") + tracked, err = GetTrackedFiles("*.txt") + assert.Equal(t, nil, err) + sort.Strings(tracked) + deletedlist := []string{"file1.txt", "file3.txt", "file4.txt", "folder1/anotherfile.txt", "folder1/file10.txt", "folder2/folder3/deep.txt", "folder2/something.txt", "z_newfile.txt"} + assert.Equal(t, deletedlist, tracked) + +} From 875b4deef06cd6d1de1359b490b7034fdec27a5a Mon Sep 17 00:00:00 2001 From: Steve Streeting Date: Tue, 22 Mar 2016 10:39:55 +0000 Subject: [PATCH 2/3] 'git lfs track' now automatically touches matching files already in git This makes them appear as modified in 'git status' which indicates they need to be re-committed to be moved into LFS if already in git. See #1057 --- commands/command_track.go | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/commands/command_track.go b/commands/command_track.go index 78cb6383..a8f8ed3b 100644 --- a/commands/command_track.go +++ b/commands/command_track.go @@ -7,6 +7,9 @@ import ( "os" "path/filepath" "strings" + "time" + + "github.com/github/git-lfs/git" "github.com/github/git-lfs/lfs" "github.com/github/git-lfs/vendor/_nuts/github.com/spf13/cobra" @@ -77,6 +80,25 @@ ArgsLoop: continue } Print("Tracking %s", pattern) + + // Make sure any existing git tracked files have their timestamp updated + // so they will now show as modifed + // note this is relative to current dir which is how we write .gitattributes + // deliberately not done in parallel as a chan because we'll be marking modified + gittracked, err := git.GetTrackedFiles(pattern) + if err != nil { + LoggedError(err, "Error getting git tracked files") + continue + } + now := time.Now() + for _, f := range gittracked { + err := os.Chtimes(f, now, now) + if err != nil { + LoggedError(err, "Error marking %q modified", f) + continue + } + } + } } From 70e5df64acdcb4f86077e1399b0df0925435ed9b Mon Sep 17 00:00:00 2001 From: risk danger olson Date: Mon, 4 Apr 2016 14:41:43 -0600 Subject: [PATCH 3/3] wait for the command to finish --- git/git.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/git/git.go b/git/git.go index 79e14485..556cb26c 100644 --- a/git/git.go +++ b/git/git.go @@ -777,6 +777,6 @@ func GetTrackedFiles(pattern string) ([]string, error) { line := scanner.Text() ret = append(ret, strings.TrimSpace(line)) } - return ret, nil + return ret, cmd.Wait() }