7 Commits

Author SHA1 Message Date
fatalerrors
a7f7452b2b add auto to gacp 2026-05-05 16:25:13 +02:00
fatalerrors
bc67399ebc Merge branch '4.x' 2026-04-23 17:59:07 +02:00
fatalerrors
02b037d0fc proper changelog, removed the old history.txt file 2026-04-23 17:57:01 +02:00
fatalerrors
e567957ea0 update doc 2026-04-23 17:36:25 +02:00
fatalerrors
67bdd3e863 add gacp 2026-04-23 17:31:33 +02:00
fatalerrors
fa573bce8f add git helpers 2026-04-23 17:18:01 +02:00
fatalerrors
241d53ebc4 Merge branch '4.x' 2026-04-22 17:58:21 +02:00
6 changed files with 826 additions and 153 deletions

View File

@@ -58,8 +58,16 @@ A bar-style prompt showing current time, execution time of the last command
| `findbig` | filefct | Find the biggest files in the given or current directory | | `findbig` | filefct | Find the biggest files in the given or current directory |
| `finddead` | filefct | Find dead symbolic links in the given or current directory | | `finddead` | filefct | Find dead symbolic links in the given or current directory |
| `findzero` | filefct | Find empty files in the given or current directory | | `findzero` | filefct | Find empty files in the given or current directory |
| `gacp` | git | Add, commit and push changes; auto-pulls with rebase first if needed |
| `genpwd` | pwd | Generate one or more random secure passwords with configurable constraints | | `genpwd` | pwd | Generate one or more random secure passwords with configurable constraints |
| `ggraph` | git | Display a decorated git history graph |
| `gpid` | processes | Give the list of PIDs matching the given process name(s) | | `gpid` | processes | Give the list of PIDs matching the given process name(s) |
| `gprune` | git | Delete local branches already merged into the main branch |
| `greset` | git | Reset the current branch to upstream, stashing local changes first |
| `groot` | git | Display the repository root path, or change directory to it with `-g` |
| `gsync` | git | Fetch and rebase the current branch onto its upstream |
| `gst` | git | Display compact git status with branch tracking information |
| `gwip` | git | Create a quick WIP checkpoint commit |
| `help` | help | Display the list of available functions and basic usage | | `help` | help | Display the list of available functions and basic usage |
| `isipv4` | net | Tell if the given parameter is a valid IPv4 address | | `isipv4` | net | Tell if the given parameter is a valid IPv4 address |
| `isipv6` | net | Tell if the given parameter is a valid IPv6 address | | `isipv6` | net | Tell if the given parameter is a valid IPv6 address |
@@ -171,6 +179,15 @@ change the default without having to pass flags every time.
| `BUSY_DEFAULT_PATTERN` | `[0-9a-f]` | Hex pattern matched by `busy` | | `BUSY_DEFAULT_PATTERN` | `[0-9a-f]` | Hex pattern matched by `busy` |
| `BUSY_DEFAULT_DELAY` | `0.1` | Polling delay (seconds) for `busy` | | `BUSY_DEFAULT_DELAY` | `0.1` | Polling delay (seconds) for `busy` |
**`[git]`**
| Key | Default | Description |
|---|---|---|
| `GIT_MAIN_BRANCH` | `main` | Fallback main branch name used when remote HEAD cannot be detected |
| `GIT_DEFAULT_REMOTE` | `origin` | Default remote used by git helper functions |
| `GIT_WIP_PREFIX` | `wip` | Prefix used by `gwip` when generating automatic checkpoint messages |
| `GIT_GACP_AUTO_ADD` | `1` | Set to `1` to make `gacp` automatically add all modified files when no explicit file list is given; set to `0` to require explicit paths or the `-a` flag |
**`[info]`** **`[info]`**
| Key | Default | Description | | Key | Default | Description |

View File

@@ -7,6 +7,29 @@ Versions follow `MAJOR.MINOR.PATCH-REVISION_STAGE_N` (e.g. `3.99.1-4_rc_1`).
--- ---
## [4.0.0] — 2026-04-23
### Added
- New `profile.conf` reference template at `doc/profile.conf.example`.
- Dynamic locale shortcuts generated from `SET_LOCALE` and startup default
language selection through `DEFAULT_LANG`.
- Prompt theming system with bundled themes (`default`, `dark`, `light`,
`solarized`, `solarized-light`, `monokai`, `monochrome`, `abyss`, `plasma`,
`adwaita`) and per-key prompt color overrides.
- Module defaults exposed as configuration keys in `profile.conf`.
### Changed
- `utaz` now supports a wider range of archive formats.
- Prompt and theme rendering improved, including better 24-bit color support.
- Overall code quality and maintainability improved across modules.
### Documentation
- README updated with full function reference and configuration tables.
- New and expanded docs in `doc/` (`CONTRIBUTING.md`, `FAQ.md`, `todo.md`).
- Historical releases imported from `history.txt` into this changelog.
---
## [3.99.2-4_rc_2] — 2026-04-21 ## [3.99.2-4_rc_2] — 2026-04-21
### Fixed ### Fixed
@@ -78,12 +101,6 @@ Versions follow `MAJOR.MINOR.PATCH-REVISION_STAGE_N` (e.g. `3.99.1-4_rc_1`).
--- ---
---
> **Note:** Versions prior to `3.95.x-4_beta` did not maintain a formal
> changelog. The full history of earlier changes is available through the git
> log (`git log --oneline`).
## [3.95.3-4_beta_3] — 2024 ## [3.95.3-4_beta_3] — 2024
### Added ### Added
@@ -95,3 +112,153 @@ Versions follow `MAJOR.MINOR.PATCH-REVISION_STAGE_N` (e.g. `3.99.1-4_rc_1`).
- `genpwd` / `pwdscore` password tools. - `genpwd` / `pwdscore` password tools.
- `matrix` / `rain` screensavers. - `matrix` / `rain` screensavers.
- `profile_upgrade` with git and archive download support. - `profile_upgrade` with git and archive download support.
---
> **Note:** The section below was imported from `history.txt` to preserve
> pre-`3.95.x-4_beta` release notes.
## Legacy releases (imported from `history.txt`)
### [3.6.1] — 2026-03-05
- Fix typo in `compress.sh`.
### [3.6.0] — 2026-03-05
- Improved `utaz` with broader multi-format support.
- Introduced `ppu` and `ppn`.
- Improved update system.
### [3.5.0] — 2026-03-04
- `rain` now has configurable speed and color.
- `showinfo` adapted to `fastfetch` (in addition to `neofetch`).
### [3.3.1] — 2022-02-24
- Fixed version detection.
- Added `busy`.
- Fixed use of library functions before loading.
### [3.3.0] — 2022-11-28
- Initial version update support.
- Changed versioning code.
- Added installation path detection.
### [3.2.3] — 2022-11-28
- Improved README.
### [3.2.2] — 2022-11-21
- Fixed `taz` compression level parsing.
- Fixed typo in `dpkgs`.
### [3.2.1] — 2022-11-20
- Fixed several messages.
- Made `dpkgs` RPM-aware (initial support).
- Removed version history from main script and reverted declaration order.
- Added required license information in all files.
- Completed `LICENSE` file.
### [3.2.0] — 2022-11-18
- Created `disp` command and integrated it across the codebase.
### [3.1.1] — 2022-11-10
- `genpwd`: added feasibility check for requested password constraints.
### [3.1.0] — 2022-11-08
- Added password generator.
### [3.0.1] — 2022-11-07
- Added concatenation option to `rmspc`.
- Added `ku`.
- Improved error handling in `meteo`.
### [3.0.0] — 2022-08-27
- Split code into several files/modules.
- Added `rain` screensaver.
### [2.8.2] — 2022-07-29
- Added warning for non-bash users.
### [2.8.1] — 2022-07-19
- Cleanup, fixes and optimizations.
### [2.8.0] — 2022-06-24
- Added `backtrace`, `error` and `settrace`.
- Bugfixes in `showinfo`.
### [2.7.1] — 2022-06-22
- Minor corrections.
- Added `help` command.
### [2.7.0] — 2022-06-21
- Added `isipv4` and `isipv6`, integrated into `rmhost`.
- Removed broken Konsole save/restore support.
### [2.6.3] — 2021-10-18
- Changed PS1 to status-bar style.
- Minor improvements.
### [2.6.2] — 2021-02-26
- Bugfix in `taz` for directories with trailing slash.
### [2.6.1] — 2020-12-25
- Added checks in `rmhost`.
- Improved `rmspc`.
- Created `expandlist`.
### [2.6.0] — 2020-10-24
- Added Konsole session save/restore.
### [2.5.3] — 2020-09-11
- Added aliases, improved code consistency and fixed typos.
- Improved `utaz`, removed `showdiskmap`, removed remaining French text.
- Added license information for future publication.
### [2.5.2] — 2020-03-06
- Sorted and improved aliases.
### [2.5.1] — 2020-03-05
- Language consistency fixes.
- Added `pigz` support in `taz`.
### [2.5.0] — 2020-03-03
- Added `taz` and `rmspc`.
- Renamed `auzip` to `utaz` and improved it.
### [2.4.0] — 2020-03-02
- Added `auzip`.
### [2.3.2] — 2020-01-31
- `figlet`: changed default font to `ansi_shadow`.
### [2.3.1] — 2020-01-16
- Bugfix: non-interactive shells were blocked by some functions.
### [2.3.0] — 2020-01-08
- Added `figlet` and `neofetch` as MOTD replacement.
### [2.2.0] — 2019-12-16
- Added `showinfo`.
- First implementation of `showdiskmap`.
### [2.1.2] — 2019-09-24
- Bugfix in profile version display.
### [2.1.1] — 2019-09-23
- Bugfix in `dpkgs`.
### [2.1.0] — 2018-09-16
- Added `rmhost`, `setc`, `setfr`.
- Improved locale management.
### [2.0.1] — 2017-02-04
- `clean` improvements (`--shell`).
### [2.0.0] — 2015-10-24
- Added advanced functions (`clean`, `ssr`, etc.).
### [1.0.0] — 2013-02-16
- Initial version.
### [Initial fork]
Forked default Bash profile from Beyond Linux From Scratch by
* James Robertson <jameswrobertson@earthlink.net>
* Dagmar d'Surreal <rivyqntzne@pbzpnfg.arg>

View File

@@ -76,6 +76,21 @@ TERM=xterm-256color
# busy: Delay between matched lines in milliseconds (0 = no delay). # busy: Delay between matched lines in milliseconds (0 = no delay).
#BUSY_DEFAULT_DELAY=0 #BUSY_DEFAULT_DELAY=0
# ==============================================================================
[git]
# Fallback main branch name used when remote HEAD cannot be detected.
#GIT_MAIN_BRANCH=main
# Default remote used by git helper functions.
#GIT_DEFAULT_REMOTE=origin
# Prefix used by gwip when generating automatic checkpoint messages.
#GIT_WIP_PREFIX=wip
# gacp: Automatically add all modified files (git add -A) when no explicit file
# list is provided. Set to 0 to require explicit file paths or the -a flag.
#GIT_GACP_AUTO_ADD=1
# ============================================================================== # ==============================================================================
[info] [info]
# meteo: Default city when no argument is given. Leave unset to require an # meteo: Default city when no argument is given. Leave unset to require an

View File

@@ -1,147 +0,0 @@
------------------------------------------------------------------------------
Initial version from Beyond Linux From Scratch by
* James Robertson <jameswrobertson@earthlink.net>
* Dagmar d'Surreal <rivyqntzne@pbzpnfg.arg>
------------------------------------------------------------------------------
Current version from Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
------------------------------------------------------------------------------
Version history:
------------------------------------------------------------------------------
# 05/03/2026 v3.6.1
Fix a typo in compress.sh
# 05/03/2026 v3.6.0
Improved utaz to make it multiformat with lot of it
Introduced ppu and ppn
Improved update system
# 04/03/2026 v3.5.0
rain has now configurable speed and color
showinfo adapted to fastfetch, replacing neofetch
# 24/02/2022 v3.3.1
Fixed version detection
Added "busy" function
Fixed use of library functions before it's loaded
# 28/11/2022 v3.3.0
Initial version update support
Changed versioning code
Added installation path detection
# 28/11/2022 v3.2.3
Made proper readme file, to improve
# 21/11/2022 v3.2.2
Fixed taz compression level analysis
Fixed typo in dpkgs
# 20/11/2022 v3.2.1
Fix some messages
Make dpkgs rpm aware (more to come)
Removed version history from main script and revert declaration order
Added required license information in all files
Completed LICENSE file
# 18/11/2022 v3.2.0
Created disp command for display and make use of it
# 10/11/2022 v3.1.1
genpwd: test if password is doable
# 08/11/2022 v3.1.0
Added password generator
# 07/11/2022 v3.0.1
Added concatenation to rmspc
Added ku
Error managed in meteo
# 27/08/2022 v3.0.0
Splitted everything in several files
Added rain screensaver
# 29/07/2022 v2.8.2
Added warning for non bash or zsh users
# 19/07/2022 v2.8.1
Few cleanups, fixes and optimizations
# 24/06/2022 v2.8.0
Added backtrace, error and settrace
[bugfix] corrected showinfo
# 22/06/2022 v2.7.1
[bugfix] few minor corrections
Added help command
# 21/06/2022 v2.7.0
Added isipv4 and isipv6 and use it in rmhost as an improvement
Removed konsole save and restore not working
# 18/10/2021 v2.6.3
Changed PS1 for status bar style version
Few minor improvements
# 26/02/2021 v2.6.2
[bugfix] taz: corrected bug with trailing slash on directories
# 25/12/2020 v2.6.1
Add check on rmhost
Improvements rmspc
Created expendlist
# 24/10/2020 v2.6.0
Added session save and restore for Konsole
# 11/09/2020 v2.5.3
Few more aliases, improved code consistancy and typo,
Improved utaz, removed showdiskmap, removed remaining French,
Added license information for future publication
# 06/03/2020 v2.5.2
Few aliases sorted out
# 05/03/2020 v2.5.1
Language consistancy fix
Added pigz support in taz
# 03/03/2020 v2.5.0
Added command taz and rmspc
Renamed auzip => utaz and improved it
# 02/03/2020 v2.4.0
Added command auzip
# 31/01/2020 v2.3.2
Figlet: changed default font to ansi_shadow
# 16/01/2020 v2.3.1
[bugfix] non-interactive were blocked with some functions
# 08/01/2020 v2.3.0
Added use of figlet and neofetch as a motd replace
# 16/12/2019 v2.2.0
Added showinfo
Primary write of showdiskmap
# 24/09/2019 v2.1.2
[bugfix] bug in profile version display
# 23/09/2019 v2.1.1
[bugfix] dpkgs
# 16/09/2018 v2.1.0
Added rmhost, setc, setfr
More locales management
# 04/02/2017 v2.0.1
clean improvements (--shell)
# 24/10/2015 v2.0.0
Added advanced functionnalities (clean, srr, etc.)
# 16/02/2013 v1.0.0
Initial version

613
profile.d/git.sh Executable file
View File

@@ -0,0 +1,613 @@
#!/usr/bin/env bash
# ------------------------------------------------------------------------------
# Copyright (c) 2013-2026 Geoffray Levasseur <fatalerrors@geoffray-levasseur.org>
# Protected by the BSD3 license. Please read bellow for details.
#
# * Redistribution and use in source and binary forms,
# * with or without modification, are permitted provided
# * that the following conditions are met:
# *
# * Redistributions of source code must retain the above
# * copyright notice, this list of conditions and the
# * following disclaimer.
# *
# * Redistributions in binary form must reproduce the above
# * copyright notice, this list of conditions and the following
# * disclaimer in the documentation and/or other materials
# * provided with the distribution.
# *
# * Neither the name of the copyright holder nor the names
# * of any other contributors may be used to endorse or
# * promote products derived from this software without
# * specific prior written permission.
# *
# * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
# * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
# * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
# * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
# * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
# * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
# * OF SUCH DAMAGE.
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
# Built-in defaults (can be overridden from [git] section in profile.conf)
: "${GIT_MAIN_BRANCH:=main}"
: "${GIT_DEFAULT_REMOTE:=origin}"
: "${GIT_WIP_PREFIX:=wip}"
: "${GIT_GACP_AUTO_ADD:=1}"
# ------------------------------------------------------------------------------
# Internal helper: ensure git is available and cwd is a git worktree
_git_require_repo()
{
if ! command -v git >/dev/null 2>&1; then
disp E "git command not found."
return 1
fi
if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
disp E "Current directory is not inside a git repository."
return 1
fi
return 0
}
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
# Internal helper: return default branch from remote HEAD, fallback to config
_git_default_branch()
{
local remote="${1:-$GIT_DEFAULT_REMOTE}"
local head
head=$(git symbolic-ref --quiet --short "refs/remotes/${remote}/HEAD" 2>/dev/null) || true
if [[ -n $head ]]; then
printf "%s\n" "${head#${remote}/}"
return 0
fi
printf "%s\n" "$GIT_MAIN_BRANCH"
return 0
}
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
# Display compact git status + branch tracking information
# Usage: gst [path]
gst()
{
local PARSED
PARSED=$(getopt -o h --long help -n 'gst' -- "$@")
# shellcheck disable=SC2181 # getopt return code is checked immediately after
if [[ $? -ne 0 ]]; then
disp E "Invalid options, use \"gst --help\" to display usage."
return 1
fi
eval set -- "$PARSED"
while true; do
case "$1" in
-h|--help)
printf "gst: Display short git status and branch tracking info.\n"
printf "Usage: gst [path]\n"
return 0
;;
--)
shift
break
;;
*)
disp E "Invalid options, use \"gst --help\" to display usage."
return 1
;;
esac
done
local target="${1:-.}"
git -C "$target" status --short --branch
}
export -f gst
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
# Show a readable commit graph
# Usage: ggraph [-n limit]
ggraph()
{
local PARSED
PARSED=$(getopt -o hn: --long help,limit: -n 'ggraph' -- "$@")
# shellcheck disable=SC2181 # getopt return code is checked immediately after
if [[ $? -ne 0 ]]; then
disp E "Invalid options, use \"ggraph --help\" to display usage."
return 1
fi
eval set -- "$PARSED"
local limit=30
while true; do
case "$1" in
-h|--help)
printf "ggraph: Display decorated git history graph.\n"
printf "Usage: ggraph [-n limit]\n"
printf "Options:\n"
printf "\t-n, --limit\tNumber of commits to display (default: 30)\n"
return 0
;;
-n|--limit)
limit="$2"
shift 2
;;
--)
shift
break
;;
*)
disp E "Invalid options, use \"ggraph --help\" to display usage."
return 1
;;
esac
done
[[ $limit =~ ^[0-9]+$ ]] || {
disp E "Invalid limit: must be a positive integer."
return 1
}
_git_require_repo || return 1
git log --graph --decorate --oneline --all --max-count="$limit"
}
export -f ggraph
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
# Sync current branch with remote (fetch + rebase)
# Usage: gsync [remote]
gsync()
{
local PARSED
PARSED=$(getopt -o h --long help -n 'gsync' -- "$@")
# shellcheck disable=SC2181 # getopt return code is checked immediately after
if [[ $? -ne 0 ]]; then
disp E "Invalid options, use \"gsync --help\" to display usage."
return 1
fi
eval set -- "$PARSED"
while true; do
case "$1" in
-h|--help)
printf "gsync: Fetch and rebase current branch onto its remote tracking branch.\n"
printf "Usage: gsync [remote]\n"
return 0
;;
--)
shift
break
;;
*)
disp E "Invalid options, use \"gsync --help\" to display usage."
return 1
;;
esac
done
_git_require_repo || return 1
local remote="${1:-$GIT_DEFAULT_REMOTE}"
local branch upstream
branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null) || return 1
upstream=$(git rev-parse --abbrev-ref --symbolic-full-name '@{u}' 2>/dev/null) || true
disp I "Fetching from $remote..."
git fetch --prune "$remote" || return 1
if [[ -z $upstream ]]; then
disp W "No upstream configured for $branch, skipping rebase."
disp I "Set one with: git branch --set-upstream-to ${remote}/${branch} ${branch}"
return 0
fi
disp I "Rebasing $branch onto $upstream..."
git rebase "$upstream"
}
export -f gsync
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
# Add, commit, and push changes with automatic pull/rebase if needed
# Usage: gacp -m "message" [file1 file2 ...]
gacp()
{
local PARSED
PARSED=$(getopt -o ham: --long help,auto,message: -n 'gacp' -- "$@")
# shellcheck disable=SC2181 # getopt return code is checked immediately after
if [[ $? -ne 0 ]]; then
disp E "Invalid options, use \"gacp --help\" to display usage."
return 1
fi
eval set -- "$PARSED"
local msg="" auto_add="$GIT_GACP_AUTO_ADD"
while true; do
case "$1" in
-h|--help)
printf "gacp: Run git add, git commit, and git push in one command.\n"
printf "Usage: gacp [-a] -m \"message\" [file1 file2 ...]\n"
printf "Options:\n"
printf "\t-a, --auto\tAutomatically add all modified files (git add -A)\n"
printf "\t-m, --message\tCommit message (mandatory)\n"
printf "\n"
printf "If files are provided, only those paths are added (-a is ignored).\n"
printf "If no file is provided and -a is active, all changes are added with git add -A.\n"
printf "Default for -a can be set via GIT_GACP_AUTO_ADD in profile.conf.\n"
printf "If the remote branch moved forward, gacp pulls with rebase before pushing.\n"
return 0
;;
-a|--auto)
auto_add=1
shift
;;
-m|--message)
msg="$2"
shift 2
;;
--)
shift
break
;;
*)
disp E "Invalid options, use \"gacp --help\" to display usage."
return 1
;;
esac
done
_git_require_repo || return 1
if [[ -z $msg ]]; then
disp E "Missing commit message. Use -m or --message."
return 1
fi
local branch upstream remote tracking_branch behind counts
branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null) || return 1
upstream=$(git rev-parse --abbrev-ref --symbolic-full-name '@{u}' 2>/dev/null) || true
if [[ $# -gt 0 ]]; then
auto_add=0
disp I "Adding selected paths..."
git add -- "$@" || return 1
elif [[ $auto_add -eq 1 ]]; then
disp I "Adding all changes..."
git add -A || return 1
else
disp E "No files specified. Use -a/--auto or provide file paths."
return 1
fi
if git diff --cached --quiet; then
disp W "No staged changes to commit."
return 1
fi
disp I "Creating commit..."
git commit -m "$msg" || return 1
if [[ -n $upstream ]]; then
remote="${upstream%%/*}"
tracking_branch="${upstream#*/}"
else
remote="$GIT_DEFAULT_REMOTE"
tracking_branch="$branch"
fi
disp I "Fetching from $remote..."
git fetch --prune "$remote" || return 1
if git rev-parse --verify --quiet "refs/remotes/${remote}/${tracking_branch}" >/dev/null; then
counts=$(git rev-list --left-right --count HEAD..."${remote}/${tracking_branch}" 2>/dev/null) || return 1
read -r _ behind <<< "$counts"
if [[ ${behind:-0} -gt 0 ]]; then
disp I "Remote branch is ahead, rebasing before push..."
git pull --rebase "$remote" "$tracking_branch" || return 1
fi
fi
if [[ -n $upstream ]]; then
disp I "Pushing to $upstream..."
git push || return 1
else
disp I "Pushing and setting upstream to ${remote}/${branch}..."
git push -u "$remote" "$branch" || return 1
fi
disp I "gacp complete."
return 0
}
export -f gacp
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
# Reset local branch to exact upstream state (stash local changes first)
# Usage: greset [target]
greset()
{
local PARSED
PARSED=$(getopt -o hx --long help,with-ignored -n 'greset' -- "$@")
# shellcheck disable=SC2181 # getopt return code is checked immediately after
if [[ $? -ne 0 ]]; then
disp E "Invalid options, use \"greset --help\" to display usage."
return 1
fi
eval set -- "$PARSED"
local clean_ignored=0
while true; do
case "$1" in
-h|--help)
printf "greset: Reset current branch to upstream, stashing local changes first.\n"
printf "Usage: greset [target]\n"
printf "Options:\n"
printf "\t-x, --with-ignored\tAlso remove ignored files (git clean -fdx)\n"
printf "\n"
printf "Default target is current branch upstream (@{u}).\n"
printf "If no upstream exists, fallback target is <remote>/<branch>.\n"
printf "This command stashes local modifications (tracked + untracked),\n"
printf "drops local unpushed commits by hard-reset, and cleans untracked files.\n"
return 0
;;
-x|--with-ignored)
clean_ignored=1
shift
;;
--)
shift
break
;;
*)
disp E "Invalid options, use \"greset --help\" to display usage."
return 1
;;
esac
done
_git_require_repo || return 1
local branch upstream target remote old_head stash_msg stash_out stash_created=0 dropped=0
branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null) || return 1
upstream=$(git rev-parse --abbrev-ref --symbolic-full-name '@{u}' 2>/dev/null) || true
target="$1"
if [[ -z $target ]]; then
if [[ -n $upstream ]]; then
target="$upstream"
else
remote="$GIT_DEFAULT_REMOTE"
target="${remote}/${branch}"
fi
fi
if [[ -z $remote ]]; then
remote="${target%%/*}"
fi
old_head=$(git rev-parse HEAD 2>/dev/null) || return 1
if ! git diff --quiet || ! git diff --cached --quiet || [[ -n $(git ls-files --others --exclude-standard) ]]; then
stash_msg="greset:${branch}:$(date +'%Y-%m-%d %H:%M:%S')"
disp I "Stashing local changes as '$stash_msg'..."
stash_out=$(git stash push -u -m "$stash_msg" 2>&1) || {
disp E "Failed to stash local changes."
printf "%s\n" "$stash_out"
return 1
}
[[ $stash_out != "No local changes to save"* ]] && stash_created=1
fi
disp I "Fetching from $remote..."
git fetch --prune "$remote" || return 1
if ! git rev-parse --verify --quiet "$target" >/dev/null; then
disp E "Target '$target' does not exist."
return 1
fi
dropped=$(git rev-list --count "${target}..${old_head}" 2>/dev/null || printf "0")
disp W "Hard-resetting $branch to $target..."
git reset --hard "$target" || return 1
if (( clean_ignored )); then
git clean -fdx || return 1
else
git clean -fd || return 1
fi
if (( stash_created )); then
disp I "Local changes were stashed. Use 'git stash list' and 'git stash pop' when needed."
fi
disp I "greset complete. Dropped local-only commits: $dropped"
return 0
}
export -f greset
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
# Create a quick WIP commit for local checkpointing
# Usage: gwip [message]
gwip()
{
local PARSED
PARSED=$(getopt -o h --long help -n 'gwip' -- "$@")
# shellcheck disable=SC2181 # getopt return code is checked immediately after
if [[ $? -ne 0 ]]; then
disp E "Invalid options, use \"gwip --help\" to display usage."
return 1
fi
eval set -- "$PARSED"
while true; do
case "$1" in
-h|--help)
printf "gwip: Create a local checkpoint commit with all tracked/untracked changes.\n"
printf "Usage: gwip [message]\n"
return 0
;;
--)
shift
break
;;
*)
disp E "Invalid options, use \"gwip --help\" to display usage."
return 1
;;
esac
done
_git_require_repo || return 1
local msg
if [[ $# -gt 0 ]]; then
msg="$*"
else
msg="$GIT_WIP_PREFIX: $(date +'%Y-%m-%d %H:%M:%S')"
fi
git add -A || return 1
git commit -m "$msg"
}
export -f gwip
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
# Delete merged local branches (except protected branches)
# Usage: gprune [main-branch]
gprune()
{
local PARSED
PARSED=$(getopt -o h --long help -n 'gprune' -- "$@")
# shellcheck disable=SC2181 # getopt return code is checked immediately after
if [[ $? -ne 0 ]]; then
disp E "Invalid options, use \"gprune --help\" to display usage."
return 1
fi
eval set -- "$PARSED"
while true; do
case "$1" in
-h|--help)
printf "gprune: Delete local branches already merged into main branch.\n"
printf "Usage: gprune [main-branch]\n"
return 0
;;
--)
shift
break
;;
*)
disp E "Invalid options, use \"gprune --help\" to display usage."
return 1
;;
esac
done
_git_require_repo || return 1
local base="${1:-$(_git_default_branch "$GIT_DEFAULT_REMOTE")}" current deleted=0
current=$(git rev-parse --abbrev-ref HEAD 2>/dev/null) || return 1
disp I "Pruning branches merged into $base..."
while IFS= read -r b; do
[[ -z $b ]] && continue
[[ $b == "$current" ]] && continue
[[ $b == "$base" ]] && continue
[[ $b == "master" || $b == "main" || $b == "develop" || $b == "dev" ]] && continue
git branch -d "$b" >/dev/null 2>&1 && {
printf "Deleted: %s\n" "$b"
((deleted++))
}
done < <(git branch --merged "$base" | sed -E 's/^\*?\s*//')
(( deleted == 0 )) && disp I "No merged branches to delete."
}
export -f gprune
# ------------------------------------------------------------------------------
# ------------------------------------------------------------------------------
# Print repository root path
# Usage: groot
groot()
{
local PARSED
PARSED=$(getopt -o hg --long help,go -n 'groot' -- "$@")
# shellcheck disable=SC2181 # getopt return code is checked immediately after
if [[ $? -ne 0 ]]; then
disp E "Invalid options, use \"groot --help\" to display usage."
return 1
fi
eval set -- "$PARSED"
local do_go=0
while true; do
case "$1" in
-h|--help)
printf "groot: Display the absolute path of the current repository root.\n"
printf "Usage: groot [-g|--go]\n"
printf "Options:\n"
printf "\t-g, --go\tChange current directory to repository root\n"
return 0
;;
-g|--go)
do_go=1
shift
;;
--)
shift
break
;;
*)
disp E "Invalid options, use \"groot --help\" to display usage."
return 1
;;
esac
done
_git_require_repo || return 1
local root
root=$(git rev-parse --show-toplevel) || return 1
if (( do_go )); then
cd "$root" || {
disp E "Failed to move to repository root: $root"
return 1
}
return 0
fi
printf "%s\n" "$root"
}
export -f groot
# ------------------------------------------------------------------------------
load_conf git
# EOF

View File

@@ -52,7 +52,15 @@ help()
printf "findbig\t\tFind the biggest files in the given or current directory\n" printf "findbig\t\tFind the biggest files in the given or current directory\n"
printf "finddead\tFind dead symbolic links in the given or current directory\n" printf "finddead\tFind dead symbolic links in the given or current directory\n"
printf "findzero\tFind empty files in the given or current directory\n" printf "findzero\tFind empty files in the given or current directory\n"
printf "gacp\t\tAdd, commit and push changes (auto-pull if needed)\n"
printf "genpwd\t\tGenerate one or more random secure passwords with configurable constraints\n" printf "genpwd\t\tGenerate one or more random secure passwords with configurable constraints\n"
printf "ggraph\t\tDisplay decorated git history graph\n"
printf "gprune\t\tDelete local branches already merged into main branch\n"
printf "greset\t\tReset branch to upstream (stash local, drop local commits)\n"
printf "groot\t\tDisplay repository root path (or cd to it with -g)\n"
printf "gsync\t\tFetch and rebase current branch onto upstream\n"
printf "gst\t\tDisplay short git status and branch tracking info\n"
printf "gwip\t\tCreate a quick WIP checkpoint commit\n"
printf "gpid\t\tGive the list of PIDs matching the given process name(s)\n" printf "gpid\t\tGive the list of PIDs matching the given process name(s)\n"
printf "isipv4\t\tTell if the given parameter is a valid IPv4 address\n" printf "isipv4\t\tTell if the given parameter is a valid IPv4 address\n"
printf "isipv6\t\tTell if the given parameter is a valid IPv6 address\n" printf "isipv6\t\tTell if the given parameter is a valid IPv6 address\n"