1

Note: I'm new to working with Linux but I've briefly researched the rsync command and I'm pretty sure it's what I'll be using. Unfortunately, there's a lot of different options to this commands and I'm a bit confused on how to use it for my specific situation (outlined below).

Situation: I have two directory's, one with a base set of files that have been downloaded from a repo (I don't want to modify these) and other with a working copy of the same repo. What I'm looking for is a command that compares my working copy of the repo to the static repo to see if there's any changed between the two. If there is a change, only the changed files will be moved to another directory (specifically for backups). The other constraint is that I want to keep the directory structure of the working copy (see example below).

Example:

Static Repo:

/src
    code1.java
    code2.java
/tests
    test1.java

Working Repo:

/src
    code1.java
    code2.java (modified)
/tests
    test1.java
    test2.java (added)

Backups Directory:

/src
    code2.java
/tests
    test2.java

Originally, the Static Repo and Working Repo would be the same and the Backups Directory would be empty. Once I make changes to the Working Repo, I could run the command I'm looking for and the Backups Directory would be populated appropriately (with only the new/modified files/directories).

Does such a command exist?

4
  • 2
    is there some reason you don't want to use git? if your original is a git clone, your 'working' would be a local branch. no extra directories or tools needed.
    – quixotic
    Jan 25, 2017 at 0:07
  • The team I just started working with is currently using SVN (which I'm also new too). Is git still an option in this case, without affecting any of the team's preexisting revision control setup? Jan 25, 2017 at 0:42
  • ah. well you could certainly git-ify your local copy of the svn repo, but that might be confusing if you're new to version control. they take different approaches to some concepts. probably better to get comfortable with svn first. (note you should always be able to grab a fresh copy of the "static repo" from the svn server should you need one, but svn itself should be able to tell you exactly what changes you've made in "working repo".)
    – quixotic
    Jan 25, 2017 at 6:31
  • Agreed with @quixotic about using source control, but I'd skip SVN and start using Git. It's 2017, you want to be able to work with github.com and the like. Even the Git tutorials are probably much more recent than SVN tutorials.
    – Arjan
    Jan 26, 2017 at 16:23

2 Answers 2

2

I am not sure what problem you're trying to solve but I believe git probably could be a solution for it. But let's assume that the only acceptable option is some kind of backup script.

What I would use is find command to search for all files in working_repo newer than file in static_repo with latest modification time.

So I would start with finding latest file in static repo and then use something like:

find <working_repo> -type f -newer <latest_file_in_static_repo> -exec rsync {} <backup_dir>/{} \;

options of find:

  • -newer <f> Find files that were modified more recently than file <f>.
  • -exec <command> execute <command> on each found file, where {} is replaced by currently processed file name.
  • -type f Find only files (skip directories, symbolic links, sockets etc).

Note: I did not check command above, so it might have some errors or typos but in general it shows the idea.

1
  • Thanks, there is a slight issue with your suggested command but (as you said) it led me to figure out how to properly do what I wanted. What you suggested doesn't properly copy the entire directory structure of the modified files. I found a solution using cp here: unix.stackexchange.com/questions/83593/… Jan 25, 2017 at 18:15
1

A sane backup keeps history. And to able to read it on any system, I'd aim for something like:

20170125-230000
  /src
      code1.java (version 1)
      code2.java (version 1)
  /tests
      test1.java (version 1)

20170126-000000
  /src
      code1.java (version 1) hardlink to 20170125-230000
      code2.java (version 2)
  /tests
      test1.java (version 1) hardlink to 20170125-230000 
      test2.java (version 1)

20170126-010000
  /src
      code1.java (version 1) hardlink to 20170125-230000
      code2.java (version 2) hardlink to 20170126-000000
      code3.java (version 1)
  /tests
      test1.java (version 2)
      test3.java (version 1)

To preserve disk space, rsync can use --link-dest to create hard links for files (or maybe even folders) that have not changed. Of course, that also implies that if some sector on the backup disk goes bad, all history of some unchanged file might be lost (say code1.java (version 1) above, which effectively is only stored on disk once, while it is in all backup folders). So: always rotate the backup disks.

See Time Machine on Ubuntu? for an implementation, and to read the warnings about understanding hard linked folders. But you probably want to use something like rsnapshot.

(And indeed, the answer to your real problem is Git. But even then you need to make backups. Always create backups. Always.)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .