Skip to content

feat(clean): add --force flag to git gtr clean --merged#158

Open
maro114510 wants to merge 7 commits intocoderabbitai:mainfrom
maro114510:feat/clean-force-flag
Open

feat(clean): add --force flag to git gtr clean --merged#158
maro114510 wants to merge 7 commits intocoderabbitai:mainfrom
maro114510:feat/clean-force-flag

Conversation

@maro114510
Copy link

@maro114510 maro114510 commented Mar 16, 2026

Pull Request

Description

Adds --force to git gtr clean --merged so that worktrees with uncommitted changes or untracked files are no longer automatically skipped when the flag is explicitly provided.

Design boundary: --force bypasses only the uncommitted-changes and untracked-files checks. Detached HEAD and empty-branch protections are intentionally retained — those states indicate the branch identity is indeterminate, meaning removal could discard unrecoverable work regardless of --force.

--yes scope is unchanged; it continues to control confirmation prompts only.

Motivation

clean --merged skips any worktree with uncommitted changes or untracked files to prevent accidental data loss — a sound default for work-in-progress. However, when those files are build artifacts, generated output, or throwaway logs, the check becomes an obstacle.
The only workaround today is manually running git stash or git clean -fd in each affected worktree first.

git gtr rm already provides --force for the same class of problem in single-worktree removal. This PR brings clean --merged in line with that existing precedent.

Fixes # #157

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Code refactoring (no functional changes)
  • Other (please describe):

Testing

  • 361/361 BATS tests pass (bats tests/)
  • ShellCheck clean (shellcheck lib/commands/clean.sh)

Manual Testing Checklist

Tested on:

  • macOS
  • Linux (specify distro: **_**)
  • Windows (Git Bash)

Core functionality tested:

  • git gtr new <branch> - Create worktree
  • git gtr go <branch> - Navigate to worktree
  • git gtr editor <branch> - Open in editor (if applicable)
  • git gtr ai <branch> - Start AI tool (if applicable)
  • git gtr rm <branch> - Remove worktree
  • git gtr list - List worktrees
  • git gtr config - Configuration commands (if applicable)
  • Other commands affected by this change: git gtr clean --merged

Test Steps

  1. Create a worktree and introduce a dirty state:
    git gtr new test-feature --track none --from HEAD
    echo "artifact" > ../repo-worktrees/test-feature/build.log
    git -C ../repo-worktrees/test-feature add build.log
  2. Run git gtr clean --merged --yes (without --force)
  3. Run git gtr clean --merged --force --yes

Expected behavior:

  • Step 2: [!] Skipping test-feature (has uncommitted changes) — worktree is preserved
  • Step 3: dirty check is bypassed; worktree is removed if its PR is merged
  • Detached HEAD worktrees are still skipped even with --force

Actual behavior:

Matches expected.

Breaking Changes

  • This PR introduces breaking changes
  • I have discussed this in an issue first
  • Migration guide is included in documentation

Checklist

Before submitting this PR, please check:

  • I have read CONTRIBUTING.md
  • My code follows the project's style guidelines
  • I have performed manual testing on at least one platform
  • I have updated documentation (README.md, CLAUDE.md, etc.) if needed
  • My changes work on multiple platforms (or I've noted platform-specific behavior)
  • I have added/updated shell completions (if adding new commands or flags)
  • I have tested with both git gtr (production) and ./bin/gtr (development)
  • No new external dependencies are introduced (Bash + git only)
  • All existing functionality still works

Additional Context

Implementation propagates the flag through the call chain:

cmd_clean()           --force flag → local force
  └─ _clean_merged()  6th arg force="${6:-0}"
       └─ _clean_should_skip()  3rd arg force="${3:-0}"

License Acknowledgment

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache License 2.0.

Summary by CodeRabbit

  • New Features

    • Added --force (-f) to the clean command to allow forced removal of worktrees even with uncommitted changes or untracked files; supports auto-confirmation when combined with --yes.
  • Documentation

    • Updated help text, README, and shell completions to document and surface the new --force behavior and examples.
  • Tests

    • Added tests validating --force behavior, including dirty/untracked worktrees and preserved protections (detached HEAD, empty branches).

Extends _clean_should_skip() with an optional third argument `force`.
When force=1, uncommitted-changes and untracked-files checks are
bypassed, allowing removal of worktrees that contain build artifacts
or other disposable local state.

Detached HEAD and empty-branch protections are retained regardless of
--force, as those states are indeterminate.

Propagates force through _clean_merged() (new 6th arg) and cmd_clean()
(new --force|-f flag spec entry). All new arguments default to 0,
preserving full backward compatibility.
Covers four cases for _clean_should_skip with force=1:
- dirty worktree (staged changes) → not skipped
- worktree with untracked files   → not skipped
- detached HEAD                   → still skipped (protection retained)
- empty branch name               → still skipped (protection retained)

Also adds a smoke test confirming cmd_clean accepts --force without error.
Updates all three shell completion files (Bash, Zsh, Fish) so that
--force and -f appear as tab-completion candidates for `git gtr clean`.
Adds --force, -f to the Options section of `git gtr help clean` and
the full help page. Adds two usage examples demonstrating
--force alone and combined with --yes. Updates README.md with the
same option entry and examples.
@coderabbitai
Copy link

coderabbitai bot commented Mar 16, 2026

Walkthrough

Adds a --force (-f) option to the clean command; the flag is parsed in cmd_clean, propagated into _clean_merged and _clean_should_skip to bypass uncommitted/untracked checks, and documented and surfaced in shell completions and tests. No other control-flow or exported-interface changes.

Changes

Cohort / File(s) Summary
Documentation
README.md, lib/commands/help.sh
Document --force/-f option and update usage/examples to include force behavior.
Shell Completions
completions/_git-gtr, completions/git-gtr.fish, completions/gtr.bash
Add --force completion entry for the clean subcommand and broaden rm/remove force descriptions.
Core Implementation
lib/commands/clean.sh
Introduce force parameter: update _clean_should_skip(dir, branch, force) and _clean_merged(..., force), parse --force in cmd_clean, and propagate force to merged-clean logic to bypass dirty/untracked checks.
Tests
tests/cmd_clean.bats
Add tests asserting --force bypasses dirty/untracked worktree skips while still skipping detached HEAD and empty-branch cases; verify CLI accepts --force.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I hopped in with a flag — small, bold, and terse,
"Force" on my back, I clear thorns from the verse.
Docs updated, completions sing the tune,
Tests nod along beneath the git-silver moon. ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(clean): add --force flag to git gtr clean --merged' clearly and concisely describes the primary change: introducing a --force flag to the clean --merged command, which is the main feature added in this pull request.
Docstring Coverage ✅ Passed Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@maro114510 maro114510 marked this pull request as ready for review March 16, 2026 05:40
@maro114510 maro114510 requested a review from NatoBoram as a code owner March 16, 2026 05:40
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
tests/cmd_clean.bats (1)

105-108: Consider adding a short-flag acceptance test (-f) for parity.

You validate --force, but not -f. A tiny test here would lock in alias behavior.

Suggested test addition
 `@test` "cmd_clean accepts --force flag without error" {
   run cmd_clean --force
   [ "$status" -eq 0 ]
 }
+
+@test "cmd_clean accepts -f flag without error" {
+  run cmd_clean -f
+  [ "$status" -eq 0 ]
+}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/cmd_clean.bats` around lines 105 - 108, Add a parallel test for the
short alias of the force flag by creating a new bats test similar to the
existing "cmd_clean accepts --force flag without error" that runs cmd_clean -f
and asserts exit status 0; locate the existing cmd_clean test block and
duplicate its structure but replace "--force" with "-f" so the CLI alias
behavior for the -f short flag is validated.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@lib/commands/help.sh`:
- Line 573: Update the full-help description for the option string "--force, -f"
in the help text to reflect actual behavior: state that it forces removal even
if the worktree has uncommitted changes and also bypasses skipping of untracked
files (i.e., it will remove tracked and untracked files). Match the wording to
the shorter help entry earlier in the file (the other "--force, -f" occurrence)
so both descriptions are consistent.

---

Nitpick comments:
In `@tests/cmd_clean.bats`:
- Around line 105-108: Add a parallel test for the short alias of the force flag
by creating a new bats test similar to the existing "cmd_clean accepts --force
flag without error" that runs cmd_clean -f and asserts exit status 0; locate the
existing cmd_clean test block and duplicate its structure but replace "--force"
with "-f" so the CLI alias behavior for the -f short flag is validated.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 095e7ce2-ee76-40cb-823e-fb0129190857

📥 Commits

Reviewing files that changed from the base of the PR and between 5afbfa8 and 041c448.

📒 Files selected for processing (7)
  • README.md
  • completions/_git-gtr
  • completions/git-gtr.fish
  • completions/gtr.bash
  • lib/commands/clean.sh
  • lib/commands/help.sh
  • tests/cmd_clean.bats

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@completions/_git-gtr`:
- Around line 86-88: Update the completion option descriptions to mention
untracked files: change the '--force[Force removal even if worktree has
uncommitted changes]' description to include "or untracked files" (e.g., "Force
removal even if worktree has uncommitted changes or untracked files") and
likewise update the '-n[Show what would be removed]' description if it should
also clarify it includes untracked files; edit the strings for the '-n' and
'--force' entries in the completions/_git-gtr file to reflect this wording.

In `@completions/git-gtr.fish`:
- Line 106: The completion for the git clean command uses the entry with
condition '__fish_git_gtr_using_command clean' and option flag '-l force' whose
description currently says "Force removal even if worktree has uncommitted
changes"; update that description to mention that --force also bypasses the
untracked files check (e.g., include "and untracked files") so it accurately
reflects the behavior of the --force flag for git clean.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 2c89d570-6c5c-4669-8871-f92cfc77b650

📥 Commits

Reviewing files that changed from the base of the PR and between 041c448 and 08b1701.

📒 Files selected for processing (6)
  • README.md
  • completions/_git-gtr
  • completions/git-gtr.fish
  • completions/gtr.bash
  • lib/commands/clean.sh
  • lib/commands/help.sh
🚧 Files skipped from review as they are similar to previous changes (2)
  • README.md
  • completions/gtr.bash

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

♻️ Duplicate comments (1)
completions/git-gtr.fish (1)

106-106: ⚠️ Potential issue | 🟡 Minor

Clean --force description is still incomplete.

Line 106 mentions only uncommitted changes, but clean --merged --force also bypasses untracked-files checks. Please align wording with actual behavior.

📝 Proposed fix
-complete -c git -n '__fish_git_gtr_using_command clean' -l force -d 'Force removal even if worktree has uncommitted changes'
+complete -c git -n '__fish_git_gtr_using_command clean' -l force -d 'Force removal even if worktree has uncommitted changes or untracked files'
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@completions/git-gtr.fish` at line 106, Update the description text for the
--force completion entry (the complete invocation using
'__fish_git_gtr_using_command clean' with flag '-l force') so it accurately
reflects behavior: mention that --force forces removal of files even if the
worktree has uncommitted changes and, when used with --merged, also bypasses
untracked-files checks (i.e., will remove files that would otherwise be
protected by untracked-files settings).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Duplicate comments:
In `@completions/git-gtr.fish`:
- Line 106: Update the description text for the --force completion entry (the
complete invocation using '__fish_git_gtr_using_command clean' with flag '-l
force') so it accurately reflects behavior: mention that --force forces removal
of files even if the worktree has uncommitted changes and, when used with
--merged, also bypasses untracked-files checks (i.e., will remove files that
would otherwise be protected by untracked-files settings).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: ccf8cb03-71b0-4343-ad83-af4053685790

📥 Commits

Reviewing files that changed from the base of the PR and between 08b1701 and ab65ca0.

📒 Files selected for processing (2)
  • completions/_git-gtr
  • completions/git-gtr.fish
🚧 Files skipped from review as they are similar to previous changes (1)
  • completions/_git-gtr

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant