130

I'm doing a data transfer, the old file system relies deeply on a directory which now is on different path. This is a git directory which stores code online. I have no rights to move it or rename it.

So what I can do is rsync this directory to the same old path. But the directory name also changed.

Is there a easy way that I can rsync a directory to a target directory with a different name?

Zen
  • 7,537

4 Answers4

205

If you want to use rsync to recursively make the dest directory an exact copy of the src directory:

rsync -a src/ dest

The rsync man page explains how this works:

A trailing slash on the source [...] avoid[s] creating an additional directory level at the destination. You can think of a trailing / on a source as meaning "copy the contents of this directory" as opposed to "copy the directory by name" [...]

Adrian
  • 2,526
  • 1
  • 11
  • 10
  • 8
    This will create an src directory under dest directory – Zen Jan 08 '15 at 09:23
  • 28
    @Zen, not in any version of rsync I've ever used. If that's actually happening to you, you're missing the trailing slash at the end of the source directory argument. – Adrian Jan 08 '15 at 09:45
  • 30
    That sneaky trailing slash is KEY... – tutuca Mar 12 '18 at 03:46
  • unfortunately this does not seem to work if dest is a symlnk to src, it instead ends up copying src to src/src. Tested on macOS. Was hoping that I could replace bar -> foo/ with bar/, but had to use an intermediate temporary directory. – user5359531 May 02 '18 at 03:25
  • 1
    @user5359531 If you know that dest is a symlink to src, simply rm dest before running the above command. rsync is smart enough to create dest before copying the contents of src. You don't need an intermediate temp dir. – Adrian May 02 '18 at 16:26
  • If you are using rsync for Windows from Cygwin then -a wouldn't work correctly. -a implies a few options including -pgo. It changes target folder's permission and you can't use it. Use command icacls dest /T /Q /C /RESET to reset persmissions. My command is looking as the following rsync -rlt src/ dest. – Maxim Suslov May 28 '18 at 00:13
  • I've solved this problem at least 15 times in my life ... it's just not intuitive enough to be remembered well. – nisc Jun 12 '21 at 16:03
  • Note that the directory dest doesn't have to exist already for this to work. – Flimm Jun 07 '22 at 15:03
19

Quick Start

Run:

rsync -av --exclude='path1/in/source' --exclude='path2/in/source' [source]/ [destination]

Notes

  • -avr will create a new directory named [destination].
  • source and source/ create different results:
    • source — copy the folder source into destination.
    • source/ — copy the contents of source into destination.
  • To exclude many files:
    • --exclude-from=FILEFILE is the name of a file containing other files or directories to exclude.
  • --exclude may also contain wildcards:
    • e.g. --exclude=*/.svn*

Modified from: https://stackoverflow.com/a/2194500/749232


Example

Starting folder structure:

.
├── destination
└── source
    ├── fileToCopy.rtf
    └── fileToExclude.rtf

Run:

rsync -av --exclude='fileToCopy.rtf' source/ destination

Ending folder structure:

.
├── destination
│   └── fileToExclude.rtf
└── source
    ├── fileToCopy.rtf
    └── fileToExclude.rtf
Jack
  • 291
  • What are path1 and path2?  Why do you believe that --exclude is relevant to this question? … … … … … … … … … … … … … … … … … Please do not respond in comments; [edit] your answer to make it clearer and more complete. – Scott - Слава Україні Aug 20 '20 at 23:52
  • in case someone needs stats and progress follow this. https://askubuntu.com/a/908022/123217 – ssi-anik Mar 02 '24 at 15:13
2

If the old and new filesystems are both accessible to your machine, then consider using a symbolic link instead of rsync. If your rsync command you're using does not specify hosts (or if they are the same host), then this is the case. You're trying to mirror two directories with a different name on the same host. Don't use rsync for this, since you are duplicating the data, and you will have to run your rsync often to keep them in sync.

Using a symbolic link is a one-time fix that will mirror two directories (with different names) and requires almost no space. It's like creating an alias directory that points to another directory.

Let's say you had the old git in a directory called /old/path/old_git and now the code repository has moved to /new/path/new_git

You can do:

cd /old/path
rm -rf old_git     (if you still have it there, get rid of it, or move it out of the way)  
ln -s /new/path/new_git old_git

This will create a link as such:

/old/path/old_git -> /new/path/new_git

So that anything that is put into new_git will be instantly available the old way as well, without duplicating data, and without having to constantly sync them.

jrel
  • 237
  • 2
  • 6
  • 1
    Be careful with the rm -rf old_git command. This will remove your entire old_git repository. If I'm not understanding your problem right, this could be a bad thing. – jrel Jan 08 '15 at 14:23
1

I find an alternative solution now.

Using rysnc -r /origin/* /target/ can sync all the contents from origin directory to target directory.

Zen
  • 7,537
  • 14
    I believe this doesn't include dot (.foo) files because these will not be matched with the asterisk – Ray Burgemeestre Aug 31 '16 at 09:27
  • 2
    that relies on shell glob expansion, technically it will pass every file found there as an argument to rsync. it is almost the same as running rsync -r $(find /origin -maxdepth 1 -type f) /target/. As @RayBurgemeestre pointed out, shell glob expansion won't include dot files. – Florian Castellane Apr 09 '19 at 04:39