func trackCommand(cmd *cobra.Command, args []string) { requireGitVersion() if config.LocalGitDir == "" { Print("Not a git repository.") os.Exit(128) } if config.LocalWorkingDir == "" { Print("This operation must be run in a work tree.") os.Exit(128) } lfs.InstallHooks(false) knownPaths := findPaths() if len(args) == 0 { Print("Listing tracked paths") for _, t := range knownPaths { Print(" %s (%s)", t.Path, t.Source) } return } addTrailingLinebreak := needsTrailingLinebreak(".gitattributes") attributesFile, err := os.OpenFile(".gitattributes", os.O_RDWR|os.O_APPEND|os.O_CREATE, 0660) if err != nil { Print("Error opening .gitattributes file") return } defer attributesFile.Close() if addTrailingLinebreak { if _, err := attributesFile.WriteString("\n"); err != nil { Print("Error writing to .gitattributes") } } wd, _ := os.Getwd() relpath, err := filepath.Rel(config.LocalWorkingDir, wd) if err != nil { Exit("Current directory %q outside of git working directory %q.", wd, config.LocalWorkingDir) } ArgsLoop: for _, pattern := range args { for _, known := range knownPaths { if known.Path == filepath.Join(relpath, pattern) { Print("%s already supported", pattern) continue ArgsLoop } } // 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 // // NOTE: `git ls-files` does not do well with leading slashes. // Since all `git-lfs track` calls are relative to the root of // the repository, the leading slash is simply removed for its // implicit counterpart. if trackVerboseLoggingFlag { Print("Searching for files matching pattern: %s", pattern) } gittracked, err := git.GetTrackedFiles(pattern) if err != nil { LoggedError(err, "Error getting git tracked files") continue } if trackVerboseLoggingFlag { Print("Found %d files previously added to Git matching pattern: %s", len(gittracked), pattern) } now := time.Now() var matchedBlocklist bool for _, f := range gittracked { if forbidden := blocklistItem(f); forbidden != "" { Print("Pattern %s matches forbidden file %s. If you would like to track %s, modify .gitattributes manually.", pattern, f, f) matchedBlocklist = true } } if matchedBlocklist { continue } if !trackDryRunFlag { encodedArg := strings.Replace(pattern, " ", "[[:space:]]", -1) _, err := attributesFile.WriteString(fmt.Sprintf("%s filter=lfs diff=lfs merge=lfs -text\n", encodedArg)) if err != nil { Print("Error adding path %s", pattern) continue } } Print("Tracking %s", pattern) for _, f := range gittracked { if trackVerboseLoggingFlag || trackDryRunFlag { Print("Git LFS: touching %s", f) } if !trackDryRunFlag { err := os.Chtimes(f, now, now) if err != nil { LoggedError(err, "Error marking %q modified", f) continue } } } } }
func trackCommand(cmd *cobra.Command, args []string) { if lfs.LocalGitDir == "" { Print("Not a git repository.") os.Exit(128) } if lfs.LocalWorkingDir == "" { Print("This operation must be run in a work tree.") os.Exit(128) } lfs.InstallHooks(false) knownPaths := findPaths() if len(args) == 0 { Print("Listing tracked paths") for _, t := range knownPaths { Print(" %s (%s)", t.Path, t.Source) } return } addTrailingLinebreak := needsTrailingLinebreak(".gitattributes") attributesFile, err := os.OpenFile(".gitattributes", os.O_RDWR|os.O_APPEND|os.O_CREATE, 0660) if err != nil { Print("Error opening .gitattributes file") return } defer attributesFile.Close() if addTrailingLinebreak { if _, err := attributesFile.WriteString("\n"); err != nil { Print("Error writing to .gitattributes") } } wd, _ := os.Getwd() relpath, err := filepath.Rel(lfs.LocalWorkingDir, wd) if err != nil { Exit("Current directory %q outside of git working directory %q.", wd, lfs.LocalWorkingDir) } ArgsLoop: for _, pattern := range args { for _, known := range knownPaths { if known.Path == filepath.Join(relpath, pattern) { Print("%s already supported", pattern) continue ArgsLoop } } encodedArg := strings.Replace(pattern, " ", "[[:space:]]", -1) _, err := attributesFile.WriteString(fmt.Sprintf("%s filter=lfs diff=lfs merge=lfs -text\n", encodedArg)) if err != nil { Print("Error adding path %s", pattern) 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 } } } }