gitbash 2.2.0 → 2.2.2

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
@@ -46,32 +46,20 @@ echo 'eval "$(gitbash --init)"' >> ~/.zshrc
46
46
 
47
47
  ### Windows
48
48
 
49
- In Git Bash (part of [Git for Windows](https://gitforwindows.org)); in WSL, follow the Linux steps:
49
+ Needs [Git for Windows](https://gitforwindows.org). In PowerShell or Git Bash; in WSL, follow the Linux steps:
50
50
 
51
- ```bash
51
+ ```powershell
52
52
  npm i -g gitbash
53
53
  winget install junegunn.fzf dandavison.delta sharkdp.bat # needs fzf >= 0.54
54
54
  gitbash --config
55
55
  ```
56
56
 
57
- Shell integration for Git Bash:
58
-
59
- ```bash
60
- echo 'eval "$(gitbash --init)"' >> ~/.bashrc
61
- ```
62
-
63
- Shell integration for PowerShell: create the functions in Git Bash, then load them in your profile in PowerShell:
64
-
65
- ```bash
66
- gitbash --init --shell=pwsh > ~/gitbash.ps1 # switch is a PowerShell keyword: use gitbash switch
67
- ```
57
+ `gitbash --config` also sets up the shell integration: it offers to load the gitbash functions in your PowerShell profile (and to allow local scripts, which Windows PowerShell blocks by default) and in `~/.bashrc` for Git Bash. Open a new window afterwards. `switch` is a PowerShell keyword: use `gitbash switch` there.
68
58
 
69
- This creates your PowerShell profile if needed, loads `gitbash.ps1` from it in every new window, and allows local scripts to run (Windows PowerShell 5.1 blocks them by default):
59
+ To set it up by hand, add this line to your PowerShell profile (`notepad $PROFILE`):
70
60
 
71
61
  ```powershell
72
- if (!(Test-Path $PROFILE)) { New-Item -Force $PROFILE }
73
- Add-Content $PROFILE '. ~/gitbash.ps1'
74
- Set-ExecutionPolicy -Scope CurrentUser RemoteSigned # Windows PowerShell 5.1 only
62
+ gitbash --init --shell=pwsh | Out-String | Invoke-Expression
75
63
  ```
76
64
 
77
65
  ### Without npm
@@ -84,7 +72,7 @@ curl -fsSL https://raw.githubusercontent.com/jaggli/gitbash/main/install.sh | sh
84
72
  ```
85
73
 
86
74
  ```powershell
87
- # Windows PowerShell (needs Git for Windows)
75
+ # Windows PowerShell (needs Git for Windows; prints the line for your $PROFILE)
88
76
  irm https://raw.githubusercontent.com/jaggli/gitbash/main/install.ps1 | iex
89
77
  ```
90
78
 
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")"
@@ -359,8 +361,60 @@ check_dependencies() {
359
361
  }
360
362
 
361
363
  # Offer to add the shell integration to the rc file of the user's shell
364
+ # Line that loads the PowerShell functions, in $PROFILE
365
+ PWSH_INIT_LINE='gitbash --init --shell=pwsh | Out-String | Invoke-Expression'
366
+
367
+ # Offer to load the functions in the profiles of Windows PowerShell (powershell.exe)
368
+ # and PowerShell 7 (pwsh.exe), and to allow local scripts if needed.
369
+ # PowerShell edits its own profile: it may be UTF-16, which bash can't append to.
370
+ check_pwsh_integration() {
371
+ local exe info profile has policy found=false
372
+ # Prints "<profile>|<True if it loads gitbash>|<execution policy>" (no double
373
+ # quotes in PowerShell commands: they don't survive the Windows command line)
374
+ local query="\$p = \$PROFILE; \$has = (Test-Path -LiteralPath \$p) -and [bool](Select-String -Quiet -SimpleMatch -Pattern 'gitbash --init' -LiteralPath \$p); Write-Output (\$p + '|' + \$has + '|' + (Get-ExecutionPolicy))"
375
+ for exe in powershell.exe pwsh.exe; do
376
+ command -v "$exe" >/dev/null 2>&1 || continue
377
+ info=$("$exe" -NoProfile -NonInteractive -Command "$query" 2>/dev/null | tr -d '\r' | tail -n 1)
378
+ IFS='|' read -r profile has policy <<< "$info"
379
+ [[ -n "$profile" ]] || continue
380
+ found=true
381
+
382
+ echo
383
+ if [[ "$has" == "True" ]]; then
384
+ print_info "PowerShell integration already configured in $profile"
385
+ elif gb_confirm "Load the gitbash functions in PowerShell ($profile)?" y; then
386
+ if "$exe" -NoProfile -NonInteractive -Command \
387
+ "\$p = \$PROFILE; if (!(Test-Path -LiteralPath \$p)) { New-Item -Force -Path \$p | Out-Null }; Add-Content -LiteralPath \$p '$PWSH_INIT_LINE'"; then
388
+ print_success "Added to $profile. Open a new PowerShell window to use it."
389
+ else
390
+ print_error "Could not change $profile. Add this line yourself: $PWSH_INIT_LINE"
391
+ fi
392
+ fi
393
+
394
+ # Restricted (the default of Windows PowerShell) and AllSigned block the profile
395
+ case "$policy" in
396
+ Restricted|AllSigned|Undefined)
397
+ if gb_confirm "PowerShell blocks scripts, including your profile ($policy). Allow local scripts (execution policy RemoteSigned)?" y; then
398
+ if "$exe" -NoProfile -NonInteractive -Command 'Set-ExecutionPolicy -Scope CurrentUser RemoteSigned -Force'; then
399
+ print_success "Local scripts allowed."
400
+ else
401
+ print_error "Could not change the execution policy (it may be set by your organization)."
402
+ fi
403
+ fi
404
+ ;;
405
+ esac
406
+ done
407
+ if [[ "$found" == false ]]; then
408
+ echo
409
+ print_info "For PowerShell, add this line to your \$PROFILE:"
410
+ echo " $PWSH_INIT_LINE"
411
+ fi
412
+ }
413
+
362
414
  check_shell_integration() {
363
415
  local shell_name shell_rc
416
+ # Can't tell PowerShell from Git Bash here: offer both
417
+ gb_is_windows && check_pwsh_integration
364
418
  shell_name=$(basename "${SHELL:-}")
365
419
  case "$shell_name" in
366
420
  zsh) shell_rc="$HOME/.zshrc" ;;
@@ -372,8 +426,10 @@ check_shell_integration() {
372
426
  fi
373
427
  ;;
374
428
  *)
375
- echo
376
- print_info "Shell '$shell_name' is not supported for integration. Use 'gitbash <command>' or aliases."
429
+ if ! gb_is_windows; then
430
+ echo
431
+ print_info "Shell '$shell_name' is not supported for integration. Use 'gitbash <command>' or aliases."
432
+ fi
377
433
  return 0
378
434
  ;;
379
435
  esac
@@ -540,9 +596,8 @@ show_init_pwsh() {
540
596
  gb_is_windows && command -v cygpath >/dev/null 2>&1 && bin=$(cygpath -m "$bin")
541
597
  bash_q=$(pwsh_quote "$(pwsh_bash)")
542
598
  bin_q=$(pwsh_quote "$bin")
543
- echo "# gitbash shell integration for PowerShell - save it and dot-source it in your \$PROFILE:"
544
- echo "# gitbash --init --shell=pwsh${prefix:+ --prefix=$prefix} > ~/gitbash.ps1"
545
- echo "# . ~/gitbash.ps1"
599
+ echo "# gitbash shell integration for PowerShell - add to your \$PROFILE:"
600
+ echo "# gitbash --init --shell=pwsh${prefix:+ --prefix=$prefix} | Out-String | Invoke-Expression"
546
601
  echo "function gitbash { & $bash_q $bin_q @args }"
547
602
  for cmd in "${COMMANDS[@]}"; do
548
603
  # 'switch' is a PowerShell keyword: a function by that name can't be called
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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gitbash",
3
- "version": "2.2.0",
3
+ "version": "2.2.2",
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/",