And why are you not considering git
itself?
The strategy you describe, after one full and two incremental backups, has it's complications when you continue. It is easy to make mistakes, and it can get very inefficient, depending on the changes. There would have to be a kind of rotation, ie from time to time you make a new full backup - and then do you want to keep the old one or not?
Given a working dir "testdir" containing some project (files, and subdirs), git
makes by default a hidden .git
subdir for the data. That would be for the local, additional version control features. For backup, you can archive/copy it away to a medium or clone it via network.
The revision control you get (without asking for) is a side effect of git's differential storage.
You can leave out all the forking/branching and so on. This means you have one branch called "master".
Before you can commit (actually write to the git archive/repo), you have to configure a minimal user for the config file. Then you should first learn and test in a subdir (maybe tmpfs). Git is just as tricky as tar, sometimes.
Anyway, as a comment says: backing up is easy, hard part is the restoring.
Disadvantages of git would be just the small overhead/overkill.
Advantages are: git tracks content and file names. It only saves what is necessary, based on a diff (for text files at least).
Example
I have 3 files in a dir. After git init
, git add .
and git commit
I have a 260K .git
dir.
Then I cp -r .git /tmp/abpic.git
(a good place to save a backup:). I rm
the 154K jpg, and also change one text file. I also rm -r .git
.
]# ls
atext btext
]# git --git-dir=/tmp/abpic.git/ ls-files
atext
btext
pic154k.jpg
Before restoring the files I can get the precise differences:
]# git --git-dir=/tmp/abpic.git/ status
On branch master
Changes not staged for commit:
(use "git add/rm <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: atext
deleted: pic154k.jpg
no changes added to commit (use "git add" and/or "git commit -a")
Here I want to follow the git restore
hint.
After git --git-dir=/tmp/abpic.git/ restore \*
:
]# ls -st
total 164
4 atext 156 pic154k.jpg 4 btext
The jpeg is back, and text file btext
has not been updated (keeps timestamp). The modifications in atext
are overwritten.
To reunite the repo and the (working) dir you can just copy it back.
]# cp -r /tmp/abpic.git/ .git
]# git status
On branch master
nothing to commit, working tree clean
The files in the current dir are identical to the .git
archive (after the restore
). New changes will be displayed and can be added and committed, without any planning. You only have to store it to another medium, for backup purposes.
After a file is modified, you can use status
or diff
:
]# echo more >>btext
]# git status
On branch master
Changes not staged for commit:
(use "git add <file>..." to update what will be committed)
(use "git restore <file>..." to discard changes in working directory)
modified: btext
no changes added to commit (use "git add" and/or "git commit -a")
]# git diff
diff --git a/btext b/btext
index 96b5d76..a4a6c5b 100644
--- a/btext
+++ b/btext
@@ -1,2 +1,3 @@
This is file b
second line
+more
#]
And just like git
knows about "+more" in file 'btext', it will also only store that line incrementally.
After git add .
(or git add btext
) the status
command switches from red to green and the commit
gives you the info.
]# git add .
]# git status
On branch master
Changes to be committed:
(use "git restore --staged <file>..." to unstage)
modified: btext
]# git commit -m 'btext: more'
[master fad0453] btext: more
1 file changed, 1 insertion(+)
And you can really get at the contents, somehow:
]# git ls-tree @
100644 blob 321e55a5dc61e25fe34e7c79f388101bd1ae4bbf atext
100644 blob a4a6c5bd3359d84705e5fd01884caa8abd1736d0 btext
100644 blob 2d550ffe96aa4347e465109831ac52b7897b9f0d pic154k.jpg
And then the first 4 hex hash digits
]# git cat-file blob a4a6
This is file b
second line
more
To travel back in time by one commit it is:
]# git ls-tree @^
100644 blob 321e55a5dc61e25fe34e7c79f388101bd1ae4bbf atext
100644 blob 96b5d76c5ee3ccb7e02be421e21c4fb8b96ca2f0 btext
100644 blob 2d550ffe96aa4347e465109831ac52b7897b9f0d pic154k.jpg
]# git cat-file blob 96b5
This is file b
second line
btext's blob has a different hash before the last commit, the others have the same.
An overview would be:
]# git log
commit fad04538f7f8ddae1f630b648d1fe85c1fafa1b4 (HEAD -> master)
Author: Your Name <[email protected]>
Date: Sun Feb 16 10:51:51 2020 +0000
btext: more
commit 0bfc1837e20988f1b80f8b7070c5cdd2de346dc7
Author: Your Name <[email protected]>
Date: Sun Feb 16 08:45:16 2020 +0000
added 3 files with 'add .'
Instead of manually timestamped tar files you have commits with a message and date (and an author). Logically attached to these commits are the file lists and contents.
Simple git
is 20% more complicated than tar
, but you get decisive 50% more functionality from it.
I wanted to make OP's third change: change a file plus two new 'picture' files. I did, but now I have:
]# git log
commit deca7be7de8571a222d9fb9c0d1287e1d4d3160c (HEAD -> master)
Author: Your Name <[email protected]>
Date: Sun Feb 16 17:56:18 2020 +0000
didn't add the pics before :(
commit b0355a07476c8d8103ce937ddc372575f0fb8ebf
Author: Your Name <[email protected]>
Date: Sun Feb 16 17:54:03 2020 +0000
Two new picture files
Had to change btext...
commit fad04538f7f8ddae1f630b648d1fe85c1fafa1b4
Author: Your Name <[email protected]>
Date: Sun Feb 16 10:51:51 2020 +0000
btext: more
commit 0bfc1837e20988f1b80f8b7070c5cdd2de346dc7
Author: Your Name <[email protected]>
Date: Sun Feb 16 08:45:16 2020 +0000
added 3 files with 'add .'
]#
So what did that Your Name Guy do exactly, in his two commits, shortly before 6 pm?
The last commit's details are:
]# git show
commit deca7be7de8571a222d9fb9c0d1287e1d4d3160c (HEAD -> master)
Author: Your Name <[email protected]>
Date: Sun Feb 16 17:56:18 2020 +0000
didn't add the pics before :(
diff --git a/picture2 b/picture2
new file mode 100644
index 0000000..d00491f
--- /dev/null
+++ b/picture2
@@ -0,0 +1 @@
+1
diff --git a/picture3 b/picture3
new file mode 100644
index 0000000..0cfbf08
--- /dev/null
+++ b/picture3
@@ -0,0 +1 @@
+2
]#
And to check the second-to-last commit, whose message announces two pictures:
]# git show @^
commit b0355a07476c8d8103ce937ddc372575f0fb8ebf
Author: Your Name <[email protected]>
Date: Sun Feb 16 17:54:03 2020 +0000
Two new picture files
Had to change btext...
diff --git a/btext b/btext
index a4a6c5b..de7291e 100644
--- a/btext
+++ b/btext
@@ -1,3 +1 @@
-This is file b
-second line
-more
+Completely changed file b
]#
This happened because I tried git commit -a
to shortcut git add .
, and the two files were new (untracked). It showed in red with git status
, but as I say git is not less tricky than tar, or unix.
"Your debutante just knows what you need, but I know what you want" (or the other way round. Point is it's not always the same)
btrfs
filesystem. But before rsyncing, I create a read-only snapshot of how it was on the previous backup date. Rsync only writes the files that have changed and the previous state of them is there in the snapshot. The space consumed is very little more than would be used by incremental backups.