From d7589752a99263beec6bf7cf236e008a2e6634d7 Mon Sep 17 00:00:00 2001 From: Steve Streeting Date: Fri, 4 Sep 2015 14:59:56 +0100 Subject: [PATCH] Fix pre-push hook when multiple branches are pushed in one `git push` --- commands/command_pre_push.go | 128 +++++++++++++++++------------------ 1 file changed, 64 insertions(+), 64 deletions(-) diff --git a/commands/command_pre_push.go b/commands/command_pre_push.go index d0c6a746..3d227ea2 100644 --- a/commands/command_pre_push.go +++ b/commands/command_pre_push.go @@ -1,7 +1,7 @@ package commands import ( - "io/ioutil" + "bufio" "os" "strings" @@ -43,7 +43,6 @@ var ( // In the case of deleting a branch, no attempts to push Git LFS objects will be // made. func prePushCommand(cmd *cobra.Command, args []string) { - var left, right string if len(args) == 0 { Print("This should be run through Git's pre-push hook. Run `git lfs update` to install it.") @@ -52,79 +51,80 @@ func prePushCommand(cmd *cobra.Command, args []string) { lfs.Config.CurrentRemote = args[0] - refsData, err := ioutil.ReadAll(os.Stdin) - if err != nil { - Panic(err, "Error reading refs on stdin") - } + // We can be passed multiple lines of refs + scanner := bufio.NewScanner(os.Stdin) + for scanner.Scan() { + line := strings.TrimSpace(scanner.Text()) - if len(refsData) == 0 { - return - } - - left, right = decodeRefs(string(refsData)) - if left == prePushDeleteBranch { - return - } - - // Just use scanner here - scanOpt := &lfs.ScanRefsOptions{ScanMode: lfs.ScanLeftToRemoteMode, RemoteName: lfs.Config.CurrentRemote} - pointers, err := lfs.ScanRefs(left, right, scanOpt) - if err != nil { - Panic(err, "Error scanning for Git LFS files") - } - - totalSize := int64(0) - for _, p := range pointers { - totalSize += p.Size - } - - // Objects to skip because they're missing locally but on server - var skipObjects map[string]struct{} - - if !prePushDryRun { - // Do this as a pre-flight check since upload queue starts immediately - skipObjects = prePushCheckForMissingObjects(pointers) - } - - uploadQueue := lfs.NewUploadQueue(len(pointers), totalSize, prePushDryRun) - - for _, pointer := range pointers { - if prePushDryRun { - Print("push %s [%s]", pointer.Name, pointer.Oid) + if len(line) == 0 { continue } - if _, skip := skipObjects[pointer.Oid]; skip { - // object missing locally but on server, don't bother - continue + left, right := decodeRefs(line) + if left == prePushDeleteBranch { + return } - u, err := lfs.NewUploadable(pointer.Oid, pointer.Name) + // Just use scanner here + scanOpt := &lfs.ScanRefsOptions{ScanMode: lfs.ScanLeftToRemoteMode, RemoteName: lfs.Config.CurrentRemote} + pointers, err := lfs.ScanRefs(left, right, scanOpt) if err != nil { - if lfs.IsCleanPointerError(err) { - Exit(prePushMissingErrMsg, pointer.Name, lfs.ErrorGetContext(err, "pointer").(*lfs.Pointer).Oid) - } else if Debugging || lfs.IsFatalError(err) { - Panic(err, err.Error()) - } else { - Exit(err.Error()) - } + Panic(err, "Error scanning for Git LFS files") } - uploadQueue.Add(u) - } - - if !prePushDryRun { - uploadQueue.Wait() - for _, err := range uploadQueue.Errors() { - if Debugging || lfs.IsFatalError(err) { - LoggedError(err, err.Error()) - } else { - Error(err.Error()) - } + totalSize := int64(0) + for _, p := range pointers { + totalSize += p.Size } - if len(uploadQueue.Errors()) > 0 { - os.Exit(2) + // Objects to skip because they're missing locally but on server + var skipObjects map[string]struct{} + + if !prePushDryRun { + // Do this as a pre-flight check since upload queue starts immediately + skipObjects = prePushCheckForMissingObjects(pointers) + } + + uploadQueue := lfs.NewUploadQueue(len(pointers), totalSize, prePushDryRun) + + for _, pointer := range pointers { + if prePushDryRun { + Print("push %s [%s]", pointer.Name, pointer.Oid) + continue + } + + if _, skip := skipObjects[pointer.Oid]; skip { + // object missing locally but on server, don't bother + continue + } + + u, err := lfs.NewUploadable(pointer.Oid, pointer.Name) + if err != nil { + if lfs.IsCleanPointerError(err) { + Exit(prePushMissingErrMsg, pointer.Name, lfs.ErrorGetContext(err, "pointer").(*lfs.Pointer).Oid) + } else if Debugging || lfs.IsFatalError(err) { + Panic(err, err.Error()) + } else { + Exit(err.Error()) + } + } + + uploadQueue.Add(u) + } + + if !prePushDryRun { + uploadQueue.Wait() + for _, err := range uploadQueue.Errors() { + if Debugging || lfs.IsFatalError(err) { + LoggedError(err, err.Error()) + } else { + Error(err.Error()) + } + } + + if len(uploadQueue.Errors()) > 0 { + os.Exit(2) + } } } }