gitbash 1.6.6 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # gitbash
2
2
 
3
- Pure bash, zero dependency git commands. Reduce repetitive typing and supercharge git workflows with interactive previews and safe cleanup - see a [full comparison](./docs/workflows.md).
3
+ Pure bash, zero-dependency git utilities. Reduce repetitive typing and supercharge git workflows with optional interactive previews and safe cleanup — see a [full comparison](./docs/workflows.md).
4
4
 
5
5
  ![screenshot-status.png](./docs/screenshot-status.png)
6
6
 
@@ -15,10 +15,11 @@ npm i -g gitbash && gitbash --config
15
15
  ### Options
16
16
 
17
17
  ```bash
18
- gitbash --help # Show help
19
- gitbash --version # Show version
20
- gitbash --init # Print shell init code
21
- gitbash --config # Interactive configuration wizard
18
+ gitbash --help # Show help
19
+ gitbash --version # Show version
20
+ gitbash --init # Print shell init code
21
+ gitbash --config # Interactive configuration wizard
22
+ gitbash --config-local # Configure local overrides for current repository
22
23
  ```
23
24
 
24
25
  ### Dependencies
@@ -241,6 +242,18 @@ GITBASH_CLEANUP_DAYS=7
241
242
 
242
243
  You can create this file manually or use `gitbash --config` to configure interactively.
243
244
 
245
+ #### Local Configuration
246
+
247
+ gitbash also supports repository-specific configuration overrides. Run `gitbash --config-local` inside a git repository to create a `.gitbashrc` file in the repository root.
248
+
249
+ Local settings override the global `~/.gitbashrc` for that repository only. This is useful for:
250
+
251
+ - Different branch prefixes per project (e.g., team names)
252
+ - Project-specific issue parsing settings
253
+ - Different stale/cleanup thresholds per repository
254
+
255
+ The interactive wizard will show each setting's current global value and ask if you want to override it locally. Only overridden values are written to the local config.
256
+
244
257
  ### Individual aliases
245
258
 
246
259
  Instead of adding every command via `eval "$(gitbash --init)"` in `.zshrc` or `.bashrc`
package/bin/gitbash CHANGED
@@ -4,12 +4,24 @@
4
4
  set -euo pipefail
5
5
 
6
6
  CONFIG_FILE="$HOME/.gitbashrc"
7
+ LOCAL_CONFIG_FILE=".gitbashrc"
7
8
 
8
9
  load_config() {
10
+ # Source global config first
9
11
  if [[ -f "$CONFIG_FILE" ]]; then
10
12
  # shellcheck disable=SC1090
11
13
  source "$CONFIG_FILE"
12
14
  fi
15
+
16
+ # Source local config from repo root if present (overrides global)
17
+ local repo_root
18
+ if repo_root=$(git rev-parse --show-toplevel 2>/dev/null); then
19
+ local local_config="$repo_root/$LOCAL_CONFIG_FILE"
20
+ if [[ -f "$local_config" ]]; then
21
+ # shellcheck disable=SC1090
22
+ source "$local_config"
23
+ fi
24
+ fi
13
25
  }
14
26
 
