Describe the bug
Timeshift hardcodes /data/* and /DATA/* as default exclude entries in add_default_exclude_entries() (src/Core/Main.vala). When a user adds + /data/** (or any subdirectory include like + /data/git/**) through the Filters UI or timeshift.json, these user entries are appended after the default excludes in the generated exclude.list.
Because rsync processes exclude/include patterns top-to-bottom with first-match-wins semantics, the hardcoded /data/* always matches before the user's + /data/** include, silently making the include rules inert. The snapshot contains an empty data/ directory with no contents.
Steps to reproduce
- Have a filesystem with data on
/data (e.g., /dev/sda1 mounted at /data)
- In Timeshift settings, add
+ /data/** as an include filter
- Run a backup
- Inspect the snapshot's
exclude.list — note that /data/* (default) appears before + /data/** (user)
- Inspect the snapshot's
localhost/data/ — it is empty
Expected behavior
User include rules should be able to override default excludes. Either:
- User includes (
+ rules) should be placed before default excludes in the generated list, or
/data/* and /DATA/* should not be in the hardcoded defaults at all
Actual behavior
The exclude.list generated by create_exclude_list_for_backup() always places exclude_list_default entries first, then exclude_list_user entries. Since rsync uses first-match-wins, user includes placed after default excludes are dead rules that never match.
Why this matters
/data is not a standard system directory — it is a common convention for user data storage (used by many distributions and server configurations). Unlike /dev, /proc, /sys, and /tmp, which have well-defined roles in the Linux filesystem hierarchy, /data is an arbitrary user-defined mount point. Timeshift should not assume its contents should be excluded, and it certainly should not silently override user-specified include rules.
This is inherently dangerous: a user who adds + /data/** and + /data/git/*** to their filters will believe their data is being backed up. The UI does not indicate that these rules are ineffective. There is no warning in the logs. The backup completes "successfully" with an empty /data directory.
Suggested fix
Remove /data/* and /DATA/* from the hardcoded exclude_list_default. They are not system directories. If the goal is to exclude non-standard mount points, the existing FsTabEntry.read_file("/etc/fstab") loop already handles this for mounts outside the standard hierarchy — and that approach correctly respects the user's filesystem layout rather than guessing at it.
Alternatively, if removing the defaults is too disruptive, user include rules (+ prefixed entries in exclude_list_user) should be inserted before exclude_list_default in the generated exclude.list so that rsync's first-match-wins behavior allows them to take effect.
System
- Timeshift 24.01.1 (Ubuntu 24.04 noble)
- rsync mode (not btrfs)
/data on /dev/sda1 (ext4), root on /dev/sdb1 (ext4)
Related
Describe the bug
Timeshift hardcodes
/data/*and/DATA/*as default exclude entries inadd_default_exclude_entries()(src/Core/Main.vala). When a user adds+ /data/**(or any subdirectory include like+ /data/git/**) through the Filters UI ortimeshift.json, these user entries are appended after the default excludes in the generatedexclude.list.Because rsync processes exclude/include patterns top-to-bottom with first-match-wins semantics, the hardcoded
/data/*always matches before the user's+ /data/**include, silently making the include rules inert. The snapshot contains an emptydata/directory with no contents.Steps to reproduce
/data(e.g.,/dev/sda1mounted at/data)+ /data/**as an include filterexclude.list— note that/data/*(default) appears before+ /data/**(user)localhost/data/— it is emptyExpected behavior
User include rules should be able to override default excludes. Either:
+rules) should be placed before default excludes in the generated list, or/data/*and/DATA/*should not be in the hardcoded defaults at allActual behavior
The
exclude.listgenerated bycreate_exclude_list_for_backup()always placesexclude_list_defaultentries first, thenexclude_list_userentries. Since rsync uses first-match-wins, user includes placed after default excludes are dead rules that never match.Why this matters
/datais not a standard system directory — it is a common convention for user data storage (used by many distributions and server configurations). Unlike/dev,/proc,/sys, and/tmp, which have well-defined roles in the Linux filesystem hierarchy,/datais an arbitrary user-defined mount point. Timeshift should not assume its contents should be excluded, and it certainly should not silently override user-specified include rules.This is inherently dangerous: a user who adds
+ /data/**and+ /data/git/***to their filters will believe their data is being backed up. The UI does not indicate that these rules are ineffective. There is no warning in the logs. The backup completes "successfully" with an empty/datadirectory.Suggested fix
Remove
/data/*and/DATA/*from the hardcodedexclude_list_default. They are not system directories. If the goal is to exclude non-standard mount points, the existingFsTabEntry.read_file("/etc/fstab")loop already handles this for mounts outside the standard hierarchy — and that approach correctly respects the user's filesystem layout rather than guessing at it.Alternatively, if removing the defaults is too disruptive, user include rules (
+prefixed entries inexclude_list_user) should be inserted beforeexclude_list_defaultin the generatedexclude.listso that rsync's first-match-wins behavior allows them to take effect.System
/dataon/dev/sda1(ext4), root on/dev/sdb1(ext4)Related