[PATCH v6 0/7] Enable doing a shallow clone of a specific git revision

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxx

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@xxxxxxxxx

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@xxxxxxxxx

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@xxxxxxxxx

---
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= option

 Documentation/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





[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux