duplicity 3.2.2__tar.gz → 4.0.0.dev6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (229) hide show
  1. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/CHANGELOG.md +131 -16
  2. duplicity-4.0.0.dev6/PKG-INFO +140 -0
  3. duplicity-4.0.0.dev6/README/README-ARCH.md +134 -0
  4. duplicity-4.0.0.dev6/README/README-INSTALL.md +273 -0
  5. duplicity-4.0.0.dev6/README/README-LOG.md +92 -0
  6. duplicity-4.0.0.dev6/README/README-RELEASE.md +72 -0
  7. duplicity-4.0.0.dev6/README/README-REPO.md +92 -0
  8. duplicity-4.0.0.dev6/README/README-SNAP.md +92 -0
  9. duplicity-4.0.0.dev6/README/README-TESTING-CALL.md +224 -0
  10. duplicity-4.0.0.dev6/README/README-TESTING.md +111 -0
  11. duplicity-4.0.0.dev6/README.md +86 -0
  12. duplicity-4.0.0.dev6/duplicity.egg-info/PKG-INFO +140 -0
  13. duplicity-4.0.0.dev6/duplicity.egg-info/SOURCES.txt +152 -0
  14. duplicity-4.0.0.dev6/duplicity.egg-info/entry_points.txt +2 -0
  15. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/duplicity.egg-info/requires.txt +1 -1
  16. duplicity-4.0.0.dev6/duplicity.egg-info/top_level.txt +1 -0
  17. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/man/duplicity.1 +165 -118
  18. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/duplicity.pot +352 -356
  19. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/pyproject.toml +31 -46
  20. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/requirements.txt +1 -1
  21. duplicity-4.0.0.dev6/setup.py +532 -0
  22. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/__init__.py +2 -2
  23. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/__main__.py +21 -11
  24. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/_librsync_ctypes.py +34 -6
  25. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/_librsyncmodule.c +67 -21
  26. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/argparse311.py +27 -8
  27. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/backend.py +318 -53
  28. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/backend_pool.py +326 -37
  29. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/backends/__init__.py +1 -1
  30. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/backends/_testbackend.py +122 -20
  31. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/backends/adbackend.py +62 -19
  32. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/backends/azurebackend.py +115 -17
  33. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/backends/b2backend.py +76 -17
  34. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/backends/boxbackend.py +79 -24
  35. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/backends/dpbxbackend.py +113 -15
  36. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/backends/gdocsbackend.py +79 -32
  37. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/backends/gdrivebackend.py +58 -9
  38. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/backends/giobackend.py +104 -17
  39. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/backends/hsibackend.py +32 -6
  40. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/backends/idrivedbackend.py +111 -14
  41. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/backends/imapbackend.py +121 -50
  42. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/backends/jottacloudbackend.py +57 -15
  43. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/backends/lftpbackend.py +108 -34
  44. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/backends/localbackend.py +12 -12
  45. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/backends/mediafirebackend.py +44 -12
  46. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/backends/megabackend.py +62 -17
  47. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/backends/megav2backend.py +57 -21
  48. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/backends/megav3backend.py +64 -24
  49. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/backends/multibackend.py +53 -10
  50. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/backends/ncftpbackend.py +52 -13
  51. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/backends/onedrivebackend.py +107 -11
  52. duplicity-4.0.0.dev6/src/backends/par2backend.py +862 -0
  53. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/backends/pcabackend.py +73 -12
  54. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/backends/pydrivebackend.py +70 -12
  55. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/backends/rclonebackend.py +38 -12
  56. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/backends/rsyncbackend.py +88 -13
  57. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/backends/s3_boto3_backend.py +193 -35
  58. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/backends/slatebackend.py +34 -8
  59. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/backends/ssh_paramiko_backend.py +73 -21
  60. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/backends/ssh_pexpect_backend.py +133 -36
  61. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/backends/swiftbackend.py +60 -13
  62. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/backends/sxbackend.py +28 -6
  63. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/backends/tahoebackend.py +48 -6
  64. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/backends/webdavbackend.py +216 -51
  65. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/backends/xorrisobackend.py +111 -26
  66. duplicity-4.0.0.dev6/src/backup.py +957 -0
  67. duplicity-4.0.0.dev6/src/cleanup.py +209 -0
  68. duplicity-4.0.0.dev6/src/cli_data.py +1002 -0
  69. duplicity-4.0.0.dev6/src/cli_main.py +749 -0
  70. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/cli_util.py +434 -81
  71. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/config.py +28 -123
  72. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/diffdir.py +541 -106
  73. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/dup_collections.py +913 -201
  74. duplicity-4.0.0.dev6/src/dup_main.py +479 -0
  75. duplicity-4.0.0.dev6/src/dup_tarfile.py +203 -0
  76. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/dup_temp.py +141 -25
  77. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/dup_time.py +46 -19
  78. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/errors.py +2 -11
  79. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/file_naming.py +398 -54
  80. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/globmatch.py +14 -2
  81. duplicity-4.0.0.dev6/src/gpg.py +103 -0
  82. duplicity-4.0.0.dev6/src/gpgme/__init__.py +61 -0
  83. duplicity-4.0.0.dev6/src/gpgme/context.py +267 -0
  84. duplicity-4.0.0.dev6/src/gpgme/errors.py +76 -0
  85. duplicity-4.0.0.dev6/src/gpgme/file.py +515 -0
  86. duplicity-4.0.0.dev6/src/gpgme/keyring.py +312 -0
  87. duplicity-4.0.0.dev6/src/gpgme/profile.py +205 -0
  88. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/librsync.py +57 -44
  89. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/log.py +288 -91
  90. duplicity-4.0.0.dev6/src/manifest.py +1080 -0
  91. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/patchdir.py +412 -65
  92. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/path.py +660 -60
  93. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/progress.py +127 -18
  94. duplicity-4.0.0.dev6/src/restart.py +180 -0
  95. duplicity-4.0.0.dev6/src/restore.py +1098 -0
  96. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/robust.py +24 -9
  97. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/selection.py +334 -101
  98. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/statistics.py +141 -60
  99. duplicity-4.0.0.dev6/src/sync.py +310 -0
  100. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/tempdir.py +12 -14
  101. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/util.py +71 -15
  102. duplicity-3.2.2/PKG-INFO +0 -101
  103. duplicity-3.2.2/README-ARCH.md +0 -62
  104. duplicity-3.2.2/README-INSTALL.md +0 -158
  105. duplicity-3.2.2/README-LOG.md +0 -33
  106. duplicity-3.2.2/README-RELEASE.md +0 -66
  107. duplicity-3.2.2/README-REPO.md +0 -24
  108. duplicity-3.2.2/README-SNAP.md +0 -90
  109. duplicity-3.2.2/README-TESTING.md +0 -37
  110. duplicity-3.2.2/README.md +0 -47
  111. duplicity-3.2.2/duplicity/backends/_cf_cloudfiles.py +0 -130
  112. duplicity-3.2.2/duplicity/backends/_cf_pyrax.py +0 -154
  113. duplicity-3.2.2/duplicity/backends/cfbackend.py +0 -33
  114. duplicity-3.2.2/duplicity/backends/hubicbackend.py +0 -83
  115. duplicity-3.2.2/duplicity/backends/par2backend.py +0 -287
  116. duplicity-3.2.2/duplicity/backends/pyrax_identity/__init__.py +0 -24
  117. duplicity-3.2.2/duplicity/backends/pyrax_identity/hubic.py +0 -296
  118. duplicity-3.2.2/duplicity/cli_data.py +0 -1229
  119. duplicity-3.2.2/duplicity/cli_main.py +0 -466
  120. duplicity-3.2.2/duplicity/dup_main.py +0 -1882
  121. duplicity-3.2.2/duplicity/dup_tarfile.py +0 -35
  122. duplicity-3.2.2/duplicity/gpg.py +0 -628
  123. duplicity-3.2.2/duplicity/gpginterface.py +0 -706
  124. duplicity-3.2.2/duplicity/lazy.py +0 -499
  125. duplicity-3.2.2/duplicity/manifest.py +0 -589
  126. duplicity-3.2.2/duplicity.egg-info/PKG-INFO +0 -101
  127. duplicity-3.2.2/duplicity.egg-info/SOURCES.txt +0 -194
  128. duplicity-3.2.2/duplicity.egg-info/entry_points.txt +0 -2
  129. duplicity-3.2.2/duplicity.egg-info/top_level.txt +0 -1
  130. duplicity-3.2.2/po/af_ZA/af_ZA.po +0 -1662
  131. duplicity-3.2.2/po/ar_SA/ar_SA.po +0 -1697
  132. duplicity-3.2.2/po/ca_ES/ca_ES.po +0 -1662
  133. duplicity-3.2.2/po/cs_CZ/cs_CZ.po +0 -1689
  134. duplicity-3.2.2/po/da_DK/da_DK.po +0 -1694
  135. duplicity-3.2.2/po/de_AT/de_AT.po +0 -1694
  136. duplicity-3.2.2/po/de_DE/de_DE.po +0 -1694
  137. duplicity-3.2.2/po/el_GR/el_GR.po +0 -1687
  138. duplicity-3.2.2/po/en_AU/en_AU.po +0 -1662
  139. duplicity-3.2.2/po/en_GB/en_GB.po +0 -1669
  140. duplicity-3.2.2/po/en_PR/en_PR.po +0 -1662
  141. duplicity-3.2.2/po/en_US/en_US.po +0 -1662
  142. duplicity-3.2.2/po/es_EM/es_EM.po +0 -1694
  143. duplicity-3.2.2/po/es_ES/es_ES.po +0 -1694
  144. duplicity-3.2.2/po/es_MX/es_MX.po +0 -1694
  145. duplicity-3.2.2/po/es_PR/es_PR.po +0 -1694
  146. duplicity-3.2.2/po/es_US/es_US.po +0 -1694
  147. duplicity-3.2.2/po/fi_FI/fi_FI.po +0 -1694
  148. duplicity-3.2.2/po/fr_FR/fr_FR.po +0 -1694
  149. duplicity-3.2.2/po/he_IL/he_IL.po +0 -1664
  150. duplicity-3.2.2/po/hu_HU/hu_HU.po +0 -1679
  151. duplicity-3.2.2/po/it_IT/it_IT.po +0 -1694
  152. duplicity-3.2.2/po/ja_JP/ja_JP.po +0 -1677
  153. duplicity-3.2.2/po/ka_GE/ka_GE.po +0 -1662
  154. duplicity-3.2.2/po/ko_KR/ko_KR.po +0 -1660
  155. duplicity-3.2.2/po/nl_BE/nl_BE.po +0 -1694
  156. duplicity-3.2.2/po/nl_NL/nl_NL.po +0 -1694
  157. duplicity-3.2.2/po/nl_SR/nl_SR.po +0 -1694
  158. duplicity-3.2.2/po/no_NO/no_NO.po +0 -1687
  159. duplicity-3.2.2/po/pl_PL/pl_PL.po +0 -1697
  160. duplicity-3.2.2/po/pt_BR/pt_BR.po +0 -1693
  161. duplicity-3.2.2/po/pt_PT/pt_PT.po +0 -1692
  162. duplicity-3.2.2/po/ro_RO/ro_RO.po +0 -1695
  163. duplicity-3.2.2/po/ru_BY/ru_BY.po +0 -1697
  164. duplicity-3.2.2/po/ru_MD/ru_MD.po +0 -1697
  165. duplicity-3.2.2/po/ru_RU/ru_RU.po +0 -1697
  166. duplicity-3.2.2/po/ru_UA/ru_UA.po +0 -1696
  167. duplicity-3.2.2/po/sr_SP/sr_SP.po +0 -1664
  168. duplicity-3.2.2/po/sv_SE/sv_SE.po +0 -1694
  169. duplicity-3.2.2/po/tr_TR/tr_TR.po +0 -1662
  170. duplicity-3.2.2/po/uk_UA/uk_UA.po +0 -1683
  171. duplicity-3.2.2/po/vi_VN/vi_VN.po +0 -1660
  172. duplicity-3.2.2/po/zh_CN/zh_CN.po +0 -1689
  173. duplicity-3.2.2/po/zh_HK/zh_HK.po +0 -1660
  174. duplicity-3.2.2/po/zh_MO/zh_MO.po +0 -1660
  175. duplicity-3.2.2/po/zh_SG/zh_SG.po +0 -1689
  176. duplicity-3.2.2/po/zh_TW/zh_TW.po +0 -1660
  177. duplicity-3.2.2/setup.py +0 -200
  178. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/AUTHORS.md +0 -0
  179. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/COPYING +0 -0
  180. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/duplicity.egg-info/dependency_links.txt +0 -0
  181. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/af_ZA.po +0 -0
  182. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/ar_SA.po +0 -0
  183. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/ca_ES.po +0 -0
  184. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/cs_CZ.po +0 -0
  185. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/da_DK.po +0 -0
  186. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/de_AT.po +0 -0
  187. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/de_DE.po +0 -0
  188. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/el_GR.po +0 -0
  189. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/en_AU.po +0 -0
  190. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/en_GB.po +0 -0
  191. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/en_PR.po +0 -0
  192. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/en_US.po +0 -0
  193. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/es_EM.po +0 -0
  194. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/es_ES.po +0 -0
  195. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/es_MX.po +0 -0
  196. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/es_PR.po +0 -0
  197. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/es_US.po +0 -0
  198. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/fi_FI.po +0 -0
  199. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/fr_FR.po +0 -0
  200. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/he_IL.po +0 -0
  201. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/hu_HU.po +0 -0
  202. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/it_IT.po +0 -0
  203. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/ja_JP.po +0 -0
  204. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/ka_GE.po +0 -0
  205. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/ko_KR.po +0 -0
  206. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/nl_BE.po +0 -0
  207. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/nl_NL.po +0 -0
  208. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/nl_SR.po +0 -0
  209. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/no_NO.po +0 -0
  210. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/pl_PL.po +0 -0
  211. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/pt_BR.po +0 -0
  212. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/pt_PT.po +0 -0
  213. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/ro_RO.po +0 -0
  214. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/ru_BY.po +0 -0
  215. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/ru_MD.po +0 -0
  216. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/ru_RU.po +0 -0
  217. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/ru_UA.po +0 -0
  218. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/sr_SP.po +0 -0
  219. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/sv_SE.po +0 -0
  220. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/tr_TR.po +0 -0
  221. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/uk_UA.po +0 -0
  222. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/vi_VN.po +0 -0
  223. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/zh_CN.po +0 -0
  224. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/zh_HK.po +0 -0
  225. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/zh_MO.po +0 -0
  226. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/zh_SG.po +0 -0
  227. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/po/zh_TW.po +0 -0
  228. {duplicity-3.2.2 → duplicity-4.0.0.dev6}/setup.cfg +0 -0
  229. {duplicity-3.2.2/duplicity → duplicity-4.0.0.dev6/src}/cached_ops.py +0 -0
