[PATCH v6 0/7] Enable doing a shallow clone of a specific git revision
- From
Toon Claes <toon@iotcl.com>
- Date
- Feb 5, 2025, 16:47 UTC
- Message-ID
- <20250205-toon-clone-refs-v6-0-0bbc8e6d89fd@iotcl.com>
- In-Reply-To
- <20250204-toon-clone-refs-v5-0-37e34af283c8@iotcl.com>
The goal of this series is to add an option `--revision` to git-clone(1).
This series starts with a handful of preparatory refactoring commits that make it more straight-forward to add this new option. In the last commit we're actually adding the feature.
This series sets an example on how I think we can further refactor builtin/clone.c to increase the maintainability of the code.
--- Changes in v6: - Rewrite the documentation for git-clone(1) --[no-]tags. - Remove unneeded conditional around die_for_incompatible_opt2() in builtin/replay.c. - Fix typo in code comment in builtin/clone.c. - Link to v5: https://lore.kernel.org/r/20250204-toon-clone-refs-v5-0-37e34af283c8@iotcl.com
Changes in v5: - Add separate commit to introduce die_for_incompatible_opt2() - Small tweaks in documentation about `--[no-]tags` and `--revision`. - Better explain the refactoring of wanted_peer_refs() in the commit message. - Change type from `int` to `size_t` in wanted_peer_refs(). - Use lookup_commit_or_die() instead lookup_commit_reference() to avoid checking the result ourself. - Add a few code comments to explain some things. - Stylish cleanups like removal of unneeded empty lines, commented out test-code and remarks. - Link to v4: https://lore.kernel.org/r/20250131-toon-clone-refs-v4-0-2a4ff851498f@iotcl.com
Changes in v4: - Introduce a new commit to reduce the use of global variables. - Introduce a new commit to invert the flag --no-tags to --tags. - Introduce a new commit to refactor wanted_peer_refs() in builtin/clone.c. - Introduce a new commit to shuffle the handling of tags refspec. - Introduce a new commit to introduce a `struct clone_opts`. - Link to v3: https://lore.kernel.org/r/20241219-toon-clone-refs-v3-1-1484faea3008@iotcl.com
Changes in v3: - Fail early when the revision was not found on the remote, instead of creating a clone that's in an invalid state. - State more clearly in the commit message adding this option is useful for a not uncommon use-case. - Be explicit in the documentation the ref needs to peel down to a commit. - Die in case we try to update_head() to an object that's not a commit. - Allow combining `--revision` with `--bare`. - Add die_for_incompatible_opt2() to parse-options.h and use it for the options that are not compatible with the new `--revision` option. - Small tweaks to the added tests. - Small touchups on commit messages. - Link to v2: https://lore.kernel.org/r/20241129-toon-clone-refs-v2-1-dca4c19a3510@iotcl.com
---
Toon Claes (7):
clone: cut down on global variables in clone.c
clone: make it possible to specify --tags
clone: refactor wanted_peer_refs()
clone: add tags refspec earlier to fetch refspec
clone: introduce struct clone_opts in builtin/clone.c
parse-options: introduce die_for_incompatible_opt2()
builtin/clone: teach git-clone(1) the --revision= optionDocumentation/git-clone.txt | 27 +++- builtin/clone.c | 350 +++++++++++++++++++++++++------------------- builtin/replay.c | 7 +- parse-options.h | 9 ++ remote.c | 2 +- remote.h | 5 + t/meson.build | 1 + t/t5621-clone-revision.sh | 123 ++++++++++++++++ 8 files changed, 359 insertions(+), 165 deletions(-) ---
Range-diff versus v5:
1: fa3f2f1f03 = 1: 7d4d3bcc70 clone: cut down on global variables in clone.c
2: f88780b503 ! 2: 284f2fc20f clone: make it possible to specify --tags
@@ Documentation/git-clone.txt: corresponding `--mirror` and `--no-tags` options in
-`--no-tags`::
- Don't clone any tags, and set
+- `remote.<remote>.tagOpt=--no-tags` in the config, ensuring
+- that future `git pull` and `git fetch` operations won't follow
+- any tags. Subsequent explicit tag fetches will still work,
+- (see linkgit:git-fetch[1]).
+`--[no-]tags`::
-+ With `--no-tags`, no tags are cloned, and set
- `remote.<remote>.tagOpt=--no-tags` in the config, ensuring
- that future `git pull` and `git fetch` operations won't follow
- any tags. Subsequent explicit tag fetches will still work,
- (see linkgit:git-fetch[1]).
-+ By default tags are cloned, and passing `--tags` doesn't change that.
++ Control whether or not tags will be cloned. When `--no-tags` is
++ given, the option will be become permanent by setting the
++ `remote.<remote>.tagOpt=--no-tags` configuration. This ensures that
++ future `git pull` and `git fetch` won't follow any tags. Subsequent
++ explicit tag fetches will still work (see linkgit:git-fetch[1]).
++
++ By default, tags are cloned and passing `--tags` is thus typically a
++ no-op, unless it cancels out a previous `--no-tags`.
+
Can be used in conjunction with `--single-branch` to clone and
maintain a branch with no references other than a single cloned
3: 1289437661 = 3: 9114e6123d clone: refactor wanted_peer_refs()
4: 9687626855 ! 4: 52807dfdba clone: add tags refspec earlier to fetch refspec
@@ builtin/clone.c: int cmd_clone(int argc,
+ if (option_tags || option_branch)
+ /*
+ * Add tags refspec when user asked for tags (implicitly) or
-+ * specified --branch, which argument might be a tag.
++ * specified --branch, whose argument might be a tag.
+ */
+ refspec_append(&remote->fetch, TAG_REFSPEC);
+
5: c95f9d4f1b = 5: 3a80a479a6 clone: introduce struct clone_opts in builtin/clone.c
6: 96f92993fd ! 6: 5ef027f7a1 parse-options: introduce die_for_incompatible_opt2()
@@ Commit message
## builtin/replay.c ##
@@ builtin/replay.c: static void determine_replay_mode(struct rev_cmdline_info *cmd_info,
+ get_ref_information(cmd_info, &rinfo);
if (!rinfo.positive_refexprs)
die(_("need some commits to replay"));
- if (onto_name && *advance_name)
+- if (onto_name && *advance_name)
- die(_("--onto and --advance are incompatible"));
-+ die_for_incompatible_opt2(!!onto_name, "--onto",
-+ !!*advance_name, "--advance");
- else if (onto_name) {
+- else if (onto_name) {
++
++ die_for_incompatible_opt2(!!onto_name, "--onto",
++ !!*advance_name, "--advance");
++ if (onto_name) {
*onto = peel_committish(onto_name);
if (rinfo.positive_refexprs <
+ strset_get_size(&rinfo.positive_refs))
## parse-options.h ##
@@ parse-options.h: static inline void die_for_incompatible_opt3(int opt1, const char *opt1_name,
7: 9163c9bc85 = 7: 2eaae62e16 builtin/clone: teach git-clone(1) the --revision= option---
base-commit: bc204b742735ae06f65bb20291c95985c9633b7f change-id: 20241129-toon-clone-refs-ad3623772f92
Thanks -- Toon