In short: jj matches the patterns against local tags, warns about exact names that don't exist, and prints
No tags to delete. if nothing matched. Otherwise, in one transaction, it sets each matched tag's
target to absent, prints Deleted N tags., and records delete tag <names>.
The command is cmd_tag_delete, also available as
jj tag d (source). It is the tag counterpart of
jj bookmark delete; to create or move
tags, see jj tag set.
1. Command-line surface
| Argument | Type | Default | Meaning |
|---|---|---|---|
NAMES (positional) | name patterns, required | — | Tags to delete; globs by default, other string-pattern kinds allowed, several unioned (source, parse_union_name_patterns). |
2. Configuration
None of its own. Because the default immutable_heads() includes tags(), deleting a tag
can make its commit mutable again (source). In
a colocated workspace the deletion is exported to Git.
3. End-to-end flow
4. Core architecture touchpoints
| Structure | Read / write | How | Explained on |
|---|---|---|---|
View.local_tags | write | Each match is removed. Remote tag entries that are absent are dropped with it; present ones stay (source). | view |
| Immutable set | changes | The commit leaves tags(), so it may become mutable. | revsets |
| Commits | untouched | Nothing is abandoned. | commits |
| Operation | write | One operation if anything matched. | operations |
5. Transaction and operation
- Transaction: one, only when something matched (source).
- Operation description:
delete tag <name1, name2, …>(source). - Commits: none created or rewritten.
jj undobrings the tags back.
6. Algorithm and invariants
The patterns are unioned and matched against local tags only (source).
A tag matched by several patterns is deleted once. The unmatched warning covers only exact names
(warn_unmatched_local_tags), so unknown* just
prints No tags to delete. Removing a tag goes through
set_local_tag_target(name, absent).
Invariants: only local tag entries change; commits and present remote tags are untouched. All matches are deleted, or none.
7. Errors and edge cases
| Message | When | Source |
|---|---|---|
No tags to delete. | No local tag matched. | delete.rs |
Warning: No matching tags for names: … | An exact name has no local tag. | mod.rs, test |
Failed to parse name pattern: … | A pattern doesn't parse. | revset_util.rs |
clap: missing <NAMES> | No names given. | delete.rs |
8. Worked example
From upstream's test_tag_set_delete, at the end of the test: bar
is on commit1, and baz has just been moved to the commit above bbc74930. Then
jj tag delete 'b*':
Upstream's output and log (source):
Deleted 2 tags.
@ cca3d7af9d98
○ 13cbd51558a6
○ bbc749308d7f
○ b876c5f49546
◆ 000000000000
In the log, ◆ marks immutable commits: with the tags gone, the three commits are drawn as
ordinary mutable ones.