git-lfs/commands/command_push.go

136 lines
3.3 KiB
Go
Raw Normal View History

package commands
2013-10-04 17:09:03 +00:00
import (
2015-05-13 19:43:41 +00:00
"os"
2016-11-15 17:01:18 +00:00
"github.com/git-lfs/git-lfs/git"
"github.com/git-lfs/git-lfs/lfs"
"github.com/rubyist/tracerx"
"github.com/spf13/cobra"
2013-10-04 17:09:03 +00:00
)
2014-06-26 20:53:37 +00:00
var (
pushDryRun = false
pushObjectIDs = false
pushAll = false
useStdin = false
2015-04-24 16:41:11 +00:00
// shares some global vars and functions with command_pre_push.go
2014-06-26 20:53:37 +00:00
)
2013-10-04 17:09:03 +00:00
func uploadsBetweenRefAndRemote(ctx *uploadContext, refnames []string) {
2016-07-21 22:37:53 +00:00
tracerx.Printf("Upload refs %v to remote %v", refnames, cfg.CurrentRemote)
2015-09-08 20:51:38 +00:00
gitscanner := lfs.NewGitScanner(nil)
if err := gitscanner.RemoteForPush(cfg.CurrentRemote); err != nil {
ExitWithError(err)
}
defer gitscanner.Close()
refs, err := refsByNames(refnames)
if err != nil {
Error(err.Error())
Exit("Error getting local refs.")
}
for _, ref := range refs {
2016-11-16 20:51:36 +00:00
pointerCh, err := scanLeftOrAll(gitscanner, ref.Name)
if err != nil {
Panic(err, "Error scanning for Git LFS files in the %q ref", ref.Name)
}
2016-11-16 20:51:36 +00:00
upload(ctx, pointerCh)
}
}
2016-11-16 20:51:36 +00:00
func scanLeftOrAll(g *lfs.GitScanner, ref string) (*lfs.PointerChannelWrapper, error) {
if pushAll {
return g.ScanRefWithDeleted(ref)
}
2016-11-16 20:51:36 +00:00
return g.ScanLeftToRemote(ref)
}
func uploadsWithObjectIDs(ctx *uploadContext, oids []string) {
pointers := make([]*lfs.WrappedPointer, len(oids))
for idx, oid := range oids {
pointers[idx] = &lfs.WrappedPointer{Pointer: &lfs.Pointer{Oid: oid}}
}
2016-11-16 20:25:05 +00:00
uploadPointers(ctx, pointers)
}
func refsByNames(refnames []string) ([]*git.Ref, error) {
localrefs, err := git.LocalRefs()
if err != nil {
return nil, err
}
if pushAll && len(refnames) == 0 {
return localrefs, nil
}
reflookup := make(map[string]*git.Ref, len(localrefs))
for _, ref := range localrefs {
reflookup[ref.Name] = ref
}
refs := make([]*git.Ref, len(refnames))
for i, name := range refnames {
if ref, ok := reflookup[name]; ok {
refs[i] = ref
} else {
refs[i] = &git.Ref{name, git.RefTypeOther, name}
}
}
return refs, nil
}
2015-04-24 16:41:11 +00:00
// pushCommand pushes local objects to a Git LFS server. It takes two
// arguments:
2014-09-24 17:10:29 +00:00
//
2015-04-24 16:41:11 +00:00
// `<remote> <remote ref>`
2014-09-24 17:10:29 +00:00
//
2016-02-29 14:22:03 +00:00
// Remote must be a remote name, not a URL
2014-09-24 17:10:29 +00:00
//
2015-04-24 16:41:11 +00:00
// pushCommand calculates the git objects to send by looking comparing the range
// of commits between the local and remote git servers.
2014-06-26 20:53:37 +00:00
func pushCommand(cmd *cobra.Command, args []string) {
if len(args) == 0 {
Print("Specify a remote and a remote branch name (`git lfs push origin master`)")
os.Exit(1)
}
requireGitVersion()
// Remote is first arg
if err := git.ValidateRemote(args[0]); err != nil {
Exit("Invalid remote name %q", args[0])
}
2016-07-21 22:37:53 +00:00
cfg.CurrentRemote = args[0]
ctx := newUploadContext(pushDryRun)
if pushObjectIDs {
if len(args) < 2 {
2015-07-06 13:48:39 +00:00
Print("Usage: git lfs push --object-id <remote> <lfs-object-id> [lfs-object-id] ...")
return
}
uploadsWithObjectIDs(ctx, args[1:])
} else {
2014-09-29 16:52:24 +00:00
if len(args) < 1 {
2015-04-24 16:41:11 +00:00
Print("Usage: git lfs push --dry-run <remote> [ref]")
return
}
uploadsBetweenRefAndRemote(ctx, args[1:])
}
2013-10-04 17:09:03 +00:00
}
func init() {
RegisterCommand("push", pushCommand, func(cmd *cobra.Command) {
cmd.Flags().BoolVarP(&pushDryRun, "dry-run", "d", false, "Do everything except actually send the updates")
cmd.Flags().BoolVarP(&pushObjectIDs, "object-id", "o", false, "Push LFS object ID(s)")
cmd.Flags().BoolVarP(&pushAll, "all", "a", false, "Push all objects for the current ref to the remote.")
})
2013-10-04 17:09:03 +00:00
}