feat: add sync command to merge default branch into current branch#39
Merged
Conversation
Updating a feature branch with the latest master/main was a manual chore: run `gitm checkout master -r <repo>`, then cd into each repo and `git merge master` by hand, repeated per repo. `gitm sync` automates this across selected repos in parallel — interactively, or via --repo/--all. For each repo it auto-detects the default branch (main/master) from the stored value, skips dirty repos and repos already on the default branch, fetches the latest default from origin, and merges origin/<default> into the current branch. Merge conflicts are intentionally left in place and reported so the user can resolve them, rather than aborting or failing the whole run. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
✅ All checks passed (Go 1.26) Coverage: 69.9% |
There was a problem hiding this comment.
Pull request overview
Adds a new gitm sync command to merge each selected repository’s default branch into its current branch, fitting into the existing multi-repo CLI workflow.
Changes:
- Adds sync command wiring, selection modes, merge workflow, conflict reporting, and tests.
- Adds git merge/unmerged-file primitives with real-repo tests.
- Updates README command reference and root command registration tests.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
README.md |
Documents gitm sync and updates project structure. |
internal/git/git.go |
Adds merge and unmerged-file helpers. |
internal/git/merge_test.go |
Tests merge success, conflicts, and clean unmerged checks. |
internal/cli/sync.go |
Implements the new sync command workflow. |
internal/cli/sync_test.go |
Tests sync command flags and core repo behavior. |
internal/cli/root.go |
Registers the sync command. |
internal/cli/root_test.go |
Updates expected subcommands. |
The Test Stats table had drifted (38 files / 330 functions): test functions were added since the stats landed in #34 without updating the count, and this branch adds two test files (merge_test.go, sync_test.go). Counts exclude the single TestMain harness entry point, which is not a test. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
✅ All checks passed (Go 1.26) Coverage: 69.9% |
…fallback Resolves four review findings on the new sync command: - Require a fully clean working tree (git.IsDirty) instead of tracked-only. A merge can be blocked by an untracked file that collides with a path the default branch introduces, so untracked changes must skip the repo too — IsDirtyTrackedOnly is documented as safe only when untracked files pose no conflict risk, which is not the case for a merge. - Return a non-zero error when runner.HasErrors, matching the other multi-repo commands. Real failures (status/branch errors, non-conflict merge errors) now surface; merge conflicts remain intentional skips that still exit 0. - Stop printing the fetch-failure warning from inside the parallel worker (which could interleave with the runner's synchronized output) and fold it into the returned result message instead. - Prefer origin/<default> only when the fetch succeeded; on a failed/offline fetch fall back to the local default branch rather than silently merging a stale remote-tracking ref. Adds tests for the untracked-skip and error-exit paths; refreshes test stats. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
✅ All checks passed (Go 1.26) Coverage: 69.9% |
The sync help text and README described the manual workflow as `gitm checkout master` followed by `git merge master`, but that sequence leaves you on the default branch and makes the merge a no-op. Reword both to describe what sync actually replaces: pulling the latest master/main and merging it into your working branch by hand, per repo. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
✅ All checks passed (Go 1.26) Coverage: 69.9% |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds a new top-level command,
gitm sync, that merges the latest default branch (main/master, auto-detected per repo) into whatever branch each selected repository is currently on — across one or many repos in parallel.Why
Updating a feature branch with the latest
master/mainwas a manual, repetitive chore: rungitm checkout master -r <repo>, thencdinto the repo folder andgit merge masterby hand, repeated for every repo. This is exactly the kind of multi-repo git operationgitmexists to automate.How it works
For each selected repo (in parallel via
runner.Run):repo.DefaultBranch(set atrepo add).gitm updatefor pulling).origin, then mergesorigin/<default>into the current branch (falls back to the local default branch when there's no remote).Selection modes (consistent with
checkout/branch)gitm sync— interactive TUI multi-selectgitm sync --repo a,b/-r a,b— named repos, no promptgitm sync --all/-a— every repo, no promptChanges
internal/git/git.go: newMergeandUnmergedFilesprimitives (only new git ops needed).internal/cli/sync.go: new command +runSyncWithUIworkflow.internal/cli/root.go: registersyncCmd().README.md: ToC entry, full command reference, project-structure tree.Testing
internal/git/merge_test.go: clean merge, conflict (left in merging state), clean-repo unmerged check.internal/cli/sync_test.go: command wiring, happy-path merge, dirty skip, on-default skip, conflict-left-in-place,--repo/--allbypass TUI, no-repos.-race:go test ./... -race→ 447 passed across 8 packages.make lintclean.🤖 Generated with Claude Code