612ce5881e580d339de4ff38ef6df42a3030cd49
[scm/test.git] / commands / command_ls_files.go
1 package commands
2
3 import (
4         "os"
5         "strings"
6
7         "github.com/git-lfs/git-lfs/git"
8         "github.com/git-lfs/git-lfs/lfs"
9         "github.com/git-lfs/git-lfs/tools/humanize"
10         "github.com/spf13/cobra"
11 )
12
13 var (
14         longOIDs           = false
15         lsFilesScanAll     = false
16         lsFilesScanDeleted = false
17         lsFilesShowSize    = false
18         debug              = false
19 )
20
21 func lsFilesCommand(cmd *cobra.Command, args []string) {
22         requireInRepo()
23
24         var ref string
25
26         if len(args) == 1 {
27                 if lsFilesScanAll {
28                         Exit("fatal: cannot use --all with explicit reference")
29                 }
30                 ref = args[0]
31         } else {
32                 fullref, err := git.CurrentRef()
33                 if err != nil {
34                         ref = git.RefBeforeFirstCommit
35                 } else {
36                         ref = fullref.Sha
37                 }
38         }
39
40         showOidLen := 10
41         if longOIDs {
42                 showOidLen = 64
43         }
44
45         seen := make(map[string]struct{})
46
47         gitscanner := lfs.NewGitScanner(func(p *lfs.WrappedPointer, err error) {
48                 if err != nil {
49                         Exit("Could not scan for Git LFS tree: %s", err)
50                         return
51                 }
52
53                 if !lsFilesScanAll {
54                         if _, ok := seen[p.Name]; ok {
55                                 return
56                         }
57                 }
58
59                 if debug {
60                         Print(
61                                 "filepath: %s\n"+
62                                         "    size: %d\n"+
63                                         "checkout: %v\n"+
64                                         "download: %v\n"+
65                                         "     oid: %s %s\n"+
66                                         " version: %s\n",
67                                 p.Name,
68                                 p.Size,
69                                 fileExistsOfSize(p),
70                                 cfg.LFSObjectExists(p.Oid, p.Size),
71                                 p.OidType,
72                                 p.Oid,
73                                 p.Version)
74                 } else {
75                         msg := []string{p.Oid[:showOidLen], lsFilesMarker(p), p.Name}
76                         if lsFilesShowSize {
77                                 size := humanize.FormatBytes(uint64(p.Size))
78                                 msg = append(msg, "("+size+")")
79                         }
80
81                         Print(strings.Join(msg, " "))
82                 }
83
84                 seen[p.Name] = struct{}{}
85         })
86         defer gitscanner.Close()
87
88         includeArg, excludeArg := getIncludeExcludeArgs(cmd)
89         gitscanner.Filter = buildFilepathFilter(cfg, includeArg, excludeArg)
90
91         if err := gitscanner.ScanIndex(ref, nil); err != nil {
92                 Exit("Could not scan for Git LFS index: %s", err)
93         }
94         if lsFilesScanAll {
95                 if err := gitscanner.ScanAll(nil); err != nil {
96                         Exit("Could not scan for Git LFS history: %s", err)
97                 }
98         } else {
99                 var err error
100                 if lsFilesScanDeleted {
101                         err = gitscanner.ScanRefWithDeleted(ref, nil)
102                 } else {
103                         err = gitscanner.ScanTree(ref)
104                 }
105
106                 if err != nil {
107                         Exit("Could not scan for Git LFS tree: %s", err)
108                 }
109         }
110 }
111
112 // Returns true if a pointer appears to be properly smudge on checkout
113 func fileExistsOfSize(p *lfs.WrappedPointer) bool {
114         info, err := os.Stat(p.Name)
115         return err == nil && info.Size() == p.Size
116 }
117
118 func lsFilesMarker(p *lfs.WrappedPointer) string {
119         if fileExistsOfSize(p) {
120                 return "*"
121         }
122         return "-"
123 }
124
125 func init() {
126         RegisterCommand("ls-files", lsFilesCommand, func(cmd *cobra.Command) {
127                 cmd.Flags().BoolVarP(&longOIDs, "long", "l", false, "")
128                 cmd.Flags().BoolVarP(&lsFilesShowSize, "size", "s", false, "")
129                 cmd.Flags().BoolVarP(&debug, "debug", "d", false, "")
130                 cmd.Flags().BoolVarP(&lsFilesScanAll, "all", "a", false, "")
131                 cmd.Flags().BoolVar(&lsFilesScanDeleted, "deleted", false, "")
132                 cmd.Flags().StringVarP(&includeArg, "include", "I", "", "Include a list of paths")
133                 cmd.Flags().StringVarP(&excludeArg, "exclude", "X", "", "Exclude a list of paths")
134         })
135 }