gitbash 2.1.0 → 2.2.1
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 +64 -36
- package/bin/gitbash +98 -10
- package/bin/gitbash.js +97 -0
- package/commands/_self_update.sh +4 -0
- package/commands/_utils.sh +36 -3
- package/commands/pr.sh +1 -1
- package/commands/repo.sh +1 -1
- package/docs/CONTRIBUTING.md +1 -1
- package/package.json +4 -3
package/README.md
CHANGED
|
@@ -6,69 +6,97 @@ Pure bash, zero-dependency git utilities. Reduce repetitive typing and superchar
|
|
|
6
6
|
|
|
7
7
|
## Installation
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Needs git >= 2.23 and bash >= 3.2. fzf (menus), delta (diffs) and bat (previews) are optional but recommended.
|
|
10
|
+
|
|
11
|
+
### macOS
|
|
10
12
|
|
|
11
13
|
```bash
|
|
12
|
-
npm i -g gitbash
|
|
14
|
+
npm i -g gitbash
|
|
15
|
+
brew install fzf git-delta bat
|
|
16
|
+
gitbash --config
|
|
13
17
|
```
|
|
14
18
|
|
|
15
|
-
|
|
19
|
+
Shell integration (lets you type `commit` instead of `gitbash commit`):
|
|
16
20
|
|
|
17
21
|
```bash
|
|
18
|
-
|
|
19
|
-
|
|
22
|
+
## for bash
|
|
23
|
+
echo 'eval "$(gitbash --init)"' >> ~/.bashrc
|
|
20
24
|
|
|
21
|
-
|
|
22
|
-
|
|
25
|
+
## for zsh
|
|
26
|
+
echo 'eval "$(gitbash --init)"' >> ~/.zshrc
|
|
23
27
|
```
|
|
24
28
|
|
|
25
|
-
|
|
29
|
+
### Linux
|
|
26
30
|
|
|
27
31
|
```bash
|
|
28
|
-
|
|
29
|
-
|
|
32
|
+
npm i -g gitbash
|
|
33
|
+
sudo apt install fzf git-delta bat # Debian/Ubuntu, needs fzf >= 0.36
|
|
34
|
+
gitbash --config
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Shell integration:
|
|
30
38
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
39
|
+
```bash
|
|
40
|
+
## for bash
|
|
41
|
+
echo 'eval "$(gitbash --init)"' >> ~/.bashrc
|
|
42
|
+
|
|
43
|
+
## for zsh
|
|
44
|
+
echo 'eval "$(gitbash --init)"' >> ~/.zshrc
|
|
34
45
|
```
|
|
35
46
|
|
|
36
|
-
|
|
47
|
+
### Windows
|
|
37
48
|
|
|
38
|
-
|
|
49
|
+
Needs [Git for Windows](https://gitforwindows.org). In PowerShell or Git Bash; in WSL, follow the Linux steps:
|
|
39
50
|
|
|
40
|
-
```
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
gitbash --
|
|
44
|
-
gitbash --init # Print shell functions (see Shell integration)
|
|
45
|
-
gitbash --config # Interactive configuration wizard
|
|
46
|
-
gitbash --config-local # Configure overrides for the current repository (committed)
|
|
47
|
-
gitbash --config-user # Configure personal overrides for the current repository
|
|
51
|
+
```powershell
|
|
52
|
+
npm i -g gitbash
|
|
53
|
+
winget install junegunn.fzf dandavison.delta sharkdp.bat # needs fzf >= 0.54
|
|
54
|
+
gitbash --config
|
|
48
55
|
```
|
|
49
56
|
|
|
50
|
-
|
|
57
|
+
Shell integration for PowerShell. This creates your profile if needed, loads the functions in every new window, and allows local scripts to run (Windows PowerShell 5.1 blocks them by default):
|
|
51
58
|
|
|
52
|
-
```
|
|
53
|
-
|
|
54
|
-
|
|
59
|
+
```powershell
|
|
60
|
+
if (!(Test-Path $PROFILE)) { New-Item -Force $PROFILE }
|
|
61
|
+
Add-Content $PROFILE 'gitbash --init --shell=pwsh | Out-String | Invoke-Expression' # switch is a keyword: use gitbash switch
|
|
62
|
+
Set-ExecutionPolicy -Scope CurrentUser RemoteSigned # Windows PowerShell 5.1 only
|
|
63
|
+
```
|
|
55
64
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
65
|
+
Shell integration for Git Bash:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
echo 'eval "$(gitbash --init)"' >> ~/.bashrc
|
|
60
69
|
```
|
|
61
70
|
|
|
62
|
-
###
|
|
71
|
+
### Without npm
|
|
63
72
|
|
|
64
|
-
|
|
73
|
+
Installation by script on machines without npm available
|
|
65
74
|
|
|
66
75
|
```bash
|
|
67
|
-
|
|
68
|
-
|
|
76
|
+
# macOS, Linux, Git Bash (or: wget -qO- ... | sh)
|
|
77
|
+
curl -fsSL https://raw.githubusercontent.com/jaggli/gitbash/main/install.sh | sh
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
```powershell
|
|
81
|
+
# Windows PowerShell (needs Git for Windows; prints the line for your $PROFILE)
|
|
82
|
+
irm https://raw.githubusercontent.com/jaggli/gitbash/main/install.ps1 | iex
|
|
69
83
|
```
|
|
70
84
|
|
|
71
|
-
|
|
85
|
+
It installs to `~/.local/share/gitbash` and links `~/.local/bin/gitbash` (add that folder to your PATH if the script says so); delete both to uninstall. Set `GITBASH_VERSION` for a specific version, and `GITBASH_INSTALL_DIR` / `GITBASH_BIN_DIR` for other locations.
|
|
86
|
+
|
|
87
|
+
## Options
|
|
88
|
+
|
|
89
|
+
| Option | Description |
|
|
90
|
+
| --- | --- |
|
|
91
|
+
| `-h`, `--help` | Show the help |
|
|
92
|
+
| `-v`, `--version` | Show the version |
|
|
93
|
+
| `--update` | Update to the latest release (npm, pnpm or install script) |
|
|
94
|
+
| `--init` | Print shell functions to call commands without the `gitbash` prefix |
|
|
95
|
+
| `--init --prefix=gb-` | Prefixed functions: `gb-commit`, `gb-switch`, ... (avoids shadowing e.g. `/usr/bin/pr`) |
|
|
96
|
+
| `--init --shell=pwsh` | PowerShell functions instead of bash/zsh |
|
|
97
|
+
| `--config` | Configuration wizard (`~/.gitbashrc`); offers to install dependencies and the shell integration |
|
|
98
|
+
| `--config-local` | Overrides for the current repository (`.gitbashrc`, committed) |
|
|
99
|
+
| `--config-user` | Personal overrides for the current repository (`.gitbashrc-user`, not committed) |
|
|
72
100
|
|
|
73
101
|
## Commands
|
|
74
102
|
|
package/bin/gitbash
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
|
|
4
4
|
# Resolve symlinks to get the actual script location
|
|
5
5
|
SOURCE="${BASH_SOURCE[0]}"
|
|
6
|
+
# Started from Windows with C:\...\bin\gitbash: dirname needs forward slashes
|
|
7
|
+
[[ "$OSTYPE" == msys* || "$OSTYPE" == cygwin* ]] && SOURCE="${SOURCE//\\//}"
|
|
6
8
|
while [[ -L "$SOURCE" ]]; do
|
|
7
9
|
DIR="$(cd -P "$(dirname "$SOURCE")" && pwd)"
|
|
8
10
|
SOURCE="$(readlink "$SOURCE")"
|
|
@@ -299,7 +301,17 @@ exclude_user_config() {
|
|
|
299
301
|
print_info "Added .gitbashrc-user to $exclude"
|
|
300
302
|
}
|
|
301
303
|
|
|
302
|
-
#
|
|
304
|
+
# winget package id of a dependency
|
|
305
|
+
winget_id() {
|
|
306
|
+
case "$1" in
|
|
307
|
+
fzf) echo "junegunn.fzf" ;;
|
|
308
|
+
git-delta) echo "dandavison.delta" ;;
|
|
309
|
+
bat) echo "sharkdp.bat" ;;
|
|
310
|
+
esac
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
# Report missing optional dependencies and offer to install them with
|
|
314
|
+
# Homebrew, or winget on Windows
|
|
303
315
|
check_dependencies() {
|
|
304
316
|
local missing=() dep
|
|
305
317
|
command -v fzf >/dev/null 2>&1 || missing+=("fzf")
|
|
@@ -316,24 +328,47 @@ check_dependencies() {
|
|
|
316
328
|
|
|
317
329
|
echo "Missing optional dependencies: ${missing[*]}"
|
|
318
330
|
echo " fzf (>= $GB_FZF_MIN_VERSION) - interactive menus, git-delta - diff highlighting, bat - file previews"
|
|
319
|
-
|
|
320
|
-
|
|
331
|
+
local -a install
|
|
332
|
+
local manager
|
|
333
|
+
if gb_is_windows; then
|
|
334
|
+
manager="winget"
|
|
335
|
+
install=(winget install --exact --id)
|
|
336
|
+
else
|
|
337
|
+
manager="Homebrew"
|
|
338
|
+
install=(brew install)
|
|
339
|
+
fi
|
|
340
|
+
if ! command -v "${install[0]}" >/dev/null 2>&1; then
|
|
341
|
+
if gb_is_windows; then
|
|
342
|
+
echo "Install them with a package manager, e.g.: scoop install ${missing[*]/git-delta/delta}"
|
|
343
|
+
else
|
|
344
|
+
echo "Install them with your package manager, e.g.: sudo apt install ${missing[*]}"
|
|
345
|
+
fi
|
|
321
346
|
return 0
|
|
322
347
|
fi
|
|
323
|
-
|
|
348
|
+
local package
|
|
349
|
+
if gb_confirm "Install them with $manager?" y; then
|
|
324
350
|
for dep in "${missing[@]}"; do
|
|
325
|
-
|
|
351
|
+
package="$dep"
|
|
352
|
+
gb_is_windows && package=$(winget_id "$dep")
|
|
353
|
+
if "${install[@]}" "$package"; then
|
|
326
354
|
print_success "$dep installed"
|
|
327
355
|
else
|
|
328
356
|
print_error "Failed to install $dep"
|
|
329
357
|
fi
|
|
330
358
|
done
|
|
359
|
+
gb_is_windows && print_info "Open a new terminal to pick up the installed programs."
|
|
331
360
|
fi
|
|
332
361
|
}
|
|
333
362
|
|
|
334
363
|
# Offer to add the shell integration to the rc file of the user's shell
|
|
335
364
|
check_shell_integration() {
|
|
336
365
|
local shell_name shell_rc
|
|
366
|
+
# Can't tell PowerShell from Git Bash here: always show the PowerShell line
|
|
367
|
+
if gb_is_windows; then
|
|
368
|
+
echo
|
|
369
|
+
print_info "For PowerShell, add this line to your \$PROFILE:"
|
|
370
|
+
echo " gitbash --init --shell=pwsh | Out-String | Invoke-Expression"
|
|
371
|
+
fi
|
|
337
372
|
shell_name=$(basename "${SHELL:-}")
|
|
338
373
|
case "$shell_name" in
|
|
339
374
|
zsh) shell_rc="$HOME/.zshrc" ;;
|
|
@@ -345,8 +380,10 @@ check_shell_integration() {
|
|
|
345
380
|
fi
|
|
346
381
|
;;
|
|
347
382
|
*)
|
|
348
|
-
|
|
349
|
-
|
|
383
|
+
if ! gb_is_windows; then
|
|
384
|
+
echo
|
|
385
|
+
print_info "Shell '$shell_name' is not supported for integration. Use 'gitbash <command>' or aliases."
|
|
386
|
+
fi
|
|
350
387
|
return 0
|
|
351
388
|
;;
|
|
352
389
|
esac
|
|
@@ -402,7 +439,7 @@ show_help() {
|
|
|
402
439
|
Usage:
|
|
403
440
|
gitbash <command> [args...]
|
|
404
441
|
gitbash --help | --version | --update
|
|
405
|
-
gitbash --init [--prefix=PREFIX]
|
|
442
|
+
gitbash --init [--prefix=PREFIX] [--shell=pwsh]
|
|
406
443
|
gitbash --config | --config-local | --config-user
|
|
407
444
|
|
|
408
445
|
Commands:
|
|
@@ -428,7 +465,8 @@ Options:
|
|
|
428
465
|
-v, --version Show version number
|
|
429
466
|
--update Update gitbash to the latest release
|
|
430
467
|
--init Print shell functions for calling commands directly
|
|
431
|
-
(--prefix=gb- creates gb-commit, gb-switch,
|
|
468
|
+
(--prefix=gb- creates gb-commit, gb-switch, ...;
|
|
469
|
+
--shell=pwsh prints PowerShell functions)
|
|
432
470
|
--config Configure gitbash and save to ~/.gitbashrc
|
|
433
471
|
--config-local Configure overrides for this repository (.gitbashrc, committed)
|
|
434
472
|
--config-user Configure personal overrides for this repository (.gitbashrc-user)
|
|
@@ -441,6 +479,7 @@ Examples:
|
|
|
441
479
|
Shell Integration:
|
|
442
480
|
Add to your .zshrc or .bashrc:
|
|
443
481
|
eval "\$(gitbash --init)"
|
|
482
|
+
PowerShell: see 'gitbash --init --shell=pwsh'
|
|
444
483
|
|
|
445
484
|
This enables calling commands directly:
|
|
446
485
|
commit fix bug -p
|
|
@@ -456,10 +495,12 @@ EOF
|
|
|
456
495
|
# Print wrapper functions for the interactive shell. Commands still run in
|
|
457
496
|
# their own bash process, so nothing leaks into the user's shell.
|
|
458
497
|
show_init() {
|
|
459
|
-
local prefix="" arg cmd bin_quoted
|
|
498
|
+
local prefix="" shell="sh" arg cmd bin_quoted
|
|
460
499
|
for arg in "$@"; do
|
|
461
500
|
case "$arg" in
|
|
462
501
|
--prefix=*) prefix="${arg#--prefix=}" ;;
|
|
502
|
+
--shell=bash|--shell=zsh|--shell=sh) shell="sh" ;;
|
|
503
|
+
--shell=pwsh|--shell=powershell) shell="pwsh" ;;
|
|
463
504
|
*) print_error "Unknown option for --init: $arg"; return 1 ;;
|
|
464
505
|
esac
|
|
465
506
|
done
|
|
@@ -467,6 +508,10 @@ show_init() {
|
|
|
467
508
|
print_error "Invalid prefix '$prefix' (use letters, digits, '-' or '_')."
|
|
468
509
|
return 1
|
|
469
510
|
fi
|
|
511
|
+
if [[ "$shell" == "pwsh" ]]; then
|
|
512
|
+
show_init_pwsh "$prefix"
|
|
513
|
+
return
|
|
514
|
+
fi
|
|
470
515
|
printf -v bin_quoted '%q' "$GITBASH_BIN"
|
|
471
516
|
echo "# gitbash shell integration - add to your .zshrc or .bashrc:"
|
|
472
517
|
echo "# eval \"\$(gitbash --init${prefix:+ --prefix=$prefix})\""
|
|
@@ -475,6 +520,49 @@ show_init() {
|
|
|
475
520
|
done
|
|
476
521
|
}
|
|
477
522
|
|
|
523
|
+
# Single-quoted PowerShell string
|
|
524
|
+
pwsh_quote() {
|
|
525
|
+
local q="'"
|
|
526
|
+
printf "'%s'" "${1//$q/$q$q}"
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
# The bash that PowerShell functions run gitbash with. On Windows, Git's
|
|
530
|
+
# bin\bash.exe: it puts git and the Unix tools on PATH, unlike usr\bin\bash.exe.
|
|
531
|
+
pwsh_bash() {
|
|
532
|
+
local bash_path git_root
|
|
533
|
+
bash_path=$(command -v bash)
|
|
534
|
+
if gb_is_windows && command -v cygpath >/dev/null 2>&1; then
|
|
535
|
+
git_root=$(cygpath -w /)
|
|
536
|
+
git_root="${git_root%\\}"
|
|
537
|
+
if [[ -f "$git_root\\bin\\bash.exe" ]]; then
|
|
538
|
+
printf '%s\n' "$git_root\\bin\\bash.exe"
|
|
539
|
+
else
|
|
540
|
+
cygpath -w "$bash_path"
|
|
541
|
+
fi
|
|
542
|
+
else
|
|
543
|
+
echo "$bash_path"
|
|
544
|
+
fi
|
|
545
|
+
}
|
|
546
|
+
|
|
547
|
+
# Functions for PowerShell ($PROFILE), running gitbash with bash
|
|
548
|
+
show_init_pwsh() {
|
|
549
|
+
local prefix="$1" bash_q bin_q cmd bin="$GITBASH_BIN"
|
|
550
|
+
gb_is_windows && command -v cygpath >/dev/null 2>&1 && bin=$(cygpath -m "$bin")
|
|
551
|
+
bash_q=$(pwsh_quote "$(pwsh_bash)")
|
|
552
|
+
bin_q=$(pwsh_quote "$bin")
|
|
553
|
+
echo "# gitbash shell integration for PowerShell - add to your \$PROFILE:"
|
|
554
|
+
echo "# gitbash --init --shell=pwsh${prefix:+ --prefix=$prefix} | Out-String | Invoke-Expression"
|
|
555
|
+
echo "function gitbash { & $bash_q $bin_q @args }"
|
|
556
|
+
for cmd in "${COMMANDS[@]}"; do
|
|
557
|
+
# 'switch' is a PowerShell keyword: a function by that name can't be called
|
|
558
|
+
if [[ -z "$prefix" && "$cmd" == "switch" ]]; then
|
|
559
|
+
echo "# switch is a PowerShell keyword: use 'gitbash switch', or --prefix (e.g. gb-switch)"
|
|
560
|
+
continue
|
|
561
|
+
fi
|
|
562
|
+
echo "function ${prefix}${cmd} { & $bash_q $bin_q $cmd @args }"
|
|
563
|
+
done
|
|
564
|
+
}
|
|
565
|
+
|
|
478
566
|
# =============================================================================
|
|
479
567
|
# Main entry point
|
|
480
568
|
# =============================================================================
|
package/bin/gitbash.js
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// npm entry point: runs bin/gitbash with bash.
|
|
3
|
+
// On Windows, npm's own launchers would run the first bash on PATH, which is
|
|
4
|
+
// often WSL's (C:\Windows\System32\bash.exe): use Git for Windows' bash instead.
|
|
5
|
+
'use strict';
|
|
6
|
+
|
|
7
|
+
var childProcess = require('child_process');
|
|
8
|
+
var fs = require('fs');
|
|
9
|
+
var path = require('path');
|
|
10
|
+
|
|
11
|
+
// Forward slashes: bash's dirname doesn't split C:\...\bin\gitbash
|
|
12
|
+
var script = path.join(__dirname, 'gitbash').replace(/\\/g, '/');
|
|
13
|
+
|
|
14
|
+
function isFile(file) {
|
|
15
|
+
try {
|
|
16
|
+
return fs.statSync(file).isFile();
|
|
17
|
+
} catch (e) {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// <Git>\bin\bash.exe: it puts git and the Unix tools on PATH, unlike usr\bin\bash.exe
|
|
23
|
+
function bashIn(root) {
|
|
24
|
+
var bash = root && path.join(root, 'bin', 'bash.exe');
|
|
25
|
+
return bash && isFile(bash) ? bash : null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function gitForWindowsBash() {
|
|
29
|
+
var dirs = (process.env.PATH || '').split(path.delimiter);
|
|
30
|
+
var i, dir, bash;
|
|
31
|
+
// git.exe is in <Git>\cmd, <Git>\bin or <Git>\mingw64\bin
|
|
32
|
+
for (i = 0; i < dirs.length; i++) {
|
|
33
|
+
dir = dirs[i].replace(/^"|"$/g, '');
|
|
34
|
+
if (dir && isFile(path.join(dir, 'git.exe'))) {
|
|
35
|
+
bash = bashIn(path.dirname(dir)) || bashIn(path.dirname(path.dirname(dir)));
|
|
36
|
+
if (bash) return bash;
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
var keys = ['HKLM\\SOFTWARE\\GitForWindows', 'HKCU\\SOFTWARE\\GitForWindows'];
|
|
40
|
+
for (i = 0; i < keys.length; i++) {
|
|
41
|
+
var out = childProcess.spawnSync('reg', ['query', keys[i], '/v', 'InstallPath'], { encoding: 'utf8' });
|
|
42
|
+
var match = /InstallPath\s+REG_SZ\s+(.+)/.exec(out.stdout || '');
|
|
43
|
+
bash = match && bashIn(match[1].trim());
|
|
44
|
+
if (bash) return bash;
|
|
45
|
+
}
|
|
46
|
+
var roots = [
|
|
47
|
+
process.env.ProgramFiles && path.join(process.env.ProgramFiles, 'Git'),
|
|
48
|
+
process.env.LOCALAPPDATA && path.join(process.env.LOCALAPPDATA, 'Programs', 'Git')
|
|
49
|
+
];
|
|
50
|
+
for (i = 0; i < roots.length; i++) {
|
|
51
|
+
bash = bashIn(roots[i]);
|
|
52
|
+
if (bash) return bash;
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
var bash = 'bash';
|
|
58
|
+
if (process.platform === 'win32') {
|
|
59
|
+
bash = gitForWindowsBash();
|
|
60
|
+
if (!bash) {
|
|
61
|
+
process.stderr.write('gitbash needs Git for Windows. Install it with: winget install Git.Git\n');
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
var child = childProcess.spawn(bash, [script].concat(process.argv.slice(2)), { stdio: 'inherit' });
|
|
67
|
+
|
|
68
|
+
// Ctrl-C (SIGINT, SIGQUIT) reaches bash and fzf directly from the terminal: wait
|
|
69
|
+
// for them instead of exiting first. SIGTERM and SIGHUP are passed on.
|
|
70
|
+
var handlers = {};
|
|
71
|
+
['SIGINT', 'SIGQUIT', 'SIGTERM', 'SIGHUP'].forEach(function (signal) {
|
|
72
|
+
handlers[signal] = signal === 'SIGTERM' || signal === 'SIGHUP'
|
|
73
|
+
? function () { child.kill(signal); }
|
|
74
|
+
: function () {};
|
|
75
|
+
try {
|
|
76
|
+
process.on(signal, handlers[signal]);
|
|
77
|
+
} catch (e) {
|
|
78
|
+
// Not supported on this platform
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
child.on('error', function (err) {
|
|
83
|
+
process.stderr.write('gitbash: could not run ' + bash + ': ' + err.message + '\n');
|
|
84
|
+
process.exit(1);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
child.on('exit', function (code, signal) {
|
|
88
|
+
if (signal) {
|
|
89
|
+
// Exit the same way bash did
|
|
90
|
+
Object.keys(handlers).forEach(function (s) {
|
|
91
|
+
process.removeListener(s, handlers[s]);
|
|
92
|
+
});
|
|
93
|
+
process.kill(process.pid, signal);
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
process.exit(code === null ? 1 : code);
|
|
97
|
+
});
|
package/commands/_self_update.sh
CHANGED
|
@@ -18,6 +18,10 @@ _gb_global_package_dir() {
|
|
|
18
18
|
local root
|
|
19
19
|
root=$("$1" root -g 2>/dev/null) || return 1
|
|
20
20
|
[[ -n "$root" ]] || return 1
|
|
21
|
+
# Windows: C:\Users\...\npm\node_modules
|
|
22
|
+
if gb_is_windows && command -v cygpath >/dev/null 2>&1; then
|
|
23
|
+
root=$(cygpath -u "$root") || return 1
|
|
24
|
+
fi
|
|
21
25
|
(cd -P "$root/gitbash" 2>/dev/null && pwd)
|
|
22
26
|
}
|
|
23
27
|
|
package/commands/_utils.sh
CHANGED
|
@@ -9,7 +9,29 @@ if [[ -n "${_GB_UTILS_LOADED:-}" ]]; then
|
|
|
9
9
|
fi
|
|
10
10
|
_GB_UTILS_LOADED=1
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
# =============================================================================
|
|
13
|
+
# Platform
|
|
14
|
+
# =============================================================================
|
|
15
|
+
|
|
16
|
+
# Git Bash (MSYS2) or Cygwin on Windows
|
|
17
|
+
gb_is_windows() {
|
|
18
|
+
case "${OSTYPE:-}" in
|
|
19
|
+
msys*|cygwin*) return 0 ;;
|
|
20
|
+
esac
|
|
21
|
+
return 1
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
# Linux in WSL
|
|
25
|
+
_gb_is_wsl() {
|
|
26
|
+
[[ -n "${WSL_DISTRO_NAME:-}" || -n "${WSL_INTEROP:-}" ]]
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
# On Windows, fzf runs previews with bash and quotes {} for it since 0.54
|
|
30
|
+
if gb_is_windows; then
|
|
31
|
+
GB_FZF_MIN_VERSION="0.54.0"
|
|
32
|
+
else
|
|
33
|
+
GB_FZF_MIN_VERSION="0.36.0"
|
|
34
|
+
fi
|
|
13
35
|
|
|
14
36
|
# =============================================================================
|
|
15
37
|
# Output
|
|
@@ -286,7 +308,11 @@ _gb_version_ge() {
|
|
|
286
308
|
# Check that fzf is installed and recent enough
|
|
287
309
|
require_fzf() {
|
|
288
310
|
if ! command -v fzf >/dev/null 2>&1; then
|
|
289
|
-
|
|
311
|
+
if gb_is_windows; then
|
|
312
|
+
print_error "fzf is not installed. Install it with 'winget install junegunn.fzf'."
|
|
313
|
+
else
|
|
314
|
+
print_error "fzf is not installed. Install it with 'brew install fzf' (macOS) or 'sudo apt install fzf' (Debian/Ubuntu)."
|
|
315
|
+
fi
|
|
290
316
|
return 1
|
|
291
317
|
fi
|
|
292
318
|
local version
|
|
@@ -632,7 +658,14 @@ gb_web_url() {
|
|
|
632
658
|
# Open a URL in the browser, or print it if no opener is available
|
|
633
659
|
gb_open_url() {
|
|
634
660
|
local url="$1"
|
|
635
|
-
if command -v
|
|
661
|
+
if gb_is_windows && command -v rundll32 >/dev/null 2>&1; then
|
|
662
|
+
# Not cmd's start: it would need & and ^ in the URL escaped
|
|
663
|
+
rundll32 url.dll,FileProtocolHandler "$url"
|
|
664
|
+
elif _gb_is_wsl && command -v wslview >/dev/null 2>&1; then
|
|
665
|
+
wslview "$url"
|
|
666
|
+
elif _gb_is_wsl && command -v rundll32.exe >/dev/null 2>&1; then
|
|
667
|
+
rundll32.exe url.dll,FileProtocolHandler "$url"
|
|
668
|
+
elif command -v open >/dev/null 2>&1 && [[ "$(uname -s)" == "Darwin" ]]; then
|
|
636
669
|
open "$url"
|
|
637
670
|
elif command -v xdg-open >/dev/null 2>&1; then
|
|
638
671
|
xdg-open "$url" >/dev/null 2>&1
|
package/commands/pr.sh
CHANGED
|
@@ -59,7 +59,7 @@ Behavior:
|
|
|
59
59
|
Bitbucket <repo>/pull-requests/new?source=<branch>
|
|
60
60
|
Azure DevOps <repo>/pullrequestcreate?sourceRef=<branch>
|
|
61
61
|
- Works with SSH and HTTPS remotes; credentials in the remote URL are never used
|
|
62
|
-
- Opens the browser
|
|
62
|
+
- Opens the browser (macOS, Linux, WSL, Git Bash on Windows), otherwise prints the URL
|
|
63
63
|
|
|
64
64
|
Examples:
|
|
65
65
|
$ pr
|
package/commands/repo.sh
CHANGED
|
@@ -31,7 +31,7 @@ Behavior:
|
|
|
31
31
|
- Otherwise opens the URL derived from the remote
|
|
32
32
|
(GitHub, GitHub Enterprise, GitLab, Bitbucket, Azure DevOps)
|
|
33
33
|
- Works with SSH and HTTPS remotes; credentials in the remote URL are never used
|
|
34
|
-
- Opens the browser
|
|
34
|
+
- Opens the browser (macOS, Linux, WSL, Git Bash on Windows), otherwise prints the URL
|
|
35
35
|
|
|
36
36
|
Examples:
|
|
37
37
|
$ repo
|
package/docs/CONTRIBUTING.md
CHANGED
|
@@ -125,7 +125,7 @@ shellcheck -x bin/gitbash commands/*.sh
|
|
|
125
125
|
|
|
126
126
|
Tests live in `test/*.bats`. Each test gets its own temporary repository with a local bare remote (`test/helpers/setup.bash`). fzf is replaced by a stub that records its arguments and answers from a plan (`test/helpers/bin/fzf`); `test/fzf_real.bats` drives the real fzf in a pseudo-terminal. Add a test for every bug fix.
|
|
127
127
|
|
|
128
|
-
CI runs shellcheck and the tests on Ubuntu (bash 5)
|
|
128
|
+
CI runs shellcheck and the tests on Ubuntu (bash 5), macOS (bash 3.2 and 5) and Windows (Git Bash). Scripts must keep LF line endings (`.gitattributes` enforces it).
|
|
129
129
|
|
|
130
130
|
### Code style:
|
|
131
131
|
- Follow existing bash script conventions; scripts must work with bash 3.2
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gitbash",
|
|
3
|
-
"version": "2.1
|
|
3
|
+
"version": "2.2.1",
|
|
4
4
|
"description": "Opinionated git utilities for bash with fzf-powered menus",
|
|
5
5
|
"author": "jaggli",
|
|
6
6
|
"license": "MIT",
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"stash"
|
|
25
25
|
],
|
|
26
26
|
"bin": {
|
|
27
|
-
"gitbash": "bin/gitbash"
|
|
27
|
+
"gitbash": "bin/gitbash.js"
|
|
28
28
|
},
|
|
29
29
|
"files": [
|
|
30
30
|
"bin/",
|
|
@@ -35,7 +35,8 @@
|
|
|
35
35
|
],
|
|
36
36
|
"os": [
|
|
37
37
|
"darwin",
|
|
38
|
-
"linux"
|
|
38
|
+
"linux",
|
|
39
|
+
"win32"
|
|
39
40
|
],
|
|
40
41
|
"engines": {
|
|
41
42
|
"node": ">=14"
|