Merge pull request #1104 from github/touch-tracked-files

Touch tracked files that are already added to git
This commit is contained in:
Steve Streeting 2016-04-05 09:24:00 +01:00
commit 65f53a600e
3 changed files with 147 additions and 0 deletions

@ -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
}
}
}
}

@ -757,3 +757,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, cmd.Wait()
}

@ -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)
}