Skip to content

Comments

Skip fetch when no remote is configured (#69)#74

Open
FilleTP wants to merge 3 commits intomainfrom
feature/69-skip-fetch-without-remote
Open

Skip fetch when no remote is configured (#69)#74
FilleTP wants to merge 3 commits intomainfrom
feature/69-skip-fetch-without-remote

Conversation

@FilleTP
Copy link
Contributor

@FilleTP FilleTP commented Feb 16, 2026

Skip fetch in finish when no remote is configured and replace hardcoded "origin" with the configured remote name in branch deletion.

Finish defaults to fetching before merge, but on local-only repos (no remote configured) this produced confusing "does not appear to be a git repository" errors from git. The fetch is now silently skipped when RemoteExists() returns false.

Additionally, deleteBranchesIfNeeded() previously hardcoded "origin" for remote branch deletion — it now uses cfg.Remote (from gitflow.origin), and cfg is threaded through handleDeleteBranchStep and
handleCreateTagStep consistent with all other step handlers. A new RemoteExists() function is added to the git package. Two integration tests verify both fixes.

Resolves #69

Remarks

  • The fetch skip is silent by design — local-only workflows should not see remote-related noise
  • cfg threading through handleDeleteBranchStep and handleCreateTagStep eliminates redundant LoadConfig() calls both previously loaded config independently with an "origin" fallback
  • Repos with a configured remote are completely unaffected

Review focus:

  • cmd/finish.go — fetch guard at line 198 and cfg threading through handleDeleteBranchStep/deleteBranchesIfNeeded
  • cmd/finish.go — also handleCreateTagStep now receives cfg instead of calling LoadConfig() internally
  • internal/git/repo.go — new RemoteExists() implementation
  • test/cmd/finish_fetch_test.go — TestFinishFeatureBranchNoRemote
  • test/cmd/finish_retention_test.go — TestFinishDeleteBranchUsesConfiguredRemote

Finish defaults to fetching before merge, but on local-only repos
this produced confusing "does not appear to be a git repository"
errors from git. Now the fetch is silently skipped when the
configured remote doesn't exist.

Also fixes hardcoded "origin" in deleteBranchesIfNeeded() — branch
deletion now uses the configured remote name (gitflow.origin) and
cfg is threaded through handleDeleteBranchStep consistent with all
other step handlers.

- Add RemoteExists() to git package (local-only check)
- Guard fetch in finish with remote existence check
- Thread cfg through handleDeleteBranchStep call chain
- Add integration tests for both fixes
- Update finish manpage for fetch skip behavior

Resolves #69
Copy link

@claude claude bot left a comment

Choose a reason for hiding this comment

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

Approved · 🟢 Low impact

Adds silent fetch skip when no remote is configured and fixes hardcoded "origin" in branch deletion to use the configured remote name. The implementation is clean, follows project patterns well, and includes thorough test coverage. Both fixes address real workflow gaps without affecting existing behavior for repos with remotes. Code quality, security, commit message, and architecture were reviewed with no concerns.

Test Coverage Assessment

Excellent test coverage for both fixes. Tests follow project conventions and verify the correct behaviors.

Existing tests

Test file What it covers Evaluation
finish_fetch_test.go::TestFinishFeatureBranchNoRemote Creates a local-only repo, runs finish with default fetch, verifies fetch is skipped silently (no output, no errors), and confirms successful merge ✅ Solid
finish_retention_test.go::TestFinishDeleteBranchUsesConfiguredRemote Sets up repo with "upstream" remote instead of "origin", configures gitflow.origin=upstream, publishes branch, finishes it, and verifies remote branch deletion uses "upstream" ✅ Solid

🤖 AI fix prompt

No fixes needed — this PR is ready to merge.

Copy link
Contributor

@alexrinass alexrinass left a comment

Choose a reason for hiding this comment

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

Clean fix — the RemoteExists() guard and cfg threading through handleDeleteBranchStep/deleteBranchesIfNeeded are well done. Tests are thorough and follow project conventions.

One issue: handleCreateTagStep (line 353) still has the exact same anti-pattern this PR fixes in handleDeleteBranchStep — a redundant LoadConfig() call with an "origin" fallback. Since cfg is already available in executeSteps, it should be threaded through here too.

err = handleUpdateChildrenStep(cfg, state, branchConfig, resolvedOptions)
case stepDeleteBranch:
return handleDeleteBranchStep(state, resolvedOptions) // Final step
return handleDeleteBranchStep(cfg, state, resolvedOptions) // Final step
Copy link
Contributor

Choose a reason for hiding this comment

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

Good fix. The same treatment is needed one case above: handleCreateTagStep(state, resolvedOptions) at line 353 still calls config.LoadConfig() internally with an "origin" fallback (lines 679-684). Since cfg is right here, thread it through the same way.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks Alex - its updated now to pass the config parameter.

cmd/finish.go Outdated
// Use force delete since we've already merged the branch
forceDelete := true
if err := deleteBranchesIfNeeded(state, keepRemote, keepLocal, forceDelete); err != nil {

Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: this blank line is a style-only change unrelated to the fix.

Same anti-pattern as handleDeleteBranchStep — redundant LoadConfig()
call with hardcoded "origin" fallback. cfg is already available in
executeSteps, so thread it through instead.
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Improves finish behavior for local-only repositories by avoiding unnecessary remote operations and ensuring remote deletions respect the configured remote name (gitflow.origin), aligning finish with the configuration-driven design of git-flow-next.

Changes:

  • Skip the pre-merge fetch in finish when the configured remote does not exist locally.
  • Use cfg.Remote (from gitflow.origin) instead of hardcoding "origin" when deleting remote branches, and thread cfg through step handlers to avoid redundant config loads.
  • Add integration tests covering the no-remote fetch skip and the configured-remote deletion behavior; update the finish manpage accordingly.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.

Show a summary per file
File Description
cmd/finish.go Guards fetch with git.RemoteExists(cfg.Remote) and threads cfg through step handlers so remote deletion/tag contexts use the configured remote.
internal/git/repo.go Adds RemoteExists(remote string) bool helper used by finish to detect absence of a configured remote.
docs/git-flow-finish.1.md Documents that --fetch is automatically skipped when no remote is configured.
test/cmd/finish_fetch_test.go Adds coverage ensuring fetch is silently skipped (no “origin not a repository” noise) in a local-only repo.
test/cmd/finish_retention_test.go Adds coverage ensuring remote branch deletion uses the configured remote name (e.g., upstream).

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.

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.

git-flow-next requires origin repo

2 participants