feat(repo): add --exclude-subgroup to group clone

Description

Adds a repeatable --exclude-subgroup flag to glab repo clone --group, so you can clone a whole group tree except for one or more subgroups you don't need.

glab repo clone -g mygroup --exclude-subgroup domain/backend --paginate
glab repo clone -g mygroup --exclude-subgroup domain/backend,docs
  • GET /groups/:id/projects has no exclusion parameter, so the filter runs on the client side. It drops matching projects after they are listed and before anything is cloned, and skipped projects don't show up in the output.
  • Paths are relative to the --group value. A value that already starts with the group path also works.
  • Matching is case-insensitive, ignores leading and trailing slashes, and respects path segment boundaries. domain/backend skips domain/backend/svc but not domain/backend-utils.
  • If the excludes remove every project, the command logs an error and exits non-zero, just like the existing empty-group case.
  • The flag is listed right after --include-subgroups in help. There's a new example, and docs/source/repo/clone.md was regenerated with make gen-docs.

Known limit: relative paths can't be resolved when --group is a numeric group ID.

Resolves #7916 (closed)

How has this been tested?

  • TestNewCmdClone: flag parsing for repeated and comma-separated values.
  • TestIsExcludedSubgroup: a table test of the matcher (nested subgroups, group-prefixed values, sibling with a shared string prefix, case, slashes, empty values).
  • TestGroupCloneExcludeSubgroup: an end-to-end run with mocked Users.CurrentUser and Groups.ListGroupProjects and stubbed git clone. It checks that only projects outside the excluded subgroup get cloned, and that excluding every project returns an error.
  • go test ./internal/commands/project/clone/..., golangci-lint, and the lefthook hooks all pass locally.

Merge request reports

Loading
Loading