Repository: borgbackup/borg

Issue:
"borg diff" doesn't show empty files as difference. (Unexpected behavior)
If I have 2 archives differing by empty files (but also having another difference) the "**borg diff**" wont show the empty files as difference. If the only difference are some empty files, I see no output at all.  

### Example / how to reproduce:  
Let "/home/user/bk" be Borg repository with no encryption (didn't tried with encryption).  
Create archive of the directory "/home/user/foo" with 
`borg create /home/user/bk::arc0 /home/user/foo`
Now add some empty files in "~/foo", 
`touch /home/user/foo/file1`  
Create another archive of the dir " ~/foo "  

 `borg create /home/user/bk::arc1 /home/user/foo `   

Comparing the two archives (arc0 and arh1) with:  
`borg diff /home/user/bk::arc0 arc1`  
It shows nothing.  
___
So far this way I reproduced it on CentOS 7 with Borg 1.1.4 from EPEL and on Manjaro with Borg 1.1.4 from the official repo.

The expected behaviour according to my interpretation of the documentation (Usage->borg diff->examples) is that it should show that we added one file (namely "file1"), no matter if it's the only difference or there are another differences (doesn't work in both cases). 


Discussion:
master branch:
```
$ borg init -e none repo
$ mkdir foo
$ borg create repo::a foo
$ touch foo/empty
$ borg create repo::b foo
$ borg diff repo::a b
added           0 B foo/empty
```
1.1.4:
```
$ borg init -e none repo
$ rm -rf foo
$ mkdir foo
$ borg create repo::a foo
$ touch foo/empty
$ borg create repo::b foo
$ borg diff repo::a b
```
Empty output, bug reproduced. Same for latest 1.1-maint.
The fixed master was a side effect of the refactor in #2842.


Resolving patch:
diff --git a/src/borg/archiver.py b/src/borg/archiver.py
--- a/src/borg/archiver.py
+++ b/src/borg/archiver.py
@@ -1030,6 +1030,10 @@ def compare_link(item1, item2):
                 return 'changed link'
 
         def contents_changed(item1, item2):
+            if item1.get('deleted') != item2.get('deleted'):
+                # a deleleted/non-existing file is considered different to an existing file,
+                # even if the latter is empty.
+                return True
             if can_compare_chunk_ids:
                 return item1.chunks != item2.chunks
             else:
diff --git a/src/borg/testsuite/archiver.py b/src/borg/testsuite/archiver.py
--- a/src/borg/testsuite/archiver.py
+++ b/src/borg/testsuite/archiver.py
@@ -3410,6 +3410,7 @@ def test_basic_functionality(self):
 
         # Setup files for the second snapshot
         self.create_regular_file('file_added', size=2048)
+        self.create_regular_file('file_empty_added', size=0)
         os.unlink('input/file_removed')
         os.unlink('input/file_removed2')
         os.unlink('input/file_replaced')
@@ -3484,6 +3485,9 @@ def do_asserts(output, can_compare_ids):
             if are_hardlinks_supported():
                 assert 'added       2.05 kB input/hardlink_added' in output
 
+            # check if a diff between non-existent and empty new file is found
+            assert 'added           0 B input/file_empty_added' in output
+
             # The inode has two links and both of them are deleted. They should
             # appear as two deleted files.
             assert 'removed       256 B input/file_removed' in output


Test patch: