git-ftp 2.0.0.dev0__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 (100) hide show
  1. git_ftp-2.0.0.dev0/.gitignore +17 -0
  2. git_ftp-2.0.0.dev0/CHANGELOG.md +18 -0
  3. git_ftp-2.0.0.dev0/COMPATIBILITY.md +122 -0
  4. git_ftp-2.0.0.dev0/LICENSE +674 -0
  5. git_ftp-2.0.0.dev0/Makefile +49 -0
  6. git_ftp-2.0.0.dev0/PKG-INFO +243 -0
  7. git_ftp-2.0.0.dev0/README.md +208 -0
  8. git_ftp-2.0.0.dev0/docs/git-ftp.1.md +364 -0
  9. git_ftp-2.0.0.dev0/pyproject.toml +155 -0
  10. git_ftp-2.0.0.dev0/src/gitftp/__init__.py +5 -0
  11. git_ftp-2.0.0.dev0/src/gitftp/__main__.py +7 -0
  12. git_ftp-2.0.0.dev0/src/gitftp/_version.py +24 -0
  13. git_ftp-2.0.0.dev0/src/gitftp/auth.py +209 -0
  14. git_ftp-2.0.0.dev0/src/gitftp/changeset.py +86 -0
  15. git_ftp-2.0.0.dev0/src/gitftp/cli/__init__.py +111 -0
  16. git_ftp-2.0.0.dev0/src/gitftp/cli/cmd_add_scope.py +23 -0
  17. git_ftp-2.0.0.dev0/src/gitftp/cli/cmd_catchup.py +19 -0
  18. git_ftp-2.0.0.dev0/src/gitftp/cli/cmd_download.py +19 -0
  19. git_ftp-2.0.0.dev0/src/gitftp/cli/cmd_help.py +30 -0
  20. git_ftp-2.0.0.dev0/src/gitftp/cli/cmd_init.py +19 -0
  21. git_ftp-2.0.0.dev0/src/gitftp/cli/cmd_log.py +31 -0
  22. git_ftp-2.0.0.dev0/src/gitftp/cli/cmd_pull.py +19 -0
  23. git_ftp-2.0.0.dev0/src/gitftp/cli/cmd_push.py +21 -0
  24. git_ftp-2.0.0.dev0/src/gitftp/cli/cmd_remove_scope.py +23 -0
  25. git_ftp-2.0.0.dev0/src/gitftp/cli/cmd_show.py +31 -0
  26. git_ftp-2.0.0.dev0/src/gitftp/cli/cmd_snapshot.py +20 -0
  27. git_ftp-2.0.0.dev0/src/gitftp/cli/cmd_unlock.py +19 -0
  28. git_ftp-2.0.0.dev0/src/gitftp/cli/cmd_version.py +19 -0
  29. git_ftp-2.0.0.dev0/src/gitftp/cli/group.py +68 -0
  30. git_ftp-2.0.0.dev0/src/gitftp/cli/options.py +208 -0
  31. git_ftp-2.0.0.dev0/src/gitftp/config.py +170 -0
  32. git_ftp-2.0.0.dev0/src/gitftp/deploy.py +341 -0
  33. git_ftp-2.0.0.dev0/src/gitftp/errors.py +86 -0
  34. git_ftp-2.0.0.dev0/src/gitftp/gitrepo.py +293 -0
  35. git_ftp-2.0.0.dev0/src/gitftp/hooks.py +30 -0
  36. git_ftp-2.0.0.dev0/src/gitftp/ignore.py +83 -0
  37. git_ftp-2.0.0.dev0/src/gitftp/include.py +94 -0
  38. git_ftp-2.0.0.dev0/src/gitftp/lock.py +94 -0
  39. git_ftp-2.0.0.dev0/src/gitftp/mirror.py +413 -0
  40. git_ftp-2.0.0.dev0/src/gitftp/options.py +72 -0
  41. git_ftp-2.0.0.dev0/src/gitftp/output.py +132 -0
  42. git_ftp-2.0.0.dev0/src/gitftp/session.py +212 -0
  43. git_ftp-2.0.0.dev0/src/gitftp/transfer.py +269 -0
  44. git_ftp-2.0.0.dev0/src/gitftp/transport/__init__.py +1 -0
  45. git_ftp-2.0.0.dev0/src/gitftp/transport/base.py +93 -0
  46. git_ftp-2.0.0.dev0/src/gitftp/transport/curlftp.py +389 -0
  47. git_ftp-2.0.0.dev0/src/gitftp/transport/listing.py +155 -0
  48. git_ftp-2.0.0.dev0/src/gitftp/transport/registry.py +73 -0
  49. git_ftp-2.0.0.dev0/src/gitftp/transport/sftp.py +442 -0
  50. git_ftp-2.0.0.dev0/src/gitftp/url.py +204 -0
  51. git_ftp-2.0.0.dev0/src/gitftp/version.py +35 -0
  52. git_ftp-2.0.0.dev0/tests/__init__.py +0 -0
  53. git_ftp-2.0.0.dev0/tests/conftest.py +118 -0
  54. git_ftp-2.0.0.dev0/tests/docker/__init__.py +0 -0
  55. git_ftp-2.0.0.dev0/tests/docker/conftest.py +16 -0
  56. git_ftp-2.0.0.dev0/tests/docker/test_pure_ftpd.py +80 -0
  57. git_ftp-2.0.0.dev0/tests/fakes/__init__.py +0 -0
  58. git_ftp-2.0.0.dev0/tests/fakes/memory_transport.py +163 -0
  59. git_ftp-2.0.0.dev0/tests/helpers/__init__.py +0 -0
  60. git_ftp-2.0.0.dev0/tests/helpers/certs.py +99 -0
  61. git_ftp-2.0.0.dev0/tests/helpers/ftpserver.py +176 -0
  62. git_ftp-2.0.0.dev0/tests/helpers/gitrepo.py +118 -0
  63. git_ftp-2.0.0.dev0/tests/helpers/remote.py +50 -0
  64. git_ftp-2.0.0.dev0/tests/helpers/sftpserver.py +301 -0
  65. git_ftp-2.0.0.dev0/tests/integration/__init__.py +0 -0
  66. git_ftp-2.0.0.dev0/tests/integration/conftest.py +121 -0
  67. git_ftp-2.0.0.dev0/tests/integration/test_catchup.py +41 -0
  68. git_ftp-2.0.0.dev0/tests/integration/test_cli_basics.py +81 -0
  69. git_ftp-2.0.0.dev0/tests/integration/test_defaults_scopes.py +204 -0
  70. git_ftp-2.0.0.dev0/tests/integration/test_delete.py +36 -0
  71. git_ftp-2.0.0.dev0/tests/integration/test_download.py +141 -0
  72. git_ftp-2.0.0.dev0/tests/integration/test_entrypoint.py +93 -0
  73. git_ftp-2.0.0.dev0/tests/integration/test_filenames.py +80 -0
  74. git_ftp-2.0.0.dev0/tests/integration/test_hooks.py +110 -0
  75. git_ftp-2.0.0.dev0/tests/integration/test_ignore.py +82 -0
  76. git_ftp-2.0.0.dev0/tests/integration/test_include.py +199 -0
  77. git_ftp-2.0.0.dev0/tests/integration/test_init.py +100 -0
  78. git_ftp-2.0.0.dev0/tests/integration/test_insecure_epsv.py +69 -0
  79. git_ftp-2.0.0.dev0/tests/integration/test_lock.py +84 -0
  80. git_ftp-2.0.0.dev0/tests/integration/test_parallel.py +74 -0
  81. git_ftp-2.0.0.dev0/tests/integration/test_pull.py +136 -0
  82. git_ftp-2.0.0.dev0/tests/integration/test_push.py +324 -0
  83. git_ftp-2.0.0.dev0/tests/integration/test_sftp.py +217 -0
  84. git_ftp-2.0.0.dev0/tests/integration/test_snapshot.py +76 -0
  85. git_ftp-2.0.0.dev0/tests/integration/test_submodules.py +83 -0
  86. git_ftp-2.0.0.dev0/tests/integration/test_syncroot.py +48 -0
  87. git_ftp-2.0.0.dev0/tests/integration/test_tls.py +61 -0
  88. git_ftp-2.0.0.dev0/tests/unit/__init__.py +0 -0
  89. git_ftp-2.0.0.dev0/tests/unit/test_auth.py +108 -0
  90. git_ftp-2.0.0.dev0/tests/unit/test_changeset.py +79 -0
  91. git_ftp-2.0.0.dev0/tests/unit/test_cli_parsing.py +52 -0
  92. git_ftp-2.0.0.dev0/tests/unit/test_config.py +84 -0
  93. git_ftp-2.0.0.dev0/tests/unit/test_docs_sync.py +29 -0
  94. git_ftp-2.0.0.dev0/tests/unit/test_ignore.py +53 -0
  95. git_ftp-2.0.0.dev0/tests/unit/test_include.py +25 -0
  96. git_ftp-2.0.0.dev0/tests/unit/test_listing.py +64 -0
  97. git_ftp-2.0.0.dev0/tests/unit/test_lock.py +23 -0
  98. git_ftp-2.0.0.dev0/tests/unit/test_transfer_pool.py +129 -0
  99. git_ftp-2.0.0.dev0/tests/unit/test_url.py +137 -0
  100. git_ftp-2.0.0.dev0/tests/unit/test_worktree.py +29 -0
