-
Notifications
You must be signed in to change notification settings - Fork 11
cmd(git): More commands #465
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #465 +/- ##
===========================================
+ Coverage 42.90% 53.18% +10.28%
===========================================
Files 38 38
Lines 3627 5663 +2036
Branches 794 1063 +269
===========================================
+ Hits 1556 3012 +1456
- Misses 1718 2120 +402
- Partials 353 531 +178 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
ff046f3 to
5dff81e
Compare
8808231 to
700a4fa
Compare
f520132 to
af58b49
Compare
adfbeaa to
76822c5
Compare
8adff4c to
c843022
Compare
8839c2a to
0385215
Compare
11dbd6a to
8578585
Compare
2e5347d to
bb6d40e
Compare
why: Both shared=True and shared=False were passing --shared flag. Per git-init docs, --shared without value defaults to group permissions. shared=False should mean "no --shared flag", not default group sharing. what: - Only append --shared when shared is explicitly True - shared=False now behaves like shared=None (no flag)
why: Plain str paths were silently ignored when building required_flags. Only list and pathlib.Path were handled, so Git.stash.push(path="file.txt") would not limit the stash to that path. what: - Change elif isinstance(path, pathlib.Path) to elif path is not None - Remove unnecessary .absolute() conversion that broke relative paths - Now handles str, Path, and list consistently
why: GitRemoteManager.add() exposed fetch, track, master parameters in the signature but they were never translated to CLI flags. Callers would get silent no-ops when using these options. what: - Wire fetch to -f flag - Wire track to -t <branch> - Wire master to -m <master>
why: Commit 03b124c fixed shared=False passing --shared, but had no test. what: - Add InitSharedFixture NamedTuple with 4 test cases - Test shared=True, shared=False, shared=None, shared="group" - Verify "shared git repository" only in output when expected
why: Commit ece0d80 fixed str paths being silently ignored, but had no test. what: - Add test_stash_cmd_push_path_types testing str, pathlib.Path, list - Use timestamp filenames to avoid pytest-rerunfailures conflicts - Verify only specified file is stashed, not all modified files
…params why: Commit 5c00880 wired fetch/track/master params, but had no test. what: - Add RemoteAddParamFixture NamedTuple with 3 test cases - Add CreateRepoPytestFixtureFn import for remote repo fixture - Test fetch=True, track="master", master="master" separately
why: Git's `notes merge` has three mutually exclusive forms that were not properly supported - the API required notes_ref always, but --commit and --abort forms take no ref argument. what: - Make notes_ref optional (None default) - Add validation for mutual exclusivity of commit, abort, and notes_ref - Only append notes_ref when provided and not using commit/abort - Prevent strategy from being used with commit/abort
why: Multiple run() methods accepted **kwargs in their signatures but did not forward them to self.cmd.run(), silently ignoring any extra parameters like env, cwd, or custom config. what: - Add **kwargs to GitNotesManager.run() call - Add **kwargs to GitBranchCmd.run() call - Add **kwargs to GitBranchManager.run() call - Add **kwargs to GitRemoteCmd.run() call - Add **kwargs to GitRemoteManager.run() call
why: The assert statement was checking `any(f for f in ["push", "fetch"])` which always returns True since non-empty strings are truthy. The actual mirror value was never validated. what: - Replace always-true assertion with proper validation - Raise ValueError if mirror is not 'push' or 'fetch' - Fix --mirror syntax to use = format per git-remote docs - Simplify bool check with elif
…eter why: The doctest used quiet=True, but git remote has no --quiet flag. With kwargs passthrough now working, this caused a TypeError. what: - Replace quiet=True with check_returncode=False in doctest
why: The -C flag was appending a list object as the second element, creating invalid argv like ["git", "-C", ["path1", "path2"]] which subprocess cannot handle. Git requires separate -C flags for each path. what: - Iterate over normalized C list and append -C for each path
why: The stringify helper used `if True` instead of `if v`, causing all boolean config values to serialize as "true" regardless of actual value. what: - Change `return "true" if True else "false"` to `if v else "false"`
why: Git's init command does not have a --default flag. This parameter would cause runtime failures when used. what: - Remove default parameter from init() signature - Remove default from docstring - Remove if default is True: block
why: Using `if verbose is not None:` would add --verbose for both True and False values. The flag should only be added when verbose=True. what: - Change `if verbose is not None:` to `if verbose is True:` in GitRemoteCmd.show() and GitRemoteManager.show()
why: The config_env parameter was accepted but never used, silently ignoring callers who expected --config-env=<name>=<envvar> to be passed. what: - Add implementation to emit --config-env flag after config handling
why: Using !r (repr) incorrectly added quotes around the path, causing
git to fail with "unknown option: --separate-git-dir='/path/to/dir'".
what:
- Change {separate_git_dir!r} to {separate_git_dir!s} to match init()
why: The parameter was emitting --reference instead of --reference-if-able, which has different semantics (--reference fails if local repo is missing, --reference-if-able silently skips). what: - Change ["--reference", reference_if_able] to ["--reference-if-able", ...]
why: The --branch and --origin flags only exist for git clone, not for git fetch or git pull. Using these parameters would cause git to fail with "unknown option 'branch'" or "unknown option 'origin'". what: - Remove branch and origin parameters from fetch() signature - Remove branch and origin parameters from pull() signature - Remove implementation code that emitted these invalid flags
why: Parameters deepen, negotiation_tip, recurse_submodules, and recurse_submodules_default were defined but never used, silently ignoring callers' requests. what: - Add --deepen=<n> flag emission for deepen parameter - Add --negotiation-tip=<rev> flag emission for negotiation_tip - Add --recurse-submodules[=yes|on-demand|no] for recurse_submodules - Add --recurse-submodules-default=<value> for recurse_submodules_default - Applied to both fetch() and pull() methods
why: The whitespace parameter emitted --whitespace without the required value, and no_whitespace was invalid (git has no such flag). The correct options are --whitespace=<option> and --ignore-whitespace. what: - Fix whitespace to emit --whitespace=<value> with the option value - Replace no_whitespace with ignore_whitespace parameter - Emit --ignore-whitespace for the new boolean parameter
why: The flag was misspelled as --no-rerwre-autoupdate which would cause git to fail with "unknown option". what: - Fix typo: rerwre -> rerere
why: The flags were spelled with underscore (--sign_off, --no-sign_off) but git expects hyphen format (--signoff, --no-signoff). what: - Change --sign_off to --signoff - Change --no-sign_off to --no-signoff
why: GitNotesManager stores a custom ref but GitNoteCmd objects created by ls() ignored it, causing show/remove operations to always target refs/notes/commits instead of the manager's ref. what: - Add ref parameter to GitNoteCmd.__init__ - Pass --ref flag in GitNoteCmd.run() when ref is set - Update GitNotesManager.ls() to pass ref to GitNoteCmd instances
why: The regex pattern used \S+ for URLs which failed to match paths containing spaces (e.g., /tmp/foo bar), causing those remotes to be silently dropped from the listing. what: - Change URL pattern from \S+ to .+? (non-greedy any char) - Add line anchors (^ and $) for proper multiline matching - Non-greedy ensures we stop at the (fetch|push) suffix
why: Ensure GitNoteCmd ref propagation and URL space parsing fixes are covered by explicit regression tests. what: - Add test_notes_custom_ref_propagation: verifies GitNoteCmd objects from ls() inherit the manager's ref for show/remove operations - Add test_remote_url_with_spaces: verifies regex correctly parses remote URLs containing spaces (e.g., /tmp/foo bar) - Both tests use parametrized NamedTuple fixtures per project pattern
Code reviewFound 4 issues:
Lines 5941 to 5947 in 9421936
Lines 6121 to 6127 in 9421936
Lines 6695 to 6701 in 9421936
Lines 5553 to 5559 in 9421936
Context: Commit 🤖 Generated with Claude Code - If this code review was useful, please react with 👍. Otherwise, react with 👎. |
Code review (updated)Found 7 instances of missing
Lines 2450 to 2456 in 9421936
Lines 4553 to 4559 in 9421936
Lines 5075 to 5081 in 9421936
Lines 5941 to 5947 in 9421936
Lines 6121 to 6127 in 9421936
Lines 6458 to 6464 in 9421936
Lines 6695 to 6701 in 9421936
Context: Commit 🤖 Generated with Claude Code - If this code review was useful, please react with 👍. Otherwise, react with 👎. |
why: Multiple run() methods accepted **kwargs in their signatures but did not forward them to self.cmd.run(), silently ignoring parameters like env, cwd, or custom config. what: - Add **kwargs forwarding to GitSubmoduleCmd.run() - Add **kwargs forwarding to GitStashEntryCmd.run() - Add **kwargs forwarding to GitStashManager.run() - Add **kwargs forwarding to GitTagCmd.run() - Add **kwargs forwarding to GitTagManager.run() - Add **kwargs forwarding to GitWorktreeCmd.run() - Add **kwargs forwarding to GitWorktreeManager.run()
cmd(git): More commands
Summary
This PR introduces the Manager/Cmd pattern for git subcommands, providing
typed Python objects instead of raw strings. It also includes numerous bug
fixes to existing git command implementations.
Changes
New: Manager/Cmd Pattern
New Manager Classes
GitBranchManagergit.branchesGitBranchCmdGitRemoteManagergit.remotesGitRemoteCmdGitStashManagergit.stashesGitStashEntryCmdGitTagManagergit.tagsGitTagCmdGitWorktreeManagergit.worktreesGitWorktreeCmdGitNotesManagergit.notesGitNoteCmdGitSubmoduleManagergit.submodulesGitSubmoduleEntryCmdGitReflogManagergit.reflogGitReflogEntryCmdEnhanced Git.init()
ref_formatparameter for--ref-format(files/reftable)make_parentsto auto-create parent directories (default: True)sharedextended to support octal permissions (e.g., "0660")Bug Fixes
Git.run() fixes
"true" if True->"true" if v)config_envparameterGit.clone() fixes
reference_if_ableflag name (was using--reference)separate_git_dirquoting (was using!rinstead of!s)Git.fetch()/Git.pull() fixes
branch/originparametersrecurse_submodules,recurse_submodules_default,negotiation_tip--signoffflag spellingGit.rebase() fixes
--no-rerere-autoupdatetypoignore_whitespaceinstead ofno_whitespace)Git.init() fixes
--defaultparameter--sharedwhenshared=FalseManager/Cmd fixes
**kwargsto underlyingcmd.run()calls in all Manager/Cmd classesstash@{N}format instead of pathspec separatorgit branchinstead ofcheckout -b--verbosewhen explicitly TrueDocumentation