123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110 |
- // Package copy provides the copy command.
- package copy
- import (
- "context"
- "strings"
- "github.com/rclone/rclone/cmd"
- "github.com/rclone/rclone/fs/config/flags"
- "github.com/rclone/rclone/fs/operations"
- "github.com/rclone/rclone/fs/sync"
- "github.com/spf13/cobra"
- )
- var (
- createEmptySrcDirs = false
- )
- func init() {
- cmd.Root.AddCommand(commandDefinition)
- cmdFlags := commandDefinition.Flags()
- flags.BoolVarP(cmdFlags, &createEmptySrcDirs, "create-empty-src-dirs", "", createEmptySrcDirs, "Create empty source dirs on destination after copy", "")
- }
- var commandDefinition = &cobra.Command{
- Use: "copy source:path dest:path",
- Short: `Copy files from source to dest, skipping identical files.`,
- // Note: "|" will be replaced by backticks below
- Long: strings.ReplaceAll(`
- Copy the source to the destination. Does not transfer files that are
- identical on source and destination, testing by size and modification
- time or MD5SUM. Doesn't delete files from the destination. If you
- want to also delete files from destination, to make it match source,
- use the [sync](/commands/rclone_sync/) command instead.
- Note that it is always the contents of the directory that is synced,
- not the directory itself. So when source:path is a directory, it's the
- contents of source:path that are copied, not the directory name and
- contents.
- To copy single files, use the [copyto](/commands/rclone_copyto/)
- command instead.
- If dest:path doesn't exist, it is created and the source:path contents
- go there.
- For example
- rclone copy source:sourcepath dest:destpath
- Let's say there are two files in sourcepath
- sourcepath/one.txt
- sourcepath/two.txt
- This copies them to
- destpath/one.txt
- destpath/two.txt
- Not to
- destpath/sourcepath/one.txt
- destpath/sourcepath/two.txt
- If you are familiar with |rsync|, rclone always works as if you had
- written a trailing |/| - meaning "copy the contents of this directory".
- This applies to all commands and whether you are talking about the
- source or destination.
- See the [--no-traverse](/docs/#no-traverse) option for controlling
- whether rclone lists the destination directory or not. Supplying this
- option when copying a small number of files into a large destination
- can speed transfers up greatly.
- For example, if you have many files in /path/to/src but only a few of
- them change every day, you can copy all the files which have changed
- recently very efficiently like this:
- rclone copy --max-age 24h --no-traverse /path/to/src remote:
- Rclone will sync the modification times of files and directories if
- the backend supports it. If metadata syncing is required then use the
- |--metadata| flag.
- Note that the modification time and metadata for the root directory
- will **not** be synced. See https://github.com/rclone/rclone/issues/7652
- for more info.
- **Note**: Use the |-P|/|--progress| flag to view real-time transfer statistics.
- **Note**: Use the |--dry-run| or the |--interactive|/|-i| flag to test without copying anything.
- `, "|", "`"),
- Annotations: map[string]string{
- "groups": "Copy,Filter,Listing,Important",
- },
- Run: func(command *cobra.Command, args []string) {
- cmd.CheckArgs(2, 2, command, args)
- fsrc, srcFileName, fdst := cmd.NewFsSrcFileDst(args)
- cmd.Run(true, true, command, func() error {
- if srcFileName == "" {
- return sync.CopyDir(context.Background(), fdst, fsrc, createEmptySrcDirs)
- }
- return operations.CopyFile(context.Background(), fdst, fsrc, srcFileName, srcFileName)
- })
- },
- }
|