Skip to content

Commit 5939fe1

Browse files
author
n0madic
committed
Refactor git-clone CLI compatibility
Replace the previous flag contract with a git-oriented parser based on pflag and keep the compatibility logic inside the main package. Align common git clone behavior around exit codes, destination handling, branch/tag resolution, progress output, and explicit unsupported-option failures. Document the supported surface, keep non-Git extensions long-only, remove the legacy tags/<name> branch form, and add integration coverage for the new contract.
1 parent aa8727e commit 5939fe1

6 files changed

Lines changed: 1699 additions & 202 deletions

File tree

README.md

Lines changed: 94 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -1,68 +1,105 @@
1-
# git-clone
1+
# git-clone
22

3-
Summary
4-
-------
5-
Git clone standalone. Git repository downloader.
3+
`git-clone` is a standalone repository downloader built on top of `go-git`. It is intended to be a practical drop-in replacement for common `git clone` workflows without requiring a full Git installation.
64

7-
Can fetch repositories without installing Git environment!
5+
Where `go-git` supports the underlying behavior directly, the utility follows Git-compatible argument names, exit codes, destination checks, and branch or tag checkout semantics. Features that cannot be reproduced faithfully are either accepted as compatibility no-ops or rejected early with a git-like error.
86

9-
Help
10-
----
11-
```
12-
Usage:
13-
git-clone [OPTIONS] repository [directory]
14-
15-
Application Options:
16-
-i, --identity=<file> Selects a file from which the identity (private key) for public key
17-
ssh authentication is read. Or use the environment variable
18-
[$GIT_CLONE_KEY]
19-
-r, --recursive After the clone is created, initialize all submodules within, using
20-
their default settings.
21-
-p, --pull Incorporates changes from a remote repository into the current branch
22-
(if already cloned).
23-
-o, --origin=<name> Instead of using the remote name origin to keep track of the upstream
24-
repository, use <name>. (default: origin)
25-
-b, --branch=<name> Instead of pointing the newly created HEAD to the branch pointed to by
26-
the cloned repository’s HEAD, point to <name> branch instead.
27-
--single-branch Clone only the history leading to the tip of a single branch, either
28-
specified by the --branch option or the primary branch remote’s HEAD
29-
points at.
30-
-d, --depth=<depth> Create a shallow clone with a history truncated to the specified
31-
number of commits.
32-
-t, --tags=[all|no|following] Tag mode (default: all)
33-
-l, --last Print the latest commit.
34-
35-
Help Options:
36-
-h, --help Show this help message
37-
38-
Arguments:
39-
repository: The repository to clone from.
40-
directory: The name of a new directory to clone into.
41-
```
7+
## Compatibility
8+
9+
### Supported
10+
11+
- `repo [dir]`
12+
- `-v/--verbose`
13+
- `-q/--quiet`
14+
- `--progress`, `--no-progress`
15+
- `-n/--no-checkout`, `--checkout`
16+
- `--bare`, `--no-bare`
17+
- `--mirror`, `--no-mirror`
18+
- `-s/--shared`, `--no-shared`
19+
- `--recursive`, `--no-recursive`
20+
- `--recurse-submodules`, `--no-recurse-submodules`
21+
- `-o/--origin`
22+
- `-b/--branch`
23+
- `--single-branch`, `--no-single-branch`
24+
- `--depth`
25+
- `--tags`, `--no-tags`
26+
- `--shallow-submodules`, `--no-shallow-submodules`
27+
28+
### Supported As Compatibility No-Ops
29+
30+
These flags are accepted to preserve CLI compatibility, but this build does not emulate Git's transport/storage optimization behind them:
4231

43-
Usage
44-
-----
32+
- `-l/--local`, `--no-local`
33+
- `--hardlinks`, `--no-hardlinks`
4534

46-
$ ``git-clone https://github.com/n0madic/git-clone.git``
35+
### Partial Support
4736