15
27
  configure_gitbash() {
@@ -48,7 +60,7 @@ configure_gitbash() {
48
60
  if [[ -n "$current_prefix" ]]; then
49
61
  echo "Tip: Enter a single dash '-' to explicitly clear the prefix"
50
62
  fi
51
- read -e -p "Branch prefix [${current_prefix}]: " prefix
63
+ read -re -p "Branch prefix [${current_prefix}]: " prefix
52
64
  # If user just pressed Enter, keep current value
53
65
  # If user entered a single dash, clear it
54
66
  if [[ -z "$prefix" ]]; then
@@ -61,7 +73,7 @@ configure_gitbash() {
61
73
 
62
74
  # Merge tool
63
75
  echo
64
- read -e -p "Merge tool command (used by update on conflicts) [${current_merge}]: " input
76
+ read -re -p "Merge tool command (used by update on conflicts) [${current_merge}]: " input
65
77
  merge_cmd=${input:-$current_merge}
66
78
 
67
79
  # Issue parsing
@@ -72,7 +84,7 @@ configure_gitbash() {
72
84
  current_enabled="no"
73
85
  fi
74
86
 
75
- read -e -p "Enable Jira issue parsing in branch names? (yes/no) [${current_enabled}]: " input
87
+ read -re -p "Enable Jira issue parsing in branch names? (yes/no) [${current_enabled}]: " input
76
88
  local enable_parsing=${input:-$current_enabled}
77
89
 
78
90
  # Convert answer to no_issue_parsing variable (inverted logic)
@@ -91,7 +103,7 @@ configure_gitbash() {
91
103
 
92
104
  # Issue parsing fallback (only ask if parsing is enabled)
93
105
  if [[ "$enable_parsing" == "yes" ]]; then
94
- read -e -p "Fallback prefix when no issue number is provided [${current_issue_fallback}]: " input
106
+ read -re -p "Fallback prefix when no issue number is provided [${current_issue_fallback}]: " input
95
107
  issue_fallback=${input:-$current_issue_fallback}
96
108
  else
97
109
  issue_fallback="${current_issue_fallback}"
@@ -103,7 +115,7 @@ configure_gitbash() {
103
115
  echo " auto - Use terminal's theme detection"
104
116
  echo " dark - Force dark theme"
105
117
  echo " light - Force light theme (GitHub style)"
106
- read -e -p "Theme [${current_theme}]: " input
118
+ read -re -p "Theme [${current_theme}]: " input
107
119
  theme=${input:-$current_theme}
108
120
  case "$theme" in
109
121
  auto|dark|light) ;;
@@ -115,7 +127,7 @@ configure_gitbash() {
115
127
 
116
128
  # Stale branch threshold
117
129
  echo
118
- read -e -p "Stale branch threshold in months (used by stale) [${current_stale_months}]: " input
130
+ read -re -p "Stale branch threshold in months (used by stale) [${current_stale_months}]: " input
119
131
  stale_months=${input:-$current_stale_months}
120
132
  if ! [[ "$stale_months" =~ ^[0-9]+$ ]] || [[ "$stale_months" -lt 1 ]]; then
121
133
  echo "Invalid value. Using default of 3 months."
@@ -123,7 +135,7 @@ configure_gitbash() {
123
135
  fi
124
136
 
125
137
  # Cleanup threshold
126
- read -e -p "Cleanup threshold in days (used by cleanup) [${current_cleanup_days}]: " input
138
+ read -re -p "Cleanup threshold in days (used by cleanup) [${current_cleanup_days}]: " input
127
139
  cleanup_days=${input:-$current_cleanup_days}
128
140
  if ! [[ "$cleanup_days" =~ ^[0-9]+$ ]] || [[ "$cleanup_days" -lt 1 ]]; then
129
141
  echo "Invalid value. Using default of 7 days."
@@ -171,6 +183,182 @@ EOF
171
183
  check_shell_integration
172
184
  }
173
185
 
186
+ configure_local_gitbash() {
187
+ # Check if we're in a git repository
188
+ local repo_root
189
+ if ! repo_root=$(git rev-parse --show-toplevel 2>/dev/null); then
190
+ echo "Error: Not inside a git repository." >&2
191
+ exit 1
192
+ fi
193
+
194
+ local local_config="$repo_root/$LOCAL_CONFIG_FILE"
195
+
196
+ # Load global config first to get current defaults
197
+ load_config
198
+
199
+ # Backward compatibility: migrate GITBASH_FEATURE_BRANCH_PREFIX to GITBASH_CREATE_BRANCH_PREFIX
200
+ local current_prefix="${GITBASH_CREATE_BRANCH_PREFIX:-}"
201
+ if [[ -z "$current_prefix" && -n "${GITBASH_FEATURE_BRANCH_PREFIX:-}" ]]; then
202
+ # Remove "feature/" prefix from old variable
203
+ current_prefix="${GITBASH_FEATURE_BRANCH_PREFIX#feature/}"
204
+ fi
205
+ # Remove trailing slash if present
206
+ current_prefix="${current_prefix%/}"
207
+
208
+ echo "Configure local gitbash overrides for this repository"
209
+ echo "Config will be saved to: $local_config"
210
+ echo
211
+ echo "Press Enter to keep global setting, or enter a new value to override."
212
+ echo "Enter '-' to explicitly unset a local override."
213
+ echo
214
+
215
+ local overrides=()
216
+ local input
217
+
218
+ # Branch prefix (current_prefix already set above with backward compatibility)
219
+ echo "1. Branch prefix"
220
+ echo " Current (global): ${current_prefix:-'(empty)'}"
221
+ read -re -p " Local override: " input
222
+ if [[ -n "$input" ]]; then
223
+ if [[ "$input" == "-" ]]; then
224
+ overrides+=("GITBASH_CREATE_BRANCH_PREFIX=\"\"")
225
+ echo " → Will use empty prefix locally"
226
+ else
227
+ input="${input%/}" # Remove trailing slash
228
+ overrides+=("GITBASH_CREATE_BRANCH_PREFIX=\"$input\"")
229
+ echo " → Will use '$input' locally"
230
+ fi
231
+ else
232
+ echo " → Keeping global setting"
233
+ fi
234
+ echo
235
+
236
+ # Merge command
237
+ local current_merge="${GITBASH_MERGE_COMMAND:-fork}"
238
+ echo "2. Merge tool command (used by update on conflicts)"
239
+ echo " Current (global): $current_merge"
240
+ read -re -p " Local override: " input
241
+ if [[ -n "$input" && "$input" != "-" ]]; then
242
+ overrides+=("GITBASH_MERGE_COMMAND=\"$input\"")
243
+ echo " → Will use '$input' locally"
244
+ else
245
+ echo " → Keeping global setting"
246
+ fi
247
+ echo
248
+
249
+ # Issue parsing
250
+ local current_no_issue_parsing="${GITBASH_CREATE_NO_ISSUE_PARSING:-no}"
251
+ local current_enabled="yes"
252
+ [[ "$current_no_issue_parsing" == "yes" ]] && current_enabled="no"
253
+ echo "3. Enable Jira issue parsing in branch names? (yes/no)"
254
+ echo " Current (global): $current_enabled"
255
+ read -re -p " Local override: " input
256
+ if [[ -n "$input" && "$input" != "-" ]]; then
257
+ case "$input" in
258
+ yes)
259
+ overrides+=("GITBASH_CREATE_NO_ISSUE_PARSING=\"no\"")
260
+ echo " → Will enable parsing locally"
261
+ ;;
262
+ no)
263
+ overrides+=("GITBASH_CREATE_NO_ISSUE_PARSING=\"yes\"")
264
+ echo " → Will disable parsing locally"
265
+ ;;
266
+ *)
267
+ echo " → Invalid value, keeping global setting"
268
+ ;;
269
+ esac
270
+ else
271
+ echo " → Keeping global setting"
272
+ fi
273
+ echo
274
+
275
+ # Issue fallback
276
+ local current_issue_fallback="${GITBASH_CREATE_ISSUE_PARSING_FALLBACK:-NOISSUE}"
277
+ echo "4. Fallback prefix when no issue number is provided"
278
+ echo " Current (global): $current_issue_fallback"
279
+ read -re -p " Local override: " input
280
+ if [[ -n "$input" && "$input" != "-" ]]; then
281
+ overrides+=("GITBASH_CREATE_ISSUE_PARSING_FALLBACK=\"$input\"")
282
+ echo " → Will use '$input' locally"
283
+ else
284
+ echo " → Keeping global setting"
285
+ fi
286
+ echo
287
+
288
+ # Theme
289
+ local current_theme="${GITBASH_THEME:-auto}"
290
+ echo "5. Theme for delta/bat (auto/dark/light)"
291
+ echo " Current (global): $current_theme"
292
+ read -re -p " Local override: " input
293
+ if [[ -n "$input" && "$input" != "-" ]]; then
294
+ case "$input" in
295
+ auto|dark|light)
296
+ overrides+=("GITBASH_THEME=\"$input\"")
297
+ echo " → Will use '$input' locally"
298
+ ;;
299
+ *)
300
+ echo " → Invalid value, keeping global setting"
301
+ ;;
302
+ esac
303
+ else
304
+ echo " → Keeping global setting"
305
+ fi
306
+ echo
307
+
308
+ # Stale months
309
+ local current_stale_months="${GITBASH_STALE_MONTHS:-3}"
310
+ echo "6. Stale branch threshold in months"
311
+ echo " Current (global): $current_stale_months"
312
+ read -re -p " Local override: " input
313
+ if [[ -n "$input" && "$input" != "-" ]]; then
314
+ if [[ "$input" =~ ^[0-9]+$ ]] && [[ "$input" -ge 1 ]]; then
315
+ overrides+=("GITBASH_STALE_MONTHS=\"$input\"")
316
+ echo " → Will use '$input' locally"
317
+ else
318
+ echo " → Invalid value, keeping global setting"
319
+ fi
320
+ else
321
+ echo " → Keeping global setting"
322
+ fi
323
+ echo
324
+
325
+ # Cleanup days
326
+ local current_cleanup_days="${GITBASH_CLEANUP_DAYS:-7}"
327
+ echo "7. Cleanup threshold in days"
328
+ echo " Current (global): $current_cleanup_days"
329
+ read -re -p " Local override: " input
330
+ if [[ -n "$input" && "$input" != "-" ]]; then
331
+ if [[ "$input" =~ ^[0-9]+$ ]] && [[ "$input" -ge 1 ]]; then
332
+ overrides+=("GITBASH_CLEANUP_DAYS=\"$input\"")
333
+ echo " → Will use '$input' locally"
334
+ else
335
+ echo " → Invalid value, keeping global setting"
336
+ fi
337
+ else
338
+ echo " → Keeping global setting"
339
+ fi
340
+ echo
341
+
342
+ # Check if any overrides were set
343
+ if [[ ${#overrides[@]} -eq 0 ]]; then
344
+ echo "No local overrides configured."
345
+ return 0
346
+ fi
347
+
348
+ # Write local config file
349
+ {
350
+ echo "# Local gitbash configuration overrides for this repository"
351
+ echo "# Generated by 'gitbash --config-local'"
352
+ echo "# These settings override the global ~/.gitbashrc"
353
+ echo
354
+ for override in "${overrides[@]}"; do
355
+ echo "$override"
356
+ done
357
+ } > "$local_config"
358
+
359
+ echo "Saved local configuration to $local_config"
360
+ }
361
+
174
362
  # Check and offer to install dependencies
175
363
  check_dependencies() {
176
364
  local missing_required=()
@@ -241,7 +429,7 @@ check_dependencies() {
241
429
  # Offer to install missing dependencies
242
430
  echo
243
431
  local install_deps
244
- read -e -p "Install missing dependencies with Homebrew? (Y/n): " install_deps
432
+ read -re -p "Install missing dependencies with Homebrew? (Y/n): " install_deps
245
433
  case "$install_deps" in
246
434
  [nN][oO]|[nN])
247
435
  echo "Skipped dependency installation."
@@ -296,7 +484,7 @@ check_shell_integration() {
296
484
  echo
297
485
  echo "Shell integration not found in $shell_rc"
298
486
  local add_init
299
- read -e -p "Add 'eval \"\$(gitbash --init)\"' to $shell_rc? (Y/n): " add_init
487
+ read -re -p "Add 'eval \"\$(gitbash --init)\"' to $shell_rc? (Y/n): " add_init
300
488
  case "$add_init" in
301
489
  [nN][oO]|[nN])
302
490
  echo "Skipped shell integration."
@@ -358,6 +546,7 @@ Usage:
358
546
  gitbash --help
359
547
  gitbash --init
360
548
  gitbash --config
549
+ gitbash --config-local
361
550
 
362
551
  Commands:
363
552
  branch Interactive menu for branch operations
@@ -376,10 +565,11 @@ Commands:
376
565
  update Merge latest main/master into current branch
377
566
 
378
567
  Options:
379
- -h, --help Show this help message
380
- -v, --version Show version number
381
- --init Print shell initialization code (for sourcing)
382
- --config Configure gitbash and save to ~/.gitbashrc
568
+ -h, --help Show this help message
569
+ -v, --version Show version number
570
+ --init Print shell initialization code (for sourcing)
571
+ --config Configure gitbash and save to ~/.gitbashrc
572
+ --config-local Configure local overrides for current repository
383
573
 
384
574
  Examples:
385
575
  gitbash commit fix bug -p # Commit and push
@@ -438,6 +628,10 @@ main() {
438
628
  configure_gitbash
439
629
  exit 0
440
630
  ;;
631
+ --config-local)
632
+ configure_local_gitbash
633
+ exit 0
634
+ ;;
441
635
  *)
442
636
  local cmd="$1"
443
637
  shift
@@ -2,13 +2,24 @@
2
2
  # shellcheck disable=SC2155
3
3
  # Common utilities for gitbash commands - compatible with bash and zsh
4
4
 
5
- # Load config file if it exists
5
+ # Load config files if they exist
6
+ # Global config first, then local repo config (which can override global)
6
7
  CONFIG_FILE="$HOME/.gitbashrc"
8
+ LOCAL_CONFIG_FILE=".gitbashrc"
9
+
7
10
  if [[ -f "$CONFIG_FILE" ]]; then
8
11
  # shellcheck disable=SC1090
9
12
  source "$CONFIG_FILE"
10
13
  fi
11
14
 
15
+ # Source local config from repo root if present (overrides global)
16
+ _repo_root=$(git rev-parse --show-toplevel 2>/dev/null)
17
+ if [[ -n "$_repo_root" && -f "$_repo_root/$LOCAL_CONFIG_FILE" ]]; then
18
+ # shellcheck disable=SC1090
19
+ source "$_repo_root/$LOCAL_CONFIG_FILE"
20
+ fi
21
+ unset _repo_root
22
+
12
23
  # Color codes for consistent output
13
24
  COLOR_RED='\033[0;31m'
14
25
  COLOR_GREEN='\033[0;32m'
package/commands/pr.sh CHANGED
@@ -1,4 +1,5 @@
1
1
  ## pr opens the current pr, if in repo
2
+ # shellcheck shell=bash
2
3
  pr() {
3
4
  local should_push=false
4
5
 
@@ -87,6 +88,7 @@ EOF
87
88
  source "$SOURCE_DIR/_utils.sh"
88
89
  fi
89
90
 
91
+ local commit_answer
90
92
  prompt_read "Would you like to commit them first? (Y/n): " commit_answer
91
93
  case "$commit_answer" in
92
94
  [nN][oO]|[nN])
@@ -94,24 +96,33 @@ EOF
94
96
  ;;
95
97
  *)
96
98
  # Run status command for interactive staging and committing
97
- gitbash status
98
- if [[ $? -ne 0 ]]; then
99
+ local local_before
100
+ local local_after
101
+ local_before=$(git rev-parse --verify HEAD 2>/dev/null || true)
102
+ if ! gitbash status; then
99
103
  echo "Commit cancelled or failed. Aborting PR creation."
100
104
  return 1
101
105
  fi
102
-
103
- # If -p wasn't specified, offer to push the fresh commit
104
- if [[ "$should_push" != true ]]; then
105
- echo ""
106
- prompt_read "Push the fresh commit to origin? (Y/n): " push_answer
107
- case "$push_answer" in
108
- [nN][oO]|[nN])
109
- echo "Continuing without pushing..."
110
- ;;
111
- *)
112
- should_push=true
113
- ;;
114
- esac
106
+ local_after=$(git rev-parse --verify HEAD 2>/dev/null || true)
107
+
108
+ # Only offer to push if a new commit was actually created
109
+ if [[ "$local_after" != "$local_before" ]]; then
110
+ # If -p wasn't specified, offer to push the fresh commit
111
+ if [[ "$should_push" != true ]]; then
112
+ local push_answer
113
+ echo ""
114
+ prompt_read "Push the fresh commit to origin? (Y/n): " push_answer
115
+ case "$push_answer" in
116
+ [nN][oO]|[nN])
117
+ echo "Continuing without pushing..."
118
+ ;;
119
+ *)
120
+ should_push=true
121
+ ;;
122
+ esac
123
+ fi
124
+ else
125
+ echo "No new commit was created. Continuing without pushing..."
115
126
  fi
