Manage GitHub Labels Safely with gh label

Twelve near-duplicate labels and no idea which repository you are about to change: gh label tames both from the terminal. In about ten minutes you can inspect labels, create one, edit or rename one, clone a set between repositories, and delete one deliberately. The examples use gh 2.45.0, the version installed on the system used for this guide.

1. Check the target before changing it

Every subcommand accepts -R or --repo with an optional host, owner and repository. Use the complete value in every example, so a shell directory or an unexpected current repository cannot send a change elsewhere.

gh auth status
gh label list --repo OWNER/REPOSITORY --limit 100

Replace OWNER/REPOSITORY with a real repository such as octocat/hello-world. The list command fetches at most 30 labels by default, so raise --limit for a fuller inventory. A successful response is a table of label names, colours and descriptions.

Warning: If the command reports an authentication or permission error, stop and fix access. Do not retry with a write command.

2. Confirm the inventory

For a machine-readable check, ask for selected fields and filter them with --jq:

gh label list --repo OWNER/REPOSITORY --json name,color,description \
  --jq '.[] | [.name, .color, (.description // "")] | @tsv'

The JSON fields include the name, colour, description, default status, creation and update times, and URL. Use --search bug to search names and descriptions.

Tip: Search results are sorted by relevance, so --sort and --order do not control that result set.

3. Create a label with explicit metadata

Creating a label changes the remote repository. Choose the name, description and six-character hexadecimal colour first. Write the colour without a leading hash.

gh label create "needs reproduction" \
  --repo OWNER/REPOSITORY \
  --description "A report needs a small reproducible case" \
  --color D4C5F9

On success, gh reports that the label was created. Leave out the colour option and gh picks a random colour, which makes repeatable setup hard to review. If the label already exists, use --force only when you mean to update its colour and description:

gh label create "needs reproduction" \
  --repo OWNER/REPOSITORY \
  --description "A report needs a small reproducible case" \
  --color D4C5F9 \
  --force

Verify the resulting record instead of trusting the short status message:

gh label list --repo OWNER/REPOSITORY --search "needs reproduction" \
  --json name,color,description

4. Edit or rename an existing label

gh label edit changes the label named by its positional argument. Set a colour, a description, a new name, or any combination. A rename still changes the remote repository, so check the current spelling first.

gh label edit "needs reproduction" \
  --repo OWNER/REPOSITORY \
  --name "needs-reproduction" \
  --color BFDADC \
  --description "A report needs a small reproducible case"

Editing has no --force flag. If the original name is wrong, the command fails rather than guessing. Confirm both the new name and its metadata:

gh label list --repo OWNER/REPOSITORY --search "needs-reproduction" \
  --json name,color,description

5. Clone labels without overwriting by accident

Use gh label clone SOURCE-OWNER/SOURCE-REPOSITORY to copy labels from one repository. The destination defaults to the current repository, but an explicit --repo makes it obvious:

gh label clone SOURCE-OWNER/SOURCE-REPOSITORY \
  --repo DEST-OWNER/DEST-REPOSITORY

By default:

Warning: The next option overwrites matching destination labels, metadata included. Review both inventories first and use it only when synchronisation is intended.

gh label clone SOURCE-OWNER/SOURCE-REPOSITORY \
  --repo DEST-OWNER/DEST-REPOSITORY \
  --force

Cloning is not a two-way synchronisation, and it never removes destination-only labels. Re-run the destination list command and compare the names and metadata you expected.

6. Delete only with a recovery plan

Deletion is irreversible through gh label. It removes the label from the repository, and the command asks for confirmation by default. Name one label and one repository explicitly, and do not wrap it in a broad shell loop.

gh label delete "needs-reproduction" --repo OWNER/REPOSITORY

Read the confirmation prompt and answer only if the target is correct. For non-interactive use, --yes skips the prompt:

gh label delete "needs-reproduction" \
  --repo OWNER/REPOSITORY \
  --yes

Recovery: There is no undo command in this group. Before deleting a label used by automation or issue templates, record its name, colour and description with gh label list --json, then recreate it with gh label create using those values. Issues that used the old label may need separate review.

Common traps

Done means