48-
Clone to another dir:
49-
$ ``git-clone https://github.com/n0madic/git-clone.git foo``
50-
$ ``git-clone https://github.com/n0madic/git-clone.git ~/bar``
37+
- `-c/--config key=value`
38+
- applied to the local repository config after clone/pull
39+
- does not influence transport-time behavior the way vanilla Git can
40+
- `--recursive[=<pathspec>]` / `--recurse-submodules[=<pathspec>]`
41+
- supported without a pathspec
42+
- pathspec form is rejected early as unsupported
43+
- `-b/--branch`
44+
- supports both branches and tags
45+
- if a branch and tag share the same name, branch wins like vanilla Git
5146

52-
Cloning specific branch:
53-
$ ``git-clone -b develop https://github.com/n0madic/git-clone.git``
54-
Note: if the repository already cloned, it will simply switch the branch, and local changes will be discarded.
47+
### Recognized But Unsupported
5548

56-
Download a specific tag:
57-
$ ``git-clone -b tags/v0.1.0 https://github.com/n0madic/git-clone.git``
49+
These options are parsed and fail early with exit code `129` and a git-like error:
5850

59-
Pull if repository already cloned (if not then just clone):
60-
$ ``git-clone --pull https://github.com/n0madic/git-clone.git``
51+
- `--reject-shallow`, `--no-reject-shallow`
52+
- `-j/--jobs`, `--no-jobs`
53+
- `--template`
54+
- `--reference`
55+
- `--reference-if-able`
56+
- `--dissociate`
57+
- `--revision`
58+
- `-u/--upload-pack`
59+
- `--shallow-since`
60+
- `--shallow-exclude`
61+
- `--separate-git-dir`
62+
- `--ref-format`
63+
- `--server-option`
64+
- `-4/--ipv4`
65+
- `-6/--ipv6`
66+
- `--filter`
67+
- `--also-filter-submodules`
68+
- `--remote-submodules`
69+
- `--sparse`, `--no-sparse`
70+
- `--bundle-uri`
6171

62-
Use custom private key from file:
63-
$ ``git-clone --identity ~/.ssh/id_rsa.foo git@github.com:n0madic/git-clone.git``
72+
## Extensions
6473

65-
Use custom private key from environment:
66-
$ ``export GIT_CLONE_KEY=$(cat ~/.ssh/id_rsa.bar)``
67-
$ ``git-clone git@github.com:n0madic/git-clone.git``
68-
Note: --identity flag has a higher priority over the environment.
74+
These are intentionally outside vanilla `git clone`, but remain available as long-only flags so they do not collide with Git's standard short options:
75+
76+
- `--pull`
77+
- if destination already exists as a repository, pull instead of failing
78+
- plain clone behavior remains Git-compatible unless `--pull` is explicitly set
79+
- `--last`
80+
- prints the latest checked out commit after clone/pull
81+
- `--identity <file>`
82+
- uses the given SSH private key file or PEM contents
83+
- also respects `GIT_CLONE_KEY`
84+
85+
## Behavioral Notes
86+
87+
- Exit codes follow Git-style conventions:
88+
- `0` success
89+
- `128` fatal runtime/semantic failure
90+
- `129` usage, help, unknown option, unsupported option
91+
- Progress is written to `stderr`, not `stdout`.
92+
- Progress is shown automatically only when `stderr` is a terminal, unless `--progress` forces it or `--quiet` / `--no-progress` disables it.
93+
- Existing non-empty destinations now fail like vanilla `git clone`.
94+
- Existing repositories are only mutated when `--pull` is explicitly used.
95+
96+
## Examples
97+
98+
```bash
99+
git-clone https://github.com/n0madic/git-clone.git
100+
git-clone -b main https://github.com/n0madic/git-clone.git dst
101+
git-clone --no-tags --depth 1 https://github.com/n0madic/git-clone.git
102+
git-clone --recursive https://github.com/n0madic/git-clone.git
103+
git-clone --pull https://github.com/n0madic/git-clone.git
104+
git-clone --identity ~/.ssh/id_ed25519 git@github.com:n0madic/git-clone.git
105+
```

0 commit comments

Comments
 (0)