116
127
  ;;
117
128
  esac
@@ -138,15 +149,16 @@ EOF
138
149
  if [[ "$should_push" == true ]]; then
139
150
  # Check if remote has updates and pull first
140
151
  git fetch origin "$branch" 2>/dev/null
141
- local local_commit=$(git rev-parse HEAD)
142
- local remote_commit=$(git rev-parse "origin/$branch" 2>/dev/null)
152
+ local local_commit
153
+ local remote_commit
154
+ local_commit=$(git rev-parse HEAD)
155
+ remote_commit=$(git rev-parse "origin/$branch" 2>/dev/null)
143
156
 
144
157
  if [[ -n "$remote_commit" && "$local_commit" != "$remote_commit" ]]; then
145
158
  # Check if we're behind the remote
146
159
  if git merge-base --is-ancestor "$local_commit" "$remote_commit" 2>/dev/null; then
147
160
  echo "Remote has updates. Pulling first..."
148
- git pull --rebase origin "$branch"
149
- if [[ $? -ne 0 ]]; then
161
+ if ! git pull --rebase origin "$branch"; then
150
162
  echo "⚠ Failed to pull remote changes. Please resolve conflicts and try again."
151
163
  return 1
152
164
  fi
@@ -155,7 +167,7 @@ EOF
155
167
  # Branches have diverged
156
168
  echo "Remote has diverged. Pulling with rebase..."
157
169
  git pull --rebase origin "$branch"
158
- if [[ $? -ne 0 ]]; then
170
+ if ! git pull --rebase origin "$branch"; then
159
171
  echo "⚠ Failed to pull remote changes. Please resolve conflicts and try again."
160
172
  return 1
161
173
  fi
@@ -164,8 +176,7 @@ EOF
164
176
  fi
165
177
 
166
178
  echo "Pushing '$branch' to origin..."
167
- git push origin "$branch"
168
- if [[ $? -eq 0 ]]; then
179
+ if git push origin "$branch"; then
169
180
  echo "✓ Successfully pushed '$branch' to origin."
170
181
  else
171
182
  echo "⚠ Failed to push '$branch' to origin."
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gitbash",
3
- "version": "1.6.6",
3
+ "version": "1.7.0",
4
4
  "description": "Opinionated git utilities for bash with fzf-powered menus",
5
5
  "author": "jaggli",
6
6
  "license": "MIT",