Skip to content

Epics and Links

Mohsen Beiranvand edited this page Aug 7, 2026 · 1 revision

Epics and Links

Two distinct ways to relate tasks to each other: epics (a strict parent/child hierarchy, one parent per task) and links (a loose, typed, many-to-many relation).

Epics

git task epic SRV-epic add SRV-child      # make SRV-child a child of SRV-epic
git task epic SRV-epic rm SRV-child       # remove it

Under the hood, epic add sets the child's parent field, and epic rm clears it. git task new --parent SRV-epic and git task edit --parent SRV-epic set the same field directly; epic exists as a clearer, purpose-named entry point for the same operation.

git task show SRV-epic                    # full detail, including every child
git task ls --parent SRV-epic             # same-repo children only

show's JSON response is the one place a complete children list appears (children[]), covering both same-repo and cross-repo children. ls --parent only ever surfaces same-repo children, since it isn't scanning other repos.

Links

git task link SRV-1 add blocks SRV-2      # kinds: blocks | relates | dup
git task link SRV-1 rm blocks SRV-2

Unlike a parent, a task can carry any number of links, of any kind, in either direction. blocks/relates/dup (short for "duplicates") are the only kinds; there's no way to register a custom one.

Cross-repo epics and links

Both epic add/rm and link add/rm accept --repo <name|path|url>, letting the epic or the linked task live in a different repository than the one you're running the command from:

git task epic LB-epic add SRV-child --repo backend
git task link SRV-1 add blocks LB-abc123 --repo backend

The two behave differently under the hood, and it matters:

  • link --repo just records the reference. It fails only if --repo itself can't be resolved (an unregistered name, or a local path that doesn't exist); a URL is the one exception, stored and compared verbatim, never checked over the network. The target task id you gave is never validated to actually exist.
  • epic --repo goes further. It requires the target repo registered under the same project as the current repo (see Sync and Multi-Repo), and it opens that repo to confirm the epic id you gave actually exists there. A typo, or a repo registered under a different project, fails the command outright rather than silently recording a dead reference.

--repo accepts a registered repo name, a local filesystem path, or a remote URL (for link; epic --repo requires a registered name since it needs the project match). Registering a repo (git task register) also captures its origin URL, which is what makes a cross-repo link portable: the URL, not your machine-local path, is what gets stored, and it's compared in a protocol/host-form-agnostic way, so the same link resolves correctly for a teammate whose registry maps that URL to a different local path.

In JSON output, a same-repo link/parent has target/parent set to the resolved local task id and target_repo/parent_repo as null. A cross-repo one has the opposite: target/parent is null (nothing local to resolve), target_repo/parent_repo carries the target repo's identifier, and target_display_id/parent_display_id carries the raw label you typed. See JSON Output.

Clone this wiki locally