@@ -0,0 +1,17 @@
1
+ /src/gitftp/_version.py
2
+ /dist/
3
+ /build/
4
+ /out/
5
+ /.venv/
6
+ __pycache__/
7
+ *.py[cod]
8
+ *.egg-info/
9
+ .pytest_cache/
10
+ .mypy_cache/
11
+ .ruff_cache/
12
+ .coverage
13
+ .coverage.*
14
+ coverage.xml
15
+ junit.xml
16
+ htmlcov/
17
+ .git-ftp*-tmp
@@ -0,0 +1,18 @@
1
+ # Changelog
2
+
3
+ All notable changes to this project are documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
4
+
5
+ ## [2.0.0.dev0] 2026-09-13
6
+
7
+ First release: a native Python3 port of git-ftp 1.6.0. See [COMPATIBILITY.md](COMPATIBILITY.md) for what is unchanged, what was fixed and what is new.
8
+
9
+ ### Added
10
+ - `--worktree` / `git-ftp.worktree`: deploy from a temporary Git worktree so edits to the working tree during an upload are ignored.
11
+ - Parallel uploads, deletes and downloads (`--jobs`, `git-ftp.jobs`).
12
+ - Native `download`, `pull` and `snapshot` without lftp.
13
+ - `unlock` action, `--password-command`, `--key-passphrase`, `--no-post-hooks`,
14
+ `GIT_FTP_URL`/`GIT_FTP_USER`/`GIT_FTP_PASSWORD`.
15
+ - SFTP host key verification, ssh-agent support, encrypted keys.
16
+
17
+ ### Fixed
18
+ - Every upstream bug listed in COMPATIBILITY.md.
@@ -0,0 +1,122 @@
1
+ # Compatibility with git-ftp 1.6.0
2
+
3
+ This Python git-ftp is a port of the Bash [git-ftp](https://github.com/git-ftp/git-ftp),
4
+ version 1.6.0. The rule of the port is: **keep everything on the wire and in
5
+ configuration identical, fix the bugs, and write down every deviation here.**
6
+
7
+ A remote deployed with the Bash git-ftp can be picked up by this port and vice
8
+ versa. The deployed-commit file (`.git-ftp.log`), its content, the config keys,
9
+ the `.git-ftp-ignore` and `.git-ftp-include` formats, the hook names and
10
+ arguments, the exit codes and the default progress messages are unchanged.
11
+
12
+ ## Unchanged
13
+
14
+ | Area | Status |
15
+ |---|---|
16
+ | Actions `init`, `push`, `catchup`, `show`, `log`, `download`, `pull`, `snapshot`, `add-scope`, `remove-scope`, `help`, `version` | Same names, same semantics |
17
+ | Options | Every 1.6.0 option is accepted with the same spelling |
18
+ | Config keys `git-ftp.*` and `git-ftp.<scope>.*`, `.git-ftp-config` | Same keys, same precedence, an explicit empty value still overrides |
19
+ | `.git-ftp.log` (or `git-ftp.deployedsha1file`) | Same location and content (commit id plus newline) |
20
+ | `.git-ftp-ignore` | Same glob semantics: `*` crosses `/`, patterns match the whole Git path including the syncroot |
21
+ | `.git-ftp-include` | Same `!target` and `target:source` forms, same directory/missing-target rules, applied before ignore |
22
+ | Hooks `pre-ftp-push`, `post-ftp-push` | Same arguments and stdin format |
23
+ | Exit codes | 2 usage, 3 missing argument, 4 upload, 5 download, 6 unknown protocol, 7 locked, 8 git, 9 hook, 10 filesystem |
24
+ | Progress output | `N file(s) to sync:`, `[i of N] Buffered for upload '…'.`, `Uploading ...`, `Last deployment changed from … to ….`, etc. |
25
+ | `~/.netrc` fallback when no user is given | Same, now also for sftp |
26
+ | Remote lock semantics | Same file (`git-ftp.lck`), checked and written only with `--lock`, same "a lock for my own commit is mine" rule |
27
+ | Empty remote directories | Kept, as upstream since 1.1.0 (issue #168) |
28
+
29
+ ## Upstream bugs that are fixed
30
+
31
+ These are behaviours of the Bash script that are clearly unintended. Each is
32
+ fixed rather than reproduced.
33
+
34
+ - `--no-verify` and `--enable-post-errors` swallowed the argument after them.
35
+ - `--key=FILE`, `--pubkey=FILE` and `--branch=NAME` were not parsed.
36
+ - `--silent` also suppressed fatal error messages, and `-v` sent them to stdout.
37
+ Fatal errors now always go to stderr, at every verbosity.
38
+ - `--remote-root` was prepended to the URL's path although the manual says it
39
+ replaces it. It replaces it.
40
+ - `--lock` toggled: giving it twice turned locking off. It is a plain flag.
41
+ - The lock file's two lines were joined by a literal `\n`. A real newline is
42
+ written; both forms are read.
43
+ - The lock file was named after the script's own file name. The name is fixed.
44
+ - `ftp://user@host/path` took `user` for the host. Userinfo in a URL is parsed
45
+ as credentials.
46
+ - `host:2121/path` without a scheme was rejected as an unknown protocol even
47
+ though the built-in help shows that form. It is accepted as ftp.
48
+ - `add-scope` gave up on a URL whose password contained a colon or an at-sign.
49
+ - File names containing `%`, `?`, `[`, `]`, `"` or a backslash were mangled on
50
+ the way into curl. They are transferred intact. So is a file named `-`.
51
+ - `git-ftp.no-commit false` enabled the option. Booleans are parsed as Git
52
+ parses them (`true/yes/on/1` and `false/no/off/0`).
53
+ - A push whose remote log could not be read for *any* reason said
54
+ "use 'git ftp init'". That message is now reserved for a genuinely missing
55
+ log; a wrong password or an unreachable host is reported as what it is.
56
+ - The delete phase ran a directory listing of the remote root just to have a
57
+ transfer to attach `-Q` commands to. Deletes are plain `DELE` commands.
58
+ - Files whose type changed (a file becoming a symlink or vice versa, `T` in
59
+ `git diff`) were never uploaded. They are.
60
+ - Running from a subdirectory of the repository resolved `--syncroot` and the
61
+ submodule list against the wrong directory.
62
+ - `catchup` with more than one submodule only handled the first one, and
63
+ `cd`-ed deeper with every iteration.
64
+ - Passwords were visible on the curl command line (`ps`). Credentials are
65
+ passed to libcurl in memory and never appear in URLs, logs or argv.
66
+ - Temporary files were left behind on Ctrl-C. There are no temporary files.
67
+
68
+ ## New
69
+
70
+ - **Parallel transfers**: `--jobs N` / `git-ftp.jobs` (default 4, `1` is
71
+ sequential). Uploads run first, then deletes, and the commit log is written
72
+ last, only when every upload succeeded. The first failed upload stops the
73
+ deploy (exit 4); failed deletes are warnings, as upstream.
74
+ - Native `download`, `pull` and `snapshot`: no `lftp` needed. Listings use
75
+ `MLSD` with a `LIST` fallback; downloads are parallel too.
76
+ - Submodules are deployed in-process (no recursive `git-ftp` invocation).
77
+ - Environment variables `GIT_FTP_URL`, `GIT_FTP_USER`, `GIT_FTP_PASSWORD`,
78
+ read after the command line and before Git configuration.
79
+ - `--password-command` / `git-ftp.password-command`: a shell command whose
80
+ first output line is the password.
81
+ - `unlock` action to remove a stale lock left by an interrupted deploy.
82
+ - `--key-passphrase` / `git-ftp.key-passphrase`, and an interactive prompt,
83
+ for encrypted SFTP keys. Upstream cannot use an encrypted key at all.
84
+ - SFTP authentication through a running `ssh-agent` (`SSH_AUTH_SOCK`).
85
+ - `--password` as an alias of `--passwd`; `--no-post-hooks`.
86
+ - Ctrl-C stops the transfers promptly and exits with 130.
87
+ - `version -v` prints the libcurl and paramiko versions in use.
88
+ - `--worktree` / `git-ftp.worktree`: `init` and `push` read the upload from a
89
+ temporary Git worktree checked out at the deployed commit, so edits to the
90
+ working tree during the upload cannot leak in. Untracked files added by
91
+ `.git-ftp-include` are read from the live working tree, since a worktree of the
92
+ commit cannot contain them.
93
+
94
+ ## Behaviour that differs on purpose
95
+
96
+ - **SFTP host keys are verified** against `~/.ssh/known_hosts` and
97
+ `/etc/ssh/ssh_known_hosts`. Upstream accepted any host key silently. An
98
+ unknown host is refused with a pointer to `ssh-keyscan`; `--insecure` turns
99
+ verification off, as it does for TLS.
100
+ - **SFTP is spoken by paramiko**, not libcurl. FTP, FTPS and FTPES use libcurl
101
+ through pycurl.
102
+ - **`git` is required** at run time (the port shells out to it, as upstream).
103
+ - A valueless boolean key such as a bare `insecure` line in `.git-ftp-config`
104
+ reads as **true**, exactly as `git config` reads it.
105
+ - Diagnostics printed with `-v` go to stderr with a timestamp; progress lines
106
+ stay on stdout. Warnings (`WARNING: …`) go to stderr at every verbosity.
107
+ - `ftps://` and `ftpes://` require TLS 1.2 or newer and encrypt the data
108
+ connection as well as the control connection.
109
+ - `-u`, `-s` and `-k` without an argument work as upstream (local user, current
110
+ branch, default keychain item). An action name after a bare flag (`-u push`)
111
+ is recognised as the action.
112
+ - The `Insecure is 'N'.` and `Disable EPSV is '1'.` diagnostics are printed
113
+ once per repository (twice with one submodule), as upstream.
114
+ - `download --changed-only` uses the deployed commit to pick the files
115
+ (upstream ignored the flag for `download`).
116
+ - The macOS keychain is read through the `security` command on macOS and
117
+ ignored elsewhere, as upstream. Keychain entries cannot unlock SSH keys.
118
+
119
+ ## Not implemented
120
+
121
+ - `download`, `pull` and `snapshot` never print lftp's transfer log; they print
122
+ a one-line summary instead (`Downloaded N file(s), deleted M local file(s).`).