This PR's new Ruff CI job surfaced pre-existing style issues (unsorted
imports, deprecated typing.List/Dict, nested ifs, bare exit()) in
checkstyle.py. Cleaned these up so the newly added lint job passes.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
is_git_repo() used `git rev-parse --show-toplevel` to detect whether
the current directory is inside a git repository. --show-toplevel
fails for bare repositories since they have no working tree, so every
command that relies on this shared helper (e.g. `git browse`) reports
"Not a git repo!" when run from inside a bare repo, even though it
plainly is one.
Switch to `git rev-parse --git-dir`, which succeeds for both normal
and bare repositories and keeps the existing "not a repo" behavior
for non-repo directories.
Fixes#1238, reported and LGTM'd by maintainers there with this exact
fix; no PR had been opened for it yet.
Adds tests/is-git-repo.bats covering: a normal repo, a bare repo, and
a plain (non-repo) directory.
* feat(scp): add -v/--verbose and -i/--interactive flags
git scp/git rscp printed a diff via plain `git diff`/`git diff --stat`
with no `--no-pager` and no TTY check, blocking on the user's pager.
Add -v/--verbose to print the diff via --no-pager before syncing, and
-i/--interactive to also prompt for confirmation before the real
push/copy. Both apply to git scp and git rscp, and must precede
<remote>.
Updates man/git-scp.md and Commands.md.
* feat(scp): add -n/--dry-run flag
Add -n/--dry-run to preview a sync without changing anything: rsync
runs with -n, and git add --force / ssh ... rm are skipped outright.
Implies --verbose, since confirming or previewing with nothing shown
is useless.
Also restructures scp_and_stage's push/delete blocks from `&&`-chains
into if/then, needed to branch on dry-run, which incidentally fixes a
latent bug where a non-TTY COLOR_RESET could silently skip the real
rsync/git add/ssh rm calls.
Updates man/git-scp.md and Commands.md.
* test(scp): add coverage for -n/--dry-run and -i/--interactive abort
git-scp had no test coverage at all. Cover the two paths that need no
real remote destination: dry-run must preview without touching the
index, working tree, or remote path, and declining the interactive
confirmation must abort before anything syncs.
* feat(scp): Code review
* feat(scp): Code review
* Added edit/remove functionality to git-ignore.
* Minor change to array-string assignment.
* Fixes array handling for remove.
* Suggested fixes (iteration over arguments, pattern removal, editor handling, tmp file location, symlinked gitignore handling).
* Changed pure bash editing of files to an awk script. Some other minor cosmetic changes.
* Updated docs.
* Modified autocomplete to work with new git-ignore
* Added help message to git-ignore.
* Added help flags to git-ignore's man.
* Made $file in eval safe. Should not do the same for editor since then all of the GIT_EDITOR will be treated as command (flags included).
* Typo fixes.
* fix: support Windows ARM64 (clangarm64) in install.cmd
Git for Windows on ARM64 uses a `clangarm64` directory instead of
`mingw64`. The installer now auto-detects `clangarm64` when
`mingw64` is not present, so it works out of the box on ARM64
Windows machines without requiring the user to manually supply
the path.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* fix: remove trailing whitespace from install.cmd
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* Potential fix for pull request finding
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* fix: correctly resolve PREFIX when git.exe is under the arch dir in PATH
When 'where git.exe' resolves to ...\mingw64\bin\git.exe or
...\clangarm64\bin\git.exe, installdir becomes the architecture directory
itself. Detect that case by inspecting the leaf directory name instead of
appending mingw64/clangarm64 (which produced non-existent ...\mingw64\mingw64
paths) or using ..\ segments.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* feat: add git-delete-gone-branches command
Adds a new command to delete local branches whose remote-tracking
branch has been deleted (shown as [gone] in git branch -vv).
This is a common need after PRs are merged and remote branches are
cleaned up, leaving stale local branches behind.
Features:
- Deletes all local branches with a gone remote in one command
- --dry-run / -n flag to preview branches before deletion
Closes#1220
* Address PR review feedback on git-delete-gone-branches
- Use git for-each-ref instead of git branch -vv to avoid false
positives from commit messages containing ': gone]'
- Add interactive confirmation prompt by default; skip with -f/--force
- Add -p/--prune flag to run git fetch --prune before checking
- Add generated man page .1 and .html files
* Use GitHub profile for author contact in man page
* Fix gone-branch detection with nobracket format
* ability to specify command when hitting enter
* documentation
* man page
* generate man page and html
* run default command through same logic as other commands
impetuous: persist return val for display in promt if non-zero
also future-proofs for other benefits / DRYness. no need for another eval invocation.
* fix generated manpage
* repl config ideas
* documentation
* Update bin/git-repl
Co-authored-by: Edwin Kofler <edwin@kofler.dev>
* separator
* man page and web docs
* always use dir for project name
---------
Co-authored-by: Edwin Kofler <edwin@kofler.dev>
* Upgrade codespell to v2.4.0
It is a lastet verison, and is needed so that I can use the inline
ignore support in a future commit.
After updating tests/pyproject.toml I ran the following commands:
```
cd tests
poetry lock --no-update
poetry install
```
I also fixed a spelling error in man/git-summary.md, which was not
caught by the old version of codespell. After updating the file I also
updated the related files by running the following commands:
```
cd man
make -C .. man/git-summary.{1,html}
```
* add git-wip and git-unwip
Updated/re-built the documentation with:
```
cd man
make -C .. man/git-unwip.{1,html}
make -C .. man/git-wip.{1,html}
make -C .. man/git-extras.{1,html}
```
* Initial scaffold
* Finish first half of Bats tests
* Add Bats to CI
* Fix CI
* Fix CI
* Fix configuration to set git name and email
* Fix `GIT_CONFIG_{KEY,VALUE}` indexing
* Fix Git config override precedence
* Remove unused and untested function
* feat(git-bulk): add --no-follow-hidden flag
* docs(git-bulk): add --no-follow-hidden description
* docs(man): make ronn
* docs(git-bulk): put --no-follow-hidden at right place in usage()
* refactor(git-bulk): logic optimization
Remove unnecessary subshell
Co-authored-by: Edwin Kofler <edwin@kofler.dev>
* fix(git-bulk): bad test operator
With the Bash' regexp matching operator `=~`, we need to use the Bash
conditional expression evaluation command `[[ ]]`.
* docs(completion.zsh): add --no-follow-hidden and --no-follow-symlink
---------
Co-authored-by: Pierre Ayoub <pierre.ayoub@protonmail.com>
Co-authored-by: Edwin Kofler <edwin@kofler.dev>
* feat(git-summary): add --full-path option
* docs(git-summary): add doc for --full-path option
* docs(man): make using ronn
* docs(git-extras-completion.zsh): add --full-path option of git-summary
* feat(git-bulk): add --no-follow-symlinks flag
* docs(git-bulk): add --no-follow-symlinks description
* docs(man): make ronn
* docs(git-bulk): put --no-follow-symlinks at right place in usage()
* fix(git-bulk): use readarray for find command
1. Use `readarray` such that we can handle paths with spaces
2. Remove the unnecessary `eval`
* docs(git-bulk): Add zsh completion
* docs(git-bulk): Harmonize help strings
* docs(git-bulk): simplify previous bad logic
The previous logic was not allowing to use multiple options (which is
often the case). This was bad because this is my first time with zsh
automcompletion. Without it, the user can use any flag combination --
but at least, he has the freedom.
* fix(git-bulk): fix workspace selection when cd fails
`cd` may fails for multiple reasons:
- mistake when editing `.gitconfig` manually
- previously existing workspace that have been removed
- ...
Currently, if `cd` fails, the `BulkOp` continue its execution ... in the
workspace defined in a higher directory that where the user, despite the
user specified a specific workspace (`-w`).
The user should be noticed of a failed `cd` (this is really not expected
for a valid configuration) and the operations should stop to not execute
something unexpected.
* fix(git-bulk): replace weak eval for better variable substitution
Get rid of poor `eval` syntax because they are vulnerable to command
injection, which may have unexpected side effects.
However, they enabled a useful feature: using environment variable
(*e.g.*, defined in a `.bashrc`) inside the `.gitconfig` to use dynamic
paths as `bulk` workspaces.
As such, I keep this feature possible by using the Bash's ${!VAR}
syntax, which allows to get the value of one variable using the name of
a another variable. However, arbitrary command injection is not possible
anymore.
* fix(git-bulk): missing check about empty environnement variable
* style(git-bulk): typo
* docs(Commands.md): git-bulk env var feature
* docs(man/git-bulk): git-bulk env var feature
* docs(man/git-bulk): mention .gitconfig for config storage
* style(man/git-bulk): typo
* docs(man/git-bulk): run make/ronn for .1 and .html
Fix a logic error inside the `allowedargcount()` function. This function
may be called with one or two arguments. However, no default values are
assigned to `$1` and `$2` that are used inside a numerical comparison.
Therefore, when using a bad number of arguments for the following lines:
```
listall|purge) allowedargcount 1;;
addcurrent|removeworkspace) allowedargcount 2;;
```
Then, we would get the error `[: : integer expression expected`. To fix
this, we assign the 0 default value to `$1` and `$2`, such that we
trigger the error message destined to the user without any integer error
when there is a bad number of argument and that the function is called
with only 1 argument instead of 2.