github.com/stffabi/git-lfs@v2.3.5-0.20180214015214-8eeaa8d88902+incompatible/commands/command_post_checkout.go (about) 1 package commands 2 3 import ( 4 "os" 5 6 "github.com/git-lfs/git-lfs/git" 7 "github.com/git-lfs/git-lfs/locking" 8 "github.com/rubyist/tracerx" 9 "github.com/spf13/cobra" 10 ) 11 12 // postCheckoutCommand is run through Git's post-checkout hook. The hook passes 13 // up to 3 arguments on the command line: 14 // 15 // 1. SHA of previous commit before the checkout 16 // 2. SHA of commit just checked out 17 // 3. Flag ("0" or "1") - 1 if a branch/tag/SHA was checked out, 0 if a file was 18 // In the case of a file being checked out, the pre/post SHA are the same 19 // 20 // This hook checks that files which are lockable and not locked are made read-only, 21 // optimising that as best it can based on the available information. 22 func postCheckoutCommand(cmd *cobra.Command, args []string) { 23 if len(args) != 3 { 24 Print("This should be run through Git's post-checkout hook. Run `git lfs update` to install it.") 25 os.Exit(1) 26 } 27 28 // Skip entire hook if lockable read only feature is disabled 29 if !cfg.SetLockableFilesReadOnly() { 30 os.Exit(0) 31 } 32 33 requireGitVersion() 34 35 lockClient := newLockClient() 36 37 // Skip this hook if no lockable patterns have been configured 38 if len(lockClient.GetLockablePatterns()) == 0 { 39 os.Exit(0) 40 } 41 42 if args[2] == "1" && args[0] != "0000000000000000000000000000000000000000" { 43 postCheckoutRevChange(lockClient, args[0], args[1]) 44 } else { 45 postCheckoutFileChange(lockClient) 46 } 47 48 } 49 50 func postCheckoutRevChange(client *locking.Client, pre, post string) { 51 tracerx.Printf("post-checkout: changes between %v and %v", pre, post) 52 // We can speed things up by looking at the difference between previous HEAD 53 // and current HEAD, and only checking lockable files that are different 54 files, err := git.GetFilesChanged(pre, post) 55 56 if err != nil { 57 LoggedError(err, "Warning: post-checkout rev diff %v:%v failed: %v\nFalling back on full scan.", pre, post, err) 58 postCheckoutFileChange(client) 59 } 60 tracerx.Printf("post-checkout: checking write flags on %v", files) 61 err = client.FixLockableFileWriteFlags(files) 62 if err != nil { 63 LoggedError(err, "Warning: post-checkout locked file check failed: %v", err) 64 } 65 66 } 67 68 func postCheckoutFileChange(client *locking.Client) { 69 tracerx.Printf("post-checkout: checking write flags for all lockable files") 70 // Sadly we don't get any information about what files were checked out, 71 // so we have to check the entire repo 72 err := client.FixAllLockableFileWriteFlags() 73 if err != nil { 74 LoggedError(err, "Warning: post-checkout locked file check failed: %v", err) 75 } 76 } 77 78 func init() { 79 RegisterCommand("post-checkout", postCheckoutCommand, nil) 80 }