Repository: rclone/rclone
File: fs/operations/operations.go (Go)

Code before:
			if err == nil {
				dst = newDst
				in.ServerSideCopyEnd(dst.Size()) // account the bytes for the server-side transfer
				_ = in.Close()
				inplace = true
			} else {
				_ = in.Close()
			}
			if errors.Is(err, fs.ErrorCantCopy) {
				tr.Reset(ctx) // skip incomplete accounting - will be overwritten by the manual copy below
			}
		} else {
			err = fs.ErrorCantCopy
		}
		// If can't server-side copy, do it manually
		if errors.Is(err, fs.ErrorCantCopy) {
			// Remove partial files on premature exit
			var atexitRemovePartial atexit.FnHandle
			if !inplace {
				atexitRemovePartial = atexit.Register(func() {
					ctx := context.Background()
					removeFailedPartialCopy(ctx, f, remotePartial)
				})
			}
			if doMultiThreadCopy(ctx, f, src) {
				options := []fs.OpenOption{hashOption}
				for _, option := range ci.UploadHeaders {
					options = append(options, option)
				}
				if ci.MetadataSet != nil {
					options = append(options, fs.MetadataOption(ci.MetadataSet))
				}
				dst, err = multiThreadCopy(ctx, f, remotePartial, src, ci.MultiThreadStreams, tr, options...)
				if err == nil {
					newDst = dst
				}
				if doUpdate {
					actionTaken = "Multi-thread Copied (replaced existing)"
				} else {
					actionTaken = "Multi-thread Copied (new)"
				}
			} else {
				var in0 io.ReadCloser
				options := []fs.OpenOption{hashOption}
				for _, option := range ci.DownloadHeaders {
					options = append(options, option)
				}
				in0, err = Open(ctx, src, options...)
				if err != nil {
					err = fmt.Errorf("failed to open source object: %w", err)
				} else {

Review comment (refactor):
I think we should rename this `uploadOptions` and and move it and the following 6 lines up before the `if`, then we can re-use `uploadOptions` a bit further down when calling `Update` and `Put`.

I have on my TODO list to refactor `operations.Copy` - it is getting out of hand!

Code after:
			if err == nil {
				dst = newDst
				in.ServerSideCopyEnd(dst.Size()) // account the bytes for the server-side transfer
				_ = in.Close()
				inplace = true
			} else {
				_ = in.Close()
			}
			if errors.Is(err, fs.ErrorCantCopy) {
				tr.Reset(ctx) // skip incomplete accounting - will be overwritten by the manual copy below
			}
		} else {
			err = fs.ErrorCantCopy
		}
		// If can't server-side copy, do it manually
		if errors.Is(err, fs.ErrorCantCopy) {
			// Remove partial files on premature exit
			var atexitRemovePartial atexit.FnHandle
			if !inplace {
				atexitRemovePartial = atexit.Register(func() {
					ctx := context.Background()
					removeFailedPartialCopy(ctx, f, remotePartial)
				})
			}

			uploadOptions := []fs.OpenOption{hashOption}
			for _, option := range ci.UploadHeaders {
				uploadOptions = append(uploadOptions, option)
			}
			if ci.MetadataSet != nil {
				uploadOptions = append(uploadOptions, fs.MetadataOption(ci.MetadataSet))
			}

			if doMultiThreadCopy(ctx, f, src) {
				dst, err = multiThreadCopy(ctx, f, remotePartial, src, ci.MultiThreadStreams, tr, uploadOptions...)
				if err == nil {
					newDst = dst
				}
				if doUpdate {
					actionTaken = "Multi-thread Copied (replaced existing)"
				} else {
					actionTaken = "Multi-thread Copied (new)"
				}
			} else {
				var in0 io.ReadCloser
				options := []fs.OpenOption{hashOption}
				for _, option := range ci.DownloadHeaders {
					options = append(options, option)
				}
				in0, err = Open(ctx, src, options...)
				if err != nil {