push: add ability to read values from stdin
Read refs from stdin: `printf "branch\ntag" | git lfs push <remote> --stdin` Read object IDs from stdin: `printf "c0ffee..." | git lfs push --object-id <remote> --stdin` Values read from stdin are newline-delimited.
This commit is contained in:
parent
7001116051
commit
e35f407d6a
@ -1,6 +1,7 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"os"
|
||||
|
||||
"github.com/git-lfs/git-lfs/v3/errors"
|
||||
@ -21,12 +22,15 @@ var (
|
||||
// shares some global vars and functions with command_pre_push.go
|
||||
)
|
||||
|
||||
// pushCommand pushes local objects to a Git LFS server. It takes two
|
||||
// arguments:
|
||||
// pushCommand pushes local objects to a Git LFS server. It has four forms:
|
||||
//
|
||||
// `<remote> <remote ref>`
|
||||
// `<remote> <ref>...`
|
||||
// `<remote> --stdin` (reads refs from stdin)
|
||||
// `<remote> --object-id <oid>...`
|
||||
// `<remote> --object-id --stdin` (reads oids from stdin)
|
||||
//
|
||||
// Remote must be a remote name, not a URL
|
||||
// Remote must be a remote name, not a URL. With --stdin, values are newline
|
||||
// separated.
|
||||
//
|
||||
// pushCommand calculates the git objects to send by comparing the range
|
||||
// of commits between the local and remote git servers.
|
||||
@ -44,15 +48,36 @@ func pushCommand(cmd *cobra.Command, args []string) {
|
||||
}
|
||||
|
||||
ctx := newUploadContext(pushDryRun)
|
||||
if pushObjectIDs {
|
||||
if len(args) < 2 {
|
||||
Print(tr.Tr.Get("At least one object ID must be supplied with --object-id"))
|
||||
return
|
||||
|
||||
var argList []string
|
||||
if useStdin {
|
||||
if len(args) > 1 {
|
||||
Print(tr.Tr.Get("Further command line arguments are ignored with --stdin"))
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
uploadsWithObjectIDs(ctx, args[1:])
|
||||
scanner := bufio.NewScanner(os.Stdin) // line-delimited
|
||||
for scanner.Scan() {
|
||||
line := scanner.Text()
|
||||
if line != "" {
|
||||
argList = append(argList, line)
|
||||
}
|
||||
}
|
||||
if err := scanner.Err(); err != nil {
|
||||
ExitWithError(errors.Wrap(err, tr.Tr.Get("Error reading from stdin:")))
|
||||
}
|
||||
} else {
|
||||
uploadsBetweenRefAndRemote(ctx, args[1:])
|
||||
argList = args[1:]
|
||||
}
|
||||
|
||||
if pushObjectIDs {
|
||||
if len(argList) < 1 {
|
||||
Print(tr.Tr.Get("At least one object ID must be supplied with --object-id"))
|
||||
os.Exit(1)
|
||||
}
|
||||
uploadsWithObjectIDs(ctx, argList)
|
||||
} else {
|
||||
uploadsBetweenRefAndRemote(ctx, argList)
|
||||
}
|
||||
}
|
||||
|
||||
@ -137,6 +162,7 @@ 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(&useStdin, "stdin", "", false, "Read object IDs or refs from stdin")
|
||||
cmd.Flags().BoolVarP(&pushAll, "all", "a", false, "Push all objects for the current ref to the remote.")
|
||||
})
|
||||
}
|
||||
|
@ -8,7 +8,9 @@ git-lfs-push - Push queued large files to the Git LFS endpoint
|
||||
|
||||
`git lfs push` [options] <remote> [<ref>...] +
|
||||
`git lfs push` <remote> [<ref>...] +
|
||||
`git lfs push` [options] <remote> --stdin
|
||||
`git lfs push` --object-id <remote> [<oid>...]
|
||||
`git lfs push` --object-id <remote> --stdin
|
||||
|
||||
== DESCRIPTION
|
||||
|
||||
@ -32,6 +34,9 @@ by the local clone of the remote.
|
||||
`--object-id`::
|
||||
This pushes only the object OIDs listed at the end of the command, separated
|
||||
by spaces.
|
||||
`--stdin`::
|
||||
Read a list of newline-delimited refs (or object IDs when using `--object-id`)
|
||||
from standard input instead of the command line.
|
||||
|
||||
== SEE ALSO
|
||||
|
||||
|
64
t/t-push.sh
64
t/t-push.sh
@ -66,6 +66,17 @@ begin_test "push with given remote, configured pushRemote"
|
||||
)
|
||||
end_test
|
||||
|
||||
begin_test "push via stdin with extra arguments"
|
||||
(
|
||||
set -e
|
||||
|
||||
push_repo_setup "push-stdin-extra-args"
|
||||
|
||||
echo "main" | git lfs push origin --stdin --dry-run "another-ref" \
|
||||
2>&1 | tee push.log
|
||||
grep "Further command line arguments are ignored with --stdin" push.log
|
||||
)
|
||||
|
||||
begin_test "push"
|
||||
(
|
||||
set -e
|
||||
@ -98,6 +109,11 @@ begin_test "push"
|
||||
grep "push 82be50ad35070a4ef3467a0a650c52d5b637035e7ad02c36652e59d01ba282b7 => b.dat" push.log
|
||||
[ $(grep -c "^push " < push.log) -eq 2 ]
|
||||
|
||||
printf "push-b\n\n" | git lfs push --dry-run origin --stdin 2>&1 | tee push.log
|
||||
grep "push 4c48d2a6991c9895bcddcf027e1e4907280bcf21975492b1afbade396d6a3340 => a.dat" push.log
|
||||
grep "push 82be50ad35070a4ef3467a0a650c52d5b637035e7ad02c36652e59d01ba282b7 => b.dat" push.log
|
||||
[ $(grep -c "^push " < push.log) -eq 2 ]
|
||||
|
||||
# simulate remote ref
|
||||
mkdir -p .git/refs/remotes/origin
|
||||
git rev-parse HEAD > .git/refs/remotes/origin/HEAD
|
||||
@ -301,6 +317,13 @@ begin_test "push --all (multiple ref args)"
|
||||
grep "push $oid4 => file1.dat" push.log
|
||||
[ $(grep -c "^push " push.log) -eq 4 ]
|
||||
|
||||
printf "branch\ntag" | git lfs push --dry-run --all origin --stdin 2>&1 | tee push.log
|
||||
grep "push $oid1 => file1.dat" push.log
|
||||
grep "push $oid2 => file1.dat" push.log
|
||||
grep "push $oid3 => file1.dat" push.log
|
||||
grep "push $oid4 => file1.dat" push.log
|
||||
[ $(grep -c "^push " push.log) -eq 4 ]
|
||||
|
||||
git lfs push --all origin branch tag 2>&1 | tee push.log
|
||||
[ $(grep -c "Uploading LFS objects: 100% (4/4)" push.log) -eq 1 ]
|
||||
assert_server_object "$reponame-$suffix" "$oid1"
|
||||
@ -426,6 +449,47 @@ begin_test "push object id(s)"
|
||||
)
|
||||
end_test
|
||||
|
||||
begin_test "push object id(s) via stdin"
|
||||
(
|
||||
set -e
|
||||
|
||||
reponame="$(basename "$0" ".sh")"
|
||||
setup_remote_repo "$reponame"
|
||||
clone_repo "$reponame" repo3
|
||||
|
||||
git config "lfs.$(repo_endpoint "$GITSERVER" "$reponame").locksverify" true
|
||||
|
||||
git lfs track "*.dat"
|
||||
echo "push a" > a.dat
|
||||
git add .gitattributes a.dat
|
||||
git commit -m "add a.dat"
|
||||
|
||||
echo "" | git lfs push --object-id origin --stdin --dry-run \
|
||||
2>&1 | tee push.log
|
||||
grep "At least one object ID must be supplied with --object-id" push.log
|
||||
|
||||
echo "4c48d2a6991c9895bcddcf027e1e4907280bcf21975492b1afbade396d6a3340" | \
|
||||
git lfs push --object-id origin --stdin --dry-run "c0ffee" \
|
||||
2>&1 | tee push.log
|
||||
grep "Further command line arguments are ignored with --stdin" push.log
|
||||
|
||||
echo "4c48d2a6991c9895bcddcf027e1e4907280bcf21975492b1afbade396d6a3340" | \
|
||||
git lfs push --object-id origin --stdin --dry-run \
|
||||
2>&1 | tee push.log
|
||||
grep "push 4c48d2a6991c9895bcddcf027e1e4907280bcf21975492b1afbade396d6a3340 =>" push.log
|
||||
|
||||
echo "push b" > b.dat
|
||||
git add b.dat
|
||||
git commit -m "add b.dat"
|
||||
|
||||
printf "4c48d2a6991c9895bcddcf027e1e4907280bcf21975492b1afbade396d6a3340\n82be50ad35070a4ef3467a0a650c52d5b637035e7ad02c36652e59d01ba282b7\n\n" | \
|
||||
git lfs push --object-id origin --stdin --dry-run \
|
||||
2>&1 | tee push.log
|
||||
grep "push 4c48d2a6991c9895bcddcf027e1e4907280bcf21975492b1afbade396d6a3340 =>" push.log
|
||||
grep "push 82be50ad35070a4ef3467a0a650c52d5b637035e7ad02c36652e59d01ba282b7 =>" push.log
|
||||
)
|
||||
end_test
|
||||
|
||||
begin_test "push modified files"
|
||||
(
|
||||
set -e
|
||||
|
Loading…
Reference in New Issue
Block a user