@@ -1,8 +1,138 @@
1
1
 
2
- (Unreleased) / 2026-10-14
2
+ (Unreleased) / 2026-11-10
3
3
  =========================
4
4
 
5
+ * [`6560ed00`](https://gitlab.com/duplicity/duplicity/-/commit/6560ed00):fix: fix verify and compare notice messages in restore.py
5
6
 
7
+ rel.4.0.0.dev5 / 2026-11-09
8
+ ===========================
9
+
10
+ * [`e40e119b`](https://gitlab.com/duplicity/duplicity/-/commit/e40e119b):new: add colorized help output and convert boolean CLI flags
11
+
12
+ rel.4.0.0.dev4 / 2026-11-09
13
+ ===========================
14
+
15
+ * [`6b72705e`](https://gitlab.com/duplicity/duplicity/-/commit/6b72705e):chg: rename compare alias and fix notice message, enable pylint checks
16
+ * [`28817b3e`](https://gitlab.com/duplicity/duplicity/-/commit/28817b3e):chg: remove unused imports, dead classes, and unreferenced functions
17
+
18
+ rel.4.0.0.dev3 / 2026-11-08
19
+ ===========================
20
+
21
+ * [`68a98c71`](https://gitlab.com/duplicity/duplicity/-/commit/68a98c71):new: add --gpghome CLI option and improve GnuPG home processing
22
+ * [`b51fea66`](https://gitlab.com/duplicity/duplicity/-/commit/b51fea66):new: compress local cache metadata files and improve sync/collection handling
23
+ * [`03c26356`](https://gitlab.com/duplicity/duplicity/-/commit/03c26356):new: add 'compare' action to compare backed-up files with current local copies
24
+ * [`196924fb`](https://gitlab.com/duplicity/duplicity/-/commit/196924fb):fix: swap verify and compare operational scope
25
+ * [`493ca237`](https://gitlab.com/duplicity/duplicity/-/commit/493ca237):fix: remove force_print from startup parameters log message
26
+ * [`72eb6f14`](https://gitlab.com/duplicity/duplicity/-/commit/72eb6f14):fix: refine backend pool shutdown, gpgme file closing, and test GNUPGHOME setup
27
+ * [`4fa4837b`](https://gitlab.com/duplicity/duplicity/-/commit/4fa4837b):fix: check whether encryption/sign keys require passwords and simplify passphrase handling
28
+ * [`c66d71d5`](https://gitlab.com/duplicity/duplicity/-/commit/c66d71d5):fix: Resolve backend pool cleanup race condition
29
+ * [`f0182755`](https://gitlab.com/duplicity/duplicity/-/commit/f0182755):fix: always log startup parameters.
30
+ * [`03bb64d5`](https://gitlab.com/duplicity/duplicity/-/commit/03bb64d5):fix: accurately report ElapsedTime across full backup duration
31
+ * [`42015644`](https://gitlab.com/duplicity/duplicity/-/commit/42015644):fix: ensure backend pool worker processes terminate on shutdown and exit.
32
+ * [`3e6c3943`](https://gitlab.com/duplicity/duplicity/-/commit/3e6c3943):fix: add 'make wheels' capability
33
+ * [`735cfca9`](https://gitlab.com/duplicity/duplicity/-/commit/735cfca9):fix: some fixes to tools/makechangelog
34
+ * [`036715dd`](https://gitlab.com/duplicity/duplicity/-/commit/036715dd):fix: add repository root to sys.path in src/__main__.py for direct execution
35
+ * [`16a17a00`](https://gitlab.com/duplicity/duplicity/-/commit/16a17a00):fix: handle read-only filename attributes on signature file objects
36
+ * [`b0345f45`](https://gitlab.com/duplicity/duplicity/-/commit/b0345f45):fix: handle multi-volume signature parts in get_combined_path_iter
37
+ * [`635aa869`](https://gitlab.com/duplicity/duplicity/-/commit/635aa869):fix: use tempdir path directly in check_resources and add unit tests
38
+
39
+ rel.4.0.0.dev2 / 2026-11-02
40
+ ===========================
41
+
42
+ * [`d3506eda`](https://gitlab.com/duplicity/duplicity/-/commit/d3506eda):new: implement concurrent volume prefetcher for restore and verify
43
+ * [`679831f7`](https://gitlab.com/duplicity/duplicity/-/commit/679831f7):new: Add a comprehensive benchmark tool for 3.x to 4.x comparison
44
+ * [`ddf54b4c`](https://gitlab.com/duplicity/duplicity/-/commit/ddf54b4c):chg: isolate backend CLI options, URL formats, and config
45
+ * [`1512150c`](https://gitlab.com/duplicity/duplicity/-/commit/1512150c):chg: simplify CLI argument definitions with direct add_argument calls
46
+ * [`cabdc68b`](https://gitlab.com/duplicity/duplicity/-/commit/cabdc68b):chg: Run test-template on push events only
47
+ * [`c5c4f555`](https://gitlab.com/duplicity/duplicity/-/commit/c5c4f555):chg: Build wheels with apt's python3-gpg, not PyPI's gpg.
48
+ * [`9a2d27e4`](https://gitlab.com/duplicity/duplicity/-/commit/9a2d27e4):chg: Port issue #926 zlib-ng compression acceleration to duplicity4
49
+ * [`4ac3086d`](https://gitlab.com/duplicity/duplicity/-/commit/4ac3086d):chg: Remove redundant log message after backup completion in `dup_main.py` to streamline output.
50
+ * [`a6704d39`](https://gitlab.com/duplicity/duplicity/-/commit/a6704d39):chg: Add explicit logging error codes to improve error tracing; update tests and dependencies to align with changes
51
+ * [`04cb9144`](https://gitlab.com/duplicity/duplicity/-/commit/04cb9144):chg: Add GPGME detection and enhanced GPG recompilation logic; refactor setup to improve maintainability and error handling.
52
+ * [`ccb50af3`](https://gitlab.com/duplicity/duplicity/-/commit/ccb50af3):chg: Add sparse file support for efficient backup and restore with --sparse and --no-sparse options, functional tests, and documentation updates.
53
+ * [`4837111c`](https://gitlab.com/duplicity/duplicity/-/commit/4837111c):chg: Refactor backend file handling to use context managers, improve error management, and add unit tests for code review fixes.
54
+ * [`4887508b`](https://gitlab.com/duplicity/duplicity/-/commit/4887508b):chg: Port latest fixes and pylint check enhancements from dev to duplicity4
55
+ * [`2686dcb6`](https://gitlab.com/duplicity/duplicity/-/commit/2686dcb6):chg: Port backend missing file handling and backup set deletion improvements from dev
56
+ * [`40851660`](https://gitlab.com/duplicity/duplicity/-/commit/40851660):chg: Add support for preserving and restoring hard links during backup operations, including --hardlinks and --no-hardlinks options, tests, and documentation updates.
57
+ * [`a16fed38`](https://gitlab.com/duplicity/duplicity/-/commit/a16fed38):chg: Update project name in Sphinx configuration to "duplicity4"
58
+ * [`e9908e97`](https://gitlab.com/duplicity/duplicity/-/commit/e9908e97):chg: Enable real-time progress reporting during concurrent backend operations using shared memory counter
59
+ * [`06c38f07`](https://gitlab.com/duplicity/duplicity/-/commit/06c38f07):chg: Centralize progress reporting logic and simplify backend-specific implementations
60
+ * [`587eb3a8`](https://gitlab.com/duplicity/duplicity/-/commit/587eb3a8):chg: Update macOS deployment target and improve GitLab CI rules for wheel builds
61
+ * [`5c368d26`](https://gitlab.com/duplicity/duplicity/-/commit/5c368d26):chg: Enhance help footer to clarify usage of main and command-specific help
62
+ * [`5f6fd4cb`](https://gitlab.com/duplicity/duplicity/-/commit/5f6fd4cb):chg: Remove obsolete --help-<command> options in favor of 'duplicity command -h' help
63
+ * [`62fe605b`](https://gitlab.com/duplicity/duplicity/-/commit/62fe605b):chg: Restrict help output to options valid for each command
64
+ * [`3912fd11`](https://gitlab.com/duplicity/duplicity/-/commit/3912fd11):chg: Move `pytest` and `gpgsm-locking` plans to `plans_done` folder
65
+ * [`76fb450c`](https://gitlab.com/duplicity/duplicity/-/commit/76fb450c):chg: Update codebase docstrings and sphinx configuration for 100% doc coverage
66
+ * [`60bfeb34`](https://gitlab.com/duplicity/duplicity/-/commit/60bfeb34):chg: remove optimization check and replace asserts with explicit error handling
67
+ * [`8e5018fe`](https://gitlab.com/duplicity/duplicity/-/commit/8e5018fe):chg: Break out restore, cleanup, restart, and sync logic from dup_main.py into dedicated modules
68
+ * [`58f0840b`](https://gitlab.com/duplicity/duplicity/-/commit/58f0840b):chg: Break out full and inc backup logic from dup_main.py into backup.py
69
+ * [`95ff6ab2`](https://gitlab.com/duplicity/duplicity/-/commit/95ff6ab2):chg: Add `_FDWrapper` for safer file descriptor handling in GPG operations
70
+ * [`e60db0e3`](https://gitlab.com/duplicity/duplicity/-/commit/e60db0e3):chg: Improve Par2 backend robustness and introduce enhanced testing
71
+ * [`c824ba98`](https://gitlab.com/duplicity/duplicity/-/commit/c824ba98):fix: accelerate backup/restore pipeline and enforce full backup on legacy repos
72
+ * [`84d9df65`](https://gitlab.com/duplicity/duplicity/-/commit/84d9df65):fix: Avoid mutating global tempfile.tempdir to prevent AF_UNIX socket length errors
73
+ * [`88617c9b`](https://gitlab.com/duplicity/duplicity/-/commit/88617c9b):fix: Speed up frontend tarfile build
74
+ * [`71c7e0c2`](https://gitlab.com/duplicity/duplicity/-/commit/71c7e0c2):fix: Speed up by moving encryption and compression into the backend pool tasks
75
+ * [`c08d8906`](https://gitlab.com/duplicity/duplicity/-/commit/c08d8906):fix: Default to 3.2.2 for now.
76
+ * [`76b30bf2`](https://gitlab.com/duplicity/duplicity/-/commit/76b30bf2):fix: Fix perms on tools/benchmark*.py
77
+ * [`af0c0f24`](https://gitlab.com/duplicity/duplicity/-/commit/af0c0f24):fix: Dynamic MACOSX_DEPLOYMENT_TARGET for cibuildwheel macOS builds
78
+ * [`3ef55348`](https://gitlab.com/duplicity/duplicity/-/commit/3ef55348):fix: Fix CI configuration and cibuildwheel setup for wheels-* jobs
79
+ * [`588bad93`](https://gitlab.com/duplicity/duplicity/-/commit/588bad93):fix: Add `include_deferred` option to `filter_restore_path_iter` for improved restore and verify behavior
80
+ * [`8f9d00d0`](https://gitlab.com/duplicity/duplicity/-/commit/8f9d00d0):fix: Deprecate `--path-to-restore`; add warnings and alternatives for restore operations
81
+ * [`00b47437`](https://gitlab.com/duplicity/duplicity/-/commit/00b47437):fix: Add robust hardlink handling and data verification logic; implement comprehensive unit and functional tests.
82
+ * [`f8443a22`](https://gitlab.com/duplicity/duplicity/-/commit/f8443a22):fix: Add detailed tracking for `NewFileSize` in sparse and hardlinked file stats; enhance unit and functional tests for verification
83
+ * [`380eab54`](https://gitlab.com/duplicity/duplicity/-/commit/380eab54):fix: Add statistics for sparse and hardlinked files in dry-run and live backups; implement unit and functional tests for consistency verification.
84
+ * [`879ae803`](https://gitlab.com/duplicity/duplicity/-/commit/879ae803):fix: Add support for `--path-to-restore` in `verify` action; enhance selective file and directory verification handling.
85
+ * [`eb691a53`](https://gitlab.com/duplicity/duplicity/-/commit/eb691a53):fix: Prevent buffered stream desync during sparse reads on Python 3.14+
86
+ * [`1c9901a3`](https://gitlab.com/duplicity/duplicity/-/commit/1c9901a3):fix: Optimize restore and deep verify for efficiency; implement sequential restore, signature-based verification, and stream-based delta patching with bounded resource usage.
87
+ * [`56ee5f79`](https://gitlab.com/duplicity/duplicity/-/commit/56ee5f79):fix: Move completed plan files to correct directory structure (`plans/done`); add `fix-verify-excessive-disk-space.md`
88
+ * [`7539adae`](https://gitlab.com/duplicity/duplicity/-/commit/7539adae):fix: Improve disk space efficiency in `verify`; add sequential volume verification and explicit resource cleanup
89
+
90
+ rel.4.0.0.dev1 / 2026-10-05
91
+ ===========================
92
+
93
+ * [`24d9b668`](https://gitlab.com/duplicity/duplicity/-/commit/24d9b668):new: Extend Par2 backend with transactional support and aggregate recovery file handling
94
+ * [`c652bbaf`](https://gitlab.com/duplicity/duplicity/-/commit/c652bbaf):chg: Add logging configuration options and improve logging integration
95
+ * [`77cdf36f`](https://gitlab.com/duplicity/duplicity/-/commit/77cdf36f):chg: Remove `_legacy_transfer` from Par2 backend and simplify upload/move logic
96
+ * [`fc0f36e0`](https://gitlab.com/duplicity/duplicity/-/commit/fc0f36e0):chg: Add `put_validated` method with retry logic and refactor upload validation
97
+ * [`a3ccdbf9`](https://gitlab.com/duplicity/duplicity/-/commit/a3ccdbf9):chg: Remove `get_data_files` from `setup.py` and simplify extension build logic
98
+ * [`06098dd1`](https://gitlab.com/duplicity/duplicity/-/commit/06098dd1):chg: Remove `src/lazy.py` and associated tests to simplify the codebase
99
+ * [`28f252e8`](https://gitlab.com/duplicity/duplicity/-/commit/28f252e8):chg: Add Python 3.15 support across the project
100
+ * [`ad59a65d`](https://gitlab.com/duplicity/duplicity/-/commit/ad59a65d):chg: Clarify `flynt` usage for Python 3.10 compatibility and adjust string concatenation in `manifest.py`
101
+ * [`4d596288`](https://gitlab.com/duplicity/duplicity/-/commit/4d596288):chg: Refactor manifest handling to adopt JSON Lines format for improved structure and extensibility
102
+ * [`12309c12`](https://gitlab.com/duplicity/duplicity/-/commit/12309c12):chg: Update `CHANGELOG.md` with new release entries and modify `makechangelog` to ignore its own changes.
103
+ * [`041c451a`](https://gitlab.com/duplicity/duplicity/-/commit/041c451a):chg: Simplify Makefile test command and update coverage settings
104
+
105
+ rel.4.0.0.dev0 / 2026-09-23
106
+ ===========================
107
+
108
+ * [`57eb00be`](https://gitlab.com/duplicity/duplicity/-/commit/57eb00be):chg: Add support for split signature and manifest volumes with atomic completion records
109
+ * [`e1df4b06`](https://gitlab.com/duplicity/duplicity/-/commit/e1df4b06):chg: Move remaining plans to 'plans_done' and resolve outdated references
110
+ * [`0466fea6`](https://gitlab.com/duplicity/duplicity/-/commit/0466fea6):chg: Remove legacy Pyrax and CloudFiles backends
111
+ * [`ded09476`](https://gitlab.com/duplicity/duplicity/-/commit/ded09476):chg: Restored "NOTICE" log level and updated verbosity handling
112
+ * [`3b327d9f`](https://gitlab.com/duplicity/duplicity/-/commit/3b327d9f):chg: Improve string formatting and update pylint job configuration
113
+ * [`d71e71a6`](https://gitlab.com/duplicity/duplicity/-/commit/d71e71a6):chg: Add `swig` to CI dependencies in `.gitlab-ci.yml`
114
+ * [`77fa2670`](https://gitlab.com/duplicity/duplicity/-/commit/77fa2670):chg: Remove legacy `gpginterface.py` and associated tests
115
+ * [`9cf4557a`](https://gitlab.com/duplicity/duplicity/-/commit/9cf4557a):chg: Remove redundant parentheses from class declarations
116
+ * [`5c7b8ad0`](https://gitlab.com/duplicity/duplicity/-/commit/5c7b8ad0):chg: Remove redundant `object` inheritance across classes for Python 3
117
+ * [`30264c15`](https://gitlab.com/duplicity/duplicity/-/commit/30264c15):chg: Standardize logging levels and refactor verbosity handling
118
+ * [`e28a3c87`](https://gitlab.com/duplicity/duplicity/-/commit/e28a3c87):chg: Replace `duplicity` references with `src` across codebase
119
+
120
+ rel.3.2.3.dev2 / 2026-11-05
121
+ ===========================
122
+
123
+ * [`4cf4e13c`](https://gitlab.com/duplicity/duplicity/-/commit/4cf4e13c):chg: Move wheels build from CI to local.
124
+ * [`87cc7510`](https://gitlab.com/duplicity/duplicity/-/commit/87cc7510):fix: Fix check resources() in dup_main.py
125
+ * [`28f1a91b`](https://gitlab.com/duplicity/duplicity/-/commit/28f1a91b):fix: giobackend retries do not attempt to remount remote_file
126
+
127
+ rel.3.2.3.dev1 / 2026-10-21
128
+ ===========================
129
+
130
+ * [`2617372a`](https://gitlab.com/duplicity/duplicity/-/commit/2617372a):chg: Add archive verification and improve file handling
131
+
132
+ rel.3.2.3.dev0 / 2026-10-14
133
+ ===========================
134
+
135
+ * [`042cd4a9`](https://gitlab.com/duplicity/duplicity/-/commit/042cd4a9):chg: Set version to 3.2.3.dev0 for LP.
6
136
 
7
137
  rel.3.2.2 / 2026-10-14
8
138
  ======================
@@ -122,21 +252,6 @@ rel.3.2.0 / 2026-08-10
122
252
  * [`c823ed36`](https://gitlab.com/duplicity/duplicity/-/commit/c823ed36):fix: Could not release lockfile
123
253
  * [`3d9eab94`](https://gitlab.com/duplicity/duplicity/-/commit/3d9eab94):fix: Comprehensive fix for backup, restart, and cleanup logic.
124
254
 
125
- rel.4.0.0.dev0 / 2026-09-23
126
- ===========================
127
-
128
- * [`8427bb00`](https://gitlab.com/duplicity/duplicity/-/commit/8427bb00):chg: Add support for split signature and manifest volumes with atomic completion records
129
- * [`2b0c76e7`](https://gitlab.com/duplicity/duplicity/-/commit/2b0c76e7):chg: Move remaining plans to 'plans_done' and resolve outdated references
130
- * [`1d07db2f`](https://gitlab.com/duplicity/duplicity/-/commit/1d07db2f):chg: Remove legacy Pyrax and CloudFiles backends
131
- * [`b04ca97b`](https://gitlab.com/duplicity/duplicity/-/commit/b04ca97b):chg: Restored "NOTICE" log level and updated verbosity handling
132
- * [`f9b6ed8d`](https://gitlab.com/duplicity/duplicity/-/commit/f9b6ed8d):chg: Improve string formatting and update pylint job configuration
133
- * [`5437ccf2`](https://gitlab.com/duplicity/duplicity/-/commit/5437ccf2):chg: Add `swig` to CI dependencies in `.gitlab-ci.yml`
134
- * [`50e0e15f`](https://gitlab.com/duplicity/duplicity/-/commit/50e0e15f):chg: Remove legacy `gpginterface.py` and associated tests
135
- * [`c5e53820`](https://gitlab.com/duplicity/duplicity/-/commit/c5e53820):chg: Remove redundant parentheses from class declarations
136
- * [`f2fa175e`](https://gitlab.com/duplicity/duplicity/-/commit/f2fa175e):chg: Remove redundant `object` inheritance across classes for Python 3
137
- * [`74f7d3a9`](https://gitlab.com/duplicity/duplicity/-/commit/74f7d3a9):chg: Standardize logging levels and refactor verbosity handling
138
- * [`d090ab43`](https://gitlab.com/duplicity/duplicity/-/commit/d090ab43):chg: Replace `duplicity` references with `src` across codebase
139
-
140
255
  rel.3.2.1.dev3 / 2026-09-23
141
256
  ===========================
142
257
 
@@ -0,0 +1,140 @@
1
+ Metadata-Version: 2.4
2
+ Name: duplicity
3
+ Version: 4.0.0.dev6
4
+ Summary: Encrypted backup using rsync algorithm
5
+ Author-email: Kenneth Loafman <kenneth@loafman.com>
6
+ Maintainer: Edgar Soldin, Thomas Laubrock
7
+ Project-URL: Homepage, http://duplicity.us
8
+ Project-URL: Download, https://gitlab.com/AlphaPrime/duplicity4/-/releases
9
+ Project-URL: Issues, https://gitlab.com/AlphaPrime/duplicity4/-/issues
10
+ Project-URL: Contact, https://lists.nongnu.org/mailman/listinfo/duplicity-talk
11
+ Project-URL: Documentation, http://duplicity.us
12
+ Project-URL: Repository, https://gitlab.com/AlphaPrime/duplicity4.git
13
+ Project-URL: Changelog, https://gitlab.com/AlphaPrime/duplicity4/-/blob/duplicity4/CHANGELOG.md
14
+ Classifier: Development Status :: 6 - Mature
15
+ Classifier: Environment :: Console
16
+ Classifier: Operating System :: MacOS
17
+ Classifier: Operating System :: POSIX
18
+ Classifier: Programming Language :: C
19
+ Classifier: Programming Language :: Python :: 3
20
+ Classifier: Programming Language :: Python :: 3.10
21
+ Classifier: Programming Language :: Python :: 3.11
22
+ Classifier: Programming Language :: Python :: 3.12
23
+ Classifier: Programming Language :: Python :: 3.13
24
+ Classifier: Programming Language :: Python :: 3.14
25
+ Classifier: Programming Language :: Python :: 3.15
26
+ Classifier: Topic :: System :: Archiving :: Backup
27
+ Requires-Python: <3.16,>=3.10
28
+ Description-Content-Type: text/markdown
29
+ License-File: COPYING
30
+ License-File: AUTHORS.md
31
+ Requires-Dist: fasteners>=0.19
32
+ Requires-Dist: httplib2
33
+ Requires-Dist: pysocks
34
+ Requires-Dist: requests
35
+ Requires-Dist: requests-oauthlib
36
+ Requires-Dist: zlib_ng>=1.0.0
37
+ Requires-Dist: azure-storage-blob
38
+ Requires-Dist: b2sdk
39
+ Requires-Dist: boto3
40
+ Requires-Dist: botocore
41
+ Requires-Dist: boxsdk[jwt]
42
+ Requires-Dist: dropbox
43
+ Requires-Dist: gdata-python3
44
+ Requires-Dist: google-api-python-client
45
+ Requires-Dist: google-auth-oauthlib
46
+ Requires-Dist: jottalib
47
+ Requires-Dist: mediafire
48
+ Requires-Dist: megatools
49
+ Requires-Dist: paramiko
50
+ Requires-Dist: pexpect
51
+ Requires-Dist: pydrive2
52
+ Requires-Dist: python-swiftclient
53
+ Dynamic: license-file
54
+
55
+ # Duplicity 4
56
+
57
+ Duplicity 4 (`duplicity4`) backs directories by producing encrypted, tar-format volumes and uploading them to a remote or local storage backend. By using librsync and the rsync algorithm, Duplicity generates bandwidth- and space-efficient incremental archives that only record binary deltas of changed files. Archives are encrypted and signed using GnuPG (via GPGME) to ensure privacy, integrity, and authenticity.
58
+
59
+ ## Key Features
60
+
61
+ - **Concurrent Backend Worker Pool**: Multi-worker asynchronous volume compression, encryption, and upload pipeline (`src/backend_pool.py`) for significantly faster backups.
62
+ - **Concurrent Restore Prefetching**: Asynchronous volume prefetching for restore and verification operations.
63
+ - **Hardware-Accelerated Compression**: High-throughput compression using `zlib-ng`.
64
+ - **Advanced File Handling**: Native sparse file detection and efficient chunking (`--sparse`) alongside preserved hardlink reconstruction (`--hardlinks`).
65
+ - **Encrypted & Signed Backups**: Uses GnuPG via GPGME to encrypt and sign archives with standard OpenPGP or CMS (X.509) keys.
66
+ - **Bandwidth & Space Efficient**: Employs librsync to compute binary deltas for changed files in incremental backups.
67
+ - **Standard Archive Format**: Volumes are standard POSIX `tar` format archives encrypted with OpenPGP/CMS.
68
+ - **Extensive Storage Backend Support**: Backups can be stored locally or uploaded to cloud and remote services (SSH/SFTP, rsync, Amazon S3, Backblaze B2, Google Cloud Storage, Microsoft Azure Blob, Google Drive, Microsoft OneDrive, Dropbox, WebDAV, Swift, Mega, and more).
69
+ - **Restartable Transfers**: Asynchronous volume generation and transfer resume support for reliable operation over interrupted connections.
70
+ - **Standardized Logging**: Python standard logging integration with named severity levels (`error`, `warning`, `notice`, `info`, `debug`, `critical`) and machine-readable output options.
71
+
72
+ ## Quick Start Examples
73
+
74
+ ### 1. Perform a Backup
75
+ ```shell
76
+ # Backup local directory to a remote SFTP destination
77
+ duplicity /home/user/data pex+sftp://user@example.com/backup
78
+
79
+ # Force a full backup
80
+ duplicity full /home/user/data pex+sftp://user@example.com/backup
81
+ ```
82
+
83
+ ### 2. Restore Files
84
+ ```shell
85
+ # Restore the entire latest backup to a destination folder
86
+ duplicity restore pex+sftp://user@example.com/backup /home/user/restore
87
+
88
+ # Restore a specific file from 3 days ago
89
+ duplicity restore --file-to-restore document.txt --time 3D pex+sftp://user@example.com/backup /home/user/document.txt
90
+ ```
91
+
92
+ ### 3. Verify and Compare Backup Integrity
93
+ ```shell
94
+ # Compare remote backup contents against the local filesystem
95
+ duplicity compare pex+sftp://user@example.com/backup /home/user/data
96
+
97
+ # Verify remote backup volume checksums and integrity
98
+ duplicity verify pex+sftp://user@example.com/backup /home/user/data
99
+ ```
100
+
101
+ ### 4. Check Backup Status and List Files
102
+ ```shell
103
+ # Show collection status (backup sets and volume chains)
104
+ duplicity collection-status pex+sftp://user@example.com/backup
105
+
106
+ # List all files currently contained in the backup archive
107
+ duplicity list-current-files pex+sftp://user@example.com/backup
108
+ ```
109
+
110
+ ## System Requirements
111
+
112
+ - **Python**: Python >= 3.10 (tested through Python 3.15).
113
+ - **C Libraries**: `librsync` (>= 0.9.7, 2.x recommended), `libgpgme` (GPGME C library), `zlib-ng`.
114
+ - **GnuPG**: `gpg` (2.x), `gpgsm`, and `python3-gpg` (GPGME Python bindings).
115
+ - **Build Tools**: C compiler (`gcc` or `clang`), `make`, `python3-dev`, `swig`, `pkg-config`.
116
+
117
+ ## Documentation & Guides
118
+
119
+ Comprehensive guides for users, packagers, and developers are organized in the `README/` directory and documentation:
120
+
121
+ - [Installation Guide](README/README-INSTALL.md) — Comprehensive installation instructions (pipx, apt, pip venv, source).
122
+ - [Architecture & Design](README/README-ARCH.md) — Internal design, volume formats, signature chains, and encryption workflow.
123
+ - [Repository & Development Guide](README/README-REPO.md) — Source tree setup, building C extensions, and running from source.
124
+ - [Testing Guide](README/README-TESTING.md) — Running tests with Docker, pytest, parallel workers, and test isolation guidelines.
125
+ - [Call for Testing](README/README-TESTING-CALL.md) — Call for testing Duplicity 4.0 pre-releases, focus areas, and feedback channels.
126
+ - [Logging Subsystem & Protocol](README/README-LOG.md) — Named log levels, command-line flags, and machine-readable output protocol.
127
+ - [Release Process](README/README-RELEASE.md) — Release checklists, versioning guidelines, Launchpad PPAs, snaps, and PyPI packaging.
128
+ - [Snap Packaging](README/README-SNAP.md) — Building and testing multi-architecture Snap packages.
129
+ - [Sphinx Documentation Guide](docs/README.md) — Building HTML documentation locally and ReadTheDocs configuration.
130
+ - [Backend Development Guide](src/backends/README.md) — Guide to implementing and testing new storage backends.
131
+ - [Test Keyring Reference](testing/gnupg/README.md) — Test GnuPG keys, fingerprints, and passphrases.
132
+
133
+ ## Help & Community
134
+
135
+ - **Official Website**: <https://duplicity.us>
136
+ - **Project Repository**: <https://gitlab.com/AlphaPrime/duplicity4.git>
137
+ - **Issue Tracker**: <https://gitlab.com/AlphaPrime/duplicity4/-/issues>
138
+ - **Online Documentation**: <https://duplicity4.readthedocs.io/>
139
+ - **Mailing List**: <https://lists.nongnu.org/mailman/listinfo/duplicity-talk>
140
+ - **Translation Portal**: <https://crowdin.com/project/duplicity>
@@ -0,0 +1,134 @@
1
+ # Duplicity 4 Architecture and Design
2
+
3
+ This document details the architectural layout, core subsystems, data formats, and execution flows of Duplicity 4 (`duplicity4`).
4
+
5
+ ## System Component Diagram
6
+
7
+ ```mermaid
8
+ graph TD
9
+ subgraph Interface
10
+ Main["__main__.py (Entry Point)"]
11
+ end
12
+
13
+ subgraph Orchestration
14
+ DupMain["dup_main.py (Orchestration)"]
15
+ end
16
+
17
+ subgraph Support_Config ["Support & Config"]
18
+ CLI["cli_main.py (Argument Parsing)"]
19
+ Config["config.py (Global Settings)"]
20
+ LogUtil["log.py / util.py (Logging/Support)"]
21
+ end
22
+
23
+ subgraph Core_Logic ["Core Logic"]
24
+ Selection["selection.py (File Selection)"]
25
+ Backend["backend.py (Storage Layer)"]
26
+ Errors["errors.py (Exception Mgmt)"]
27
+ end
28
+
29
+ subgraph Operation
30
+ DiffDir["diffdir.py (Backup Logic)"]
31
+ Backends["backends/ (Storage Drivers)"]
32
+ PatchDir["patchdir.py (Restore Logic)"]
33
+ end
34
+
35
+ subgraph Engines_Metadata ["Engines & Metadata"]
36
+ LibRsync["librsync.py (rsync delta)"]
37
+ GPGME["gpgme/ (GPGME Crypto Engine)"]
38
+ ZlibNG["zlib-ng (Compression Engine)"]
39
+ Manifest["manifest.py (Metadata)"]
40
+ end
41
+
42
+ Main --> DupMain
43
+ DupMain --> CLI
44
+ DupMain --> Config
45
+ DupMain --> LogUtil
46
+
47
+ CLI --> Selection
48
+ Config --> Backend
49
+ LogUtil ~~~ Errors
50
+ Errors -.-> LogUtil
51
+
52
+ Selection --> DiffDir
53
+ Backend --> Backends
54
+
55
+ DiffDir --> Backends
56
+ PatchDir --> Backends
57
+
58
+ DiffDir --> LibRsync
59
+ DiffDir --> GPGME
60
+ DiffDir --> ZlibNG
61
+ DiffDir --> Manifest
62
+
63
+ PatchDir --> LibRsync
64
+ PatchDir --> GPGME
65
+ PatchDir --> ZlibNG
66
+ PatchDir --> Manifest
67
+
68
+ Backends --> GPGME
69
+ Backends --> ZlibNG
70
+ ```
71
+
72
+ ## Architectural Overview
73
+
74
+ Duplicity operates on a pipelined, streaming architecture that turns a filesystem directory into encrypted, compressed, multi-volume remote backup sets.
75
+
76
+ ### 1. Interface & Orchestration Layer
77
+ - **`src/__main__.py`**: Top-level entry point when running from source or binary packages.
78
+ - **`src/cli_main.py`**: Command-line interface parser and validator based on standard Python `argparse`. Translates CLI arguments into application configuration.
79
+ - **`src/dup_main.py`**: Top-level workflow coordinator. Dispatches commands (`backup`, `restore`, `verify`, `collection-status`, `list-current-files`, `cleanup`, `remove-older-than`, etc.).
80
+
81
+ ### 2. Core Processing Engines
82
+ - **Selection Engine (`src/selection.py`)**: Traverses source directories and evaluates file inclusion/exclusion rules based on globbing, regular expressions, file lists, or size/time criteria.
83
+ - **Delta Engine (`src/librsync.py`, `src/_librsyncmodule.c`)**: Interfaces with the C `librsync` library. Computes rolling checksums (signatures) of existing files and binary differences (deltas) against previous versions.
84
+ - **Archive Generator (`src/diffdir.py`)**: Bundles file deltas or full file contents into POSIX standard tar archives (`difftar`). Uses `zlib-ng` for high-throughput hardware-accelerated compression.
85
+ - **Archive Restorer (`src/patchdir.py`)**: Reconstructs directory trees by streaming full archives and applying successive incremental deltas in chronological order.
86
+ - **Manifest Engine (`src/manifest.py`)**: Records file listings, SHA1/SHA256 checksums, and volume block allocations for each backup set.
87
+
88
+ ### 3. Cryptography Subsystem (`src/gpgme/`)
89
+ Duplicity uses GPGME (GnuPG Made Easy) bindings via `python3-gpg` (`src/gpgme/`):
90
+ - **`src/gpgme/context.py`**: Manages `gpg.Context` lifecycles, protocol selection (OpenPGP vs. CMS/X.509), loopback pinentry, and passphrase callbacks.
91
+ - **`src/gpgme/file.py`**: Provides asynchronous streaming encryption, decryption, signing, and verification wrapper streams (`GPGFile`).
92
+ - **`src/gpgme/keyring.py`**: Interrogates GnuPG keyrings for key existence, fingerprints, and validation.
93
+ - **`src/gpgme/profile.py`**: Encapsulates encryption parameters, recipient keys, signing keys, and passphrases.
94
+
95
+ ### 4. Storage Backend Layer (`src/backend.py` & `src/backends/`)
96
+ - **`src/backend.py` (`BackendWrapper`)**: Provides a uniform interface for all operations (`put`, `get`, `list`, `delete`, `query_info`, `move`) with automatic retry logic, network backoff, and volume validation.
97
+ - **`src/backends/`**: Modular storage drivers implementing target-specific protocols and cloud APIs (SFTP, S3, B2, Azure, Google Drive, OneDrive, WebDAV, rsync, Swift, etc.).
98
+
99
+ ## Archive Volume Structure and Naming Conventions
100
+
101
+ Backup sets consist of several file types uploaded to the storage backend:
102
+
103
+ | File Type | Pattern | Description |
104
+ |-----------|---------|-------------|
105
+ | **Full Volume** | `duplicity-full.<time>.vol<n>.difftar[.gpg]` | POSIX tar archive containing full snapshot data of volume `n`. |
106
+ | **Incremental Volume** | `duplicity-inc.<start_time>.to.<end_time>.vol<n>.difftar[.gpg]` | POSIX tar archive containing binary librsync deltas for changed files. |
107
+ | **Full Signatures** | `duplicity-full-signatures.<time>[.vol<n>].sigtar[.gpg]` | Signatures (librsync checksum blocks) for all files in the full backup. |
108
+ | **Incremental Signatures** | `duplicity-new-signatures.<start_time>.to.<end_time>[.vol<n>].sigtar[.gpg]` | Signatures for new/modified files in the incremental backup. |
109
+ | **Manifest** | `duplicity-(full\|inc).<time>.manifest[.gpg]` | Metadata listing all archived files, volumes, and file checksums. |
110
+ | **Completion Record** | `duplicity-(full\|inc).<time>.manifest.complete[.gpg]` | Atomic commit record specifying complete manifest and signature part sets. |
111
+ | **Statistics** | `duplicity-(full\|inc).<time>.jsonstat[.gz\|.gpg]` | Machine-readable JSON backup statistics and transfer metrics. |
112
+
113
+ - `<time>` format: ISO 8601 UTC timestamp string, formatted as `YYYYMMDDTHHMMSSZ`.
114
+ - Extensions: Volumes are unencrypted (e.g. `.difftar`) or encrypted with GnuPG (`.difftar.gpg` or `.difftar.p7m`), depending on encryption settings.
115
+
116
+ ## Data Flow
117
+
118
+ ### Full Backup
119
+ 1. **Cataloging & Signatures**: Duplicity scans the source tree via `selection.py`.
120
+ 2. **Tar Volume Generation**: Files are packed into `difftar` streams up to `--volsize` (default: 200MB).
121
+ 3. **Encryption & Signing**: Volume streams pass through `GPGFile` for encryption/signing.
122
+ 4. **Upload**: Volumes are transferred to the backend and validated for size/hash integrity.
123
+ 5. **Signatures & Manifest**: A signature archive (`sigtar`) and manifest are generated, encrypted, and uploaded.
124
+
125
+ ### Incremental Backup
126
+ 1. **Signature Retrieval**: Duplicity downloads the signature file (`sigtar`) from the most recent backup.
127
+ 2. **Delta Computation**: The source tree is scanned; files that have changed are compared against cached signatures to generate librsync deltas.
128
+ 3. **Volume Generation & Upload**: Incremental `difftar` volumes containing only deltas and new files are encrypted and uploaded.
129
+ 4. **Signature & Manifest Update**: New signature chains and manifests are uploaded.
130
+
131
+ ### Restore
132
+ 1. **Collection Status**: Remote backend is scanned to locate the full backup and necessary incremental chain covering the requested target time.
133
+ 2. **Manifest Verification**: The manifest is read to determine which volumes contain the required file(s).
134
+ 3. **Stream Reconstruction**: Full `difftar` volumes are streamed and unpacked, followed by sequential delta application from each incremental volume until the target state is restored.