2017-01-02 13:07:53 +00:00
|
|
|
package commands
|
|
|
|
|
|
|
|
import (
|
|
|
|
"os"
|
|
|
|
|
2021-09-01 19:41:10 +00:00
|
|
|
"github.com/git-lfs/git-lfs/v3/git"
|
|
|
|
"github.com/git-lfs/git-lfs/v3/locking"
|
2021-12-13 19:24:35 +00:00
|
|
|
"github.com/git-lfs/git-lfs/v3/tr"
|
2016-10-17 15:18:18 +00:00
|
|
|
"github.com/rubyist/tracerx"
|
2017-01-02 13:07:53 +00:00
|
|
|
"github.com/spf13/cobra"
|
|
|
|
)
|
|
|
|
|
|
|
|
// postCheckoutCommand is run through Git's post-checkout hook. The hook passes
|
|
|
|
// up to 3 arguments on the command line:
|
|
|
|
//
|
|
|
|
// 1. SHA of previous commit before the checkout
|
|
|
|
// 2. SHA of commit just checked out
|
|
|
|
// 3. Flag ("0" or "1") - 1 if a branch/tag/SHA was checked out, 0 if a file was
|
|
|
|
// In the case of a file being checked out, the pre/post SHA are the same
|
|
|
|
//
|
|
|
|
// This hook checks that files which are lockable and not locked are made read-only,
|
|
|
|
// optimising that as best it can based on the available information.
|
|
|
|
func postCheckoutCommand(cmd *cobra.Command, args []string) {
|
|
|
|
if len(args) != 3 {
|
2021-12-13 19:24:35 +00:00
|
|
|
Print(tr.Tr.Get("This should be run through Git's post-checkout hook. Run `git lfs update` to install it."))
|
2017-01-02 13:07:53 +00:00
|
|
|
os.Exit(1)
|
|
|
|
}
|
|
|
|
|
2017-01-06 09:37:31 +00:00
|
|
|
// Skip entire hook if lockable read only feature is disabled
|
2017-01-06 09:53:14 +00:00
|
|
|
if !cfg.SetLockableFilesReadOnly() {
|
2017-01-06 09:37:31 +00:00
|
|
|
os.Exit(0)
|
|
|
|
}
|
|
|
|
|
2017-01-02 13:07:53 +00:00
|
|
|
requireGitVersion()
|
|
|
|
|
2017-10-27 21:07:32 +00:00
|
|
|
lockClient := newLockClient()
|
2017-01-02 13:07:53 +00:00
|
|
|
|
|
|
|
// Skip this hook if no lockable patterns have been configured
|
2017-01-06 09:37:31 +00:00
|
|
|
if len(lockClient.GetLockablePatterns()) == 0 {
|
2017-01-02 13:07:53 +00:00
|
|
|
os.Exit(0)
|
|
|
|
}
|
|
|
|
|
2017-01-02 16:50:01 +00:00
|
|
|
if args[2] == "1" && args[0] != "0000000000000000000000000000000000000000" {
|
2017-01-02 13:07:53 +00:00
|
|
|
postCheckoutRevChange(lockClient, args[0], args[1])
|
|
|
|
} else {
|
|
|
|
postCheckoutFileChange(lockClient)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func postCheckoutRevChange(client *locking.Client, pre, post string) {
|
2016-10-17 15:18:18 +00:00
|
|
|
tracerx.Printf("post-checkout: changes between %v and %v", pre, post)
|
2017-01-02 13:07:53 +00:00
|
|
|
// We can speed things up by looking at the difference between previous HEAD
|
|
|
|
// and current HEAD, and only checking lockable files that are different
|
|
|
|
files, err := git.GetFilesChanged(pre, post)
|
|
|
|
|
|
|
|
if err != nil {
|
2021-12-13 19:24:35 +00:00
|
|
|
LoggedError(err, tr.Tr.Get("Warning: post-checkout rev diff %v:%v failed: %v\nFalling back on full scan.", pre, post, err))
|
2017-01-02 13:07:53 +00:00
|
|
|
postCheckoutFileChange(client)
|
|
|
|
}
|
2016-10-17 15:18:18 +00:00
|
|
|
tracerx.Printf("post-checkout: checking write flags on %v", files)
|
2017-01-02 13:07:53 +00:00
|
|
|
err = client.FixLockableFileWriteFlags(files)
|
|
|
|
if err != nil {
|
2021-12-13 19:24:35 +00:00
|
|
|
LoggedError(err, tr.Tr.Get("Warning: post-checkout locked file check failed: %v", err))
|
2017-01-02 13:07:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func postCheckoutFileChange(client *locking.Client) {
|
2016-10-17 15:18:18 +00:00
|
|
|
tracerx.Printf("post-checkout: checking write flags for all lockable files")
|
2017-01-02 13:07:53 +00:00
|
|
|
// Sadly we don't get any information about what files were checked out,
|
|
|
|
// so we have to check the entire repo
|
|
|
|
err := client.FixAllLockableFileWriteFlags()
|
|
|
|
if err != nil {
|
2021-12-13 19:24:35 +00:00
|
|
|
LoggedError(err, tr.Tr.Get("Warning: post-checkout locked file check failed: %v", err))
|
2017-01-02 13:07:53 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func init() {
|
2017-01-02 14:37:08 +00:00
|
|
|
RegisterCommand("post-checkout", postCheckoutCommand, nil)
|
2017-01-02 13:07:53 +00:00
|
|
|
}
|