gitbash 2.2.2 → 3.0.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 +14 -12
- package/bin/gitbash +5 -2
- package/commands/_utils.sh +67 -31
- package/commands/branch.sh +8 -50
- package/commands/cleanstash.sh +14 -0
- package/commands/cleanup.sh +10 -5
- package/commands/commit.sh +1 -1
- package/commands/commits.sh +3 -1
- package/commands/create.sh +4 -2
- package/commands/pr.sh +1 -1
- package/commands/stale.sh +9 -3
- package/commands/stash.sh +18 -3
- package/commands/stashes.sh +8 -50
- package/commands/status.sh +5 -0
- package/commands/switch.sh +9 -0
- package/commands/unstash.sh +14 -0
- package/commands/update.sh +1 -1
- package/docs/CONTRIBUTING.md +10 -9
- package/docs/SECURITY.md +13 -3
- package/docs/workflows.md +1 -1
- package/package.json +6 -3
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# gitbash
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Git utilities written in pure bash: only git is required, fzf, delta and bat are optional. 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
|

|
|
6
6
|
|
|
@@ -76,7 +76,7 @@ curl -fsSL https://raw.githubusercontent.com/jaggli/gitbash/main/install.sh | sh
|
|
|
76
76
|
irm https://raw.githubusercontent.com/jaggli/gitbash/main/install.ps1 | iex
|
|
77
77
|
```
|
|
78
78
|
|
|
79
|
-
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.
|
|
79
|
+
It downloads the package published on npm, checks it against npm's sha512 checksum, and installs it 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.
|
|
80
80
|
|
|
81
81
|
## Options
|
|
82
82
|
|
|
@@ -94,6 +94,8 @@ It installs to `~/.local/share/gitbash` and links `~/.local/bin/gitbash` (add th
|
|
|
94
94
|
|
|
95
95
|
## Commands
|
|
96
96
|
|
|
97
|
+
`-y` / `--yes` answers every yes/no question with yes and is passed on to the commands a command runs (e.g. `pr -y` → `commit`). Deleting unmerged work or remote branches and force-pushing always ask. Options with a value accept `--days=14` and `--days 14`.
|
|
98
|
+
|
|
97
99
|
### branch
|
|
98
100
|
|
|
99
101
|
Interactive menu for branch operations (create/switch/update).
|
|
@@ -107,7 +109,7 @@ branch --version # Show version
|
|
|
107
109
|
### create
|
|
108
110
|
|
|
109
111
|
```bash
|
|
110
|
-
create [--feature|--bugfix|--hotfix|--release|-t] [
|
|
112
|
+
create [--feature|--bugfix|--hotfix|--release|-t] [-p|--push|--no-push] [-y] [JIRA_LINK|ISSUE] [TITLE...]
|
|
111
113
|
```
|
|
112
114
|
|
|
113
115
|
Create a branch from the latest `origin/<base>` with optional Jira parsing, then push and track it (`GITBASH_CREATE_AUTO_PUSH`, `--no-push`).
|
|
@@ -140,7 +142,7 @@ create # Interactive mode (no Jira prompt)
|
|
|
140
142
|
```bash
|
|
141
143
|
create PROJ-123 fix bug # → feature/PROJ-123-fix-bug
|
|
142
144
|
create fix bug # → feature/NOISSUE-fix-bug
|
|
143
|
-
create
|
|
145
|
+
create --no-push PROJ-7 quick fix # → feature/PROJ-7-quick-fix, not pushed
|
|
144
146
|
```
|
|
145
147
|
|
|
146
148
|
### switch
|
|
@@ -191,7 +193,7 @@ Interactive staging with fzf and diff previews.
|
|
|
191
193
|
### pr
|
|
192
194
|
|
|
193
195
|
```bash
|
|
194
|
-
pr [-p|--push] [--print]
|
|
196
|
+
pr [-p|--push] [--print] [-y|--yes]
|
|
195
197
|
```
|
|
196
198
|
|
|
197
199
|
Open the pull request in the browser: the existing PR via the GitHub CLI when available, otherwise the create page (GitHub, GitHub Enterprise, GitLab, Bitbucket, Azure DevOps). Offers to commit local changes and to push a branch that is not on the remote yet. `-p` pushes first, `--print` prints the URL.
|
|
@@ -215,7 +217,7 @@ Reset the current branch like a fresh clone: fetch, `git reset --hard <remote>/<
|
|
|
215
217
|
### update
|
|
216
218
|
|
|
217
219
|
```bash
|
|
218
|
-
update [-p|--push]
|
|
220
|
+
update [-p|--push] [-y|--yes]
|
|
219
221
|
```
|
|
220
222
|
|
|
221
223
|
Merge the latest `origin/<base>` into the current branch. With local changes, asks to commit, stash (restored afterwards) or abort. Lists conflicts and opens the merge tool (`GITBASH_MERGE_COMMAND`). On the base branch itself, fast-forwards it.
|
|
@@ -240,23 +242,23 @@ Interactive stash menu: create, apply, or delete stashes.
|
|
|
240
242
|
### stash
|
|
241
243
|
|
|
242
244
|
```bash
|
|
243
|
-
stash [NAME...]
|
|
245
|
+
stash [--] [NAME...]
|
|
244
246
|
```
|
|
245
247
|
|
|
246
|
-
Create named stash (includes untracked files).
|
|
248
|
+
Create named stash (includes untracked files). Use `--` for a name starting with `-`.
|
|
247
249
|
|
|
248
250
|
### unstash
|
|
249
251
|
|
|
250
|
-
Apply stash with fzf picker. Drops it afterwards unless you say no.
|
|
252
|
+
Apply stash with fzf picker. Drops it afterwards unless you say no. `-y` drops it without asking.
|
|
251
253
|
|
|
252
254
|
### cleanstash
|
|
253
255
|
|
|
254
|
-
Delete stashes (multi-select with TAB).
|
|
256
|
+
Delete stashes (multi-select with TAB). `-y` skips the confirmation.
|
|
255
257
|
|
|
256
258
|
### cleanup
|
|
257
259
|
|
|
258
260
|
```bash
|
|
259
|
-
cleanup [
|
|
261
|
+
cleanup [-n|--dry-run] [--days=N] [-y|--yes] [--json]
|
|
260
262
|
```
|
|
261
263
|
|
|
262
264
|
Find and delete leftover local branches:
|
|
@@ -288,7 +290,7 @@ Unpushed commits are shown per branch. Deletes with `git branch -d`; force-delet
|
|
|
288
290
|
### commits
|
|
289
291
|
|
|
290
292
|
```bash
|
|
291
|
-
commits [-a|--all] [COUNT]
|
|
293
|
+
commits [-a|--all] [-y|--yes] [COUNT]
|
|
292
294
|
```
|
|
293
295
|
|
|
294
296
|
List the current branch's own commits with option to revert. On a feature branch only commits not in the base branch are shown; on the base branch its first-parent history (merged branches as their merge commit). If the upstream has new commits, offers to fast-forward first. Multi-select with TAB; selected commits are reverted newest first.
|
package/bin/gitbash
CHANGED
|
@@ -20,7 +20,9 @@ if [[ "$SCRIPT_DIR" == */node_modules/.pnpm/gitbash@*/node_modules/gitbash &&
|
|
|
20
20
|
fi
|
|
21
21
|
COMMANDS_DIR="$SCRIPT_DIR/commands"
|
|
22
22
|
VERSION="$(grep -o '"version": *"[^"]*"' "$SCRIPT_DIR/package.json" | head -1 | cut -d'"' -f4)"
|
|
23
|
-
|
|
23
|
+
# Not exported: they would leak into git hooks, editors and merge tools.
|
|
24
|
+
# Commands are sourced into this process; nested runs of gitbash set them again.
|
|
25
|
+
export -n SCRIPT_DIR GITBASH_BIN VERSION
|
|
24
26
|
|
|
25
27
|
# shellcheck source=../commands/_utils.sh
|
|
26
28
|
source "$COMMANDS_DIR/_utils.sh"
|
|
@@ -394,7 +396,8 @@ check_pwsh_integration() {
|
|
|
394
396
|
# Restricted (the default of Windows PowerShell) and AllSigned block the profile
|
|
395
397
|
case "$policy" in
|
|
396
398
|
Restricted|AllSigned|Undefined)
|
|
397
|
-
|
|
399
|
+
# A security setting: never changed by pressing Enter or by GITBASH_ASSUME_YES
|
|
400
|
+
if gb_confirm --strict "PowerShell blocks scripts, including your profile ($policy). Allow local scripts (execution policy RemoteSigned)?" n; then
|
|
398
401
|
if "$exe" -NoProfile -NonInteractive -Command 'Set-ExecutionPolicy -Scope CurrentUser RemoteSigned -Force'; then
|
|
399
402
|
print_success "Local scripts allowed."
|
|
400
403
|
else
|
package/commands/_utils.sh
CHANGED
|
@@ -111,7 +111,8 @@ prompt_read() {
|
|
|
111
111
|
}
|
|
112
112
|
|
|
113
113
|
# Yes/no question. Returns 0 for yes, 1 for no. EOF or Enter picks the default.
|
|
114
|
-
# GITBASH_ASSUME_YES=1 (
|
|
114
|
+
# GITBASH_ASSUME_YES=1 (exported by --yes flags, so commands run from a command
|
|
115
|
+
# inherit it) answers yes, unless --strict is given.
|
|
115
116
|
# Usage: gb_confirm [--strict] "Question?" y|n
|
|
116
117
|
gb_confirm() {
|
|
117
118
|
local strict=false
|
|
@@ -269,7 +270,12 @@ _gb_normalize_config() {
|
|
|
269
270
|
GITBASH_CLEANUP_DAYS=7
|
|
270
271
|
fi
|
|
271
272
|
GITBASH_CLEANUP_DAYS="${GITBASH_CLEANUP_DAYS:-7}"
|
|
272
|
-
|
|
273
|
+
# Values reach git as arguments: a leading '-' would be read as an option
|
|
274
|
+
if [[ -n "$GITBASH_BASE_BRANCH" ]] && ! _gb_valid_branch_name "$GITBASH_BASE_BRANCH"; then
|
|
275
|
+
print_warning "Invalid GITBASH_BASE_BRANCH '$GITBASH_BASE_BRANCH', detecting the base branch instead."
|
|
276
|
+
GITBASH_BASE_BRANCH=""
|
|
277
|
+
fi
|
|
278
|
+
if ! [[ "${GITBASH_REMOTE:-origin}" =~ ^[A-Za-z0-9._][A-Za-z0-9._-]*$ ]]; then
|
|
273
279
|
print_warning "Invalid GITBASH_REMOTE '$GITBASH_REMOTE', using 'origin'."
|
|
274
280
|
GITBASH_REMOTE="origin"
|
|
275
281
|
fi
|
|
@@ -345,15 +351,24 @@ gb_current_branch() {
|
|
|
345
351
|
git symbolic-ref --quiet --short HEAD 2>/dev/null
|
|
346
352
|
}
|
|
347
353
|
|
|
348
|
-
#
|
|
354
|
+
# Returns 0 if $1 is a valid branch name that can't be mistaken for an option.
|
|
355
|
+
# (git itself accepts refs like "refs/heads/--output=file", so check the dash too.)
|
|
356
|
+
_gb_valid_branch_name() {
|
|
357
|
+
[[ -n "$1" && "$1" != -* ]] && git check-ref-format "refs/heads/$1" >/dev/null 2>&1
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
# Detect the base branch: GITBASH_BASE_BRANCH, <remote>/HEAD, main, master.
|
|
361
|
+
# The result is passed to git as an argument: names from a committed .gitbashrc
|
|
362
|
+
# or from the remote are only used when valid.
|
|
349
363
|
gb_base_branch() {
|
|
350
364
|
local remote branch
|
|
351
365
|
remote=$(gb_remote)
|
|
352
|
-
if [[ -n "${GITBASH_BASE_BRANCH:-}" ]]; then
|
|
366
|
+
if [[ -n "${GITBASH_BASE_BRANCH:-}" ]] && _gb_valid_branch_name "$GITBASH_BASE_BRANCH"; then
|
|
353
367
|
echo "$GITBASH_BASE_BRANCH"
|
|
354
368
|
return 0
|
|
355
369
|
fi
|
|
356
|
-
if branch=$(git symbolic-ref --quiet --short "refs/remotes/$remote/HEAD" 2>/dev/null)
|
|
370
|
+
if branch=$(git symbolic-ref --quiet --short "refs/remotes/$remote/HEAD" 2>/dev/null) &&
|
|
371
|
+
_gb_valid_branch_name "${branch#"$remote"/}"; then
|
|
357
372
|
echo "${branch#"$remote"/}"
|
|
358
373
|
return 0
|
|
359
374
|
fi
|
|
@@ -434,18 +449,39 @@ gb_sync_and_push() {
|
|
|
434
449
|
done
|
|
435
450
|
|
|
436
451
|
local remote branch
|
|
437
|
-
remote=$(gb_remote)
|
|
438
452
|
if ! branch=$(gb_current_branch); then
|
|
439
453
|
print_error "Detached HEAD: check out a branch before pushing."
|
|
440
454
|
return 1
|
|
441
455
|
fi
|
|
456
|
+
|
|
457
|
+
# Push to the branch's upstream (e.g. a fork, or a different name on the remote),
|
|
458
|
+
# else to <GITBASH_REMOTE>/<branch>. An upstream that is a protected branch (a
|
|
459
|
+
# branch started from origin/main tracks main) is never pushed to.
|
|
460
|
+
local target="$branch" set_upstream=false up_remote up_merge
|
|
461
|
+
remote=$(gb_remote)
|
|
462
|
+
up_remote=$(git config "branch.$branch.remote" 2>/dev/null) || up_remote=""
|
|
463
|
+
up_merge=$(git config "branch.$branch.merge" 2>/dev/null) || up_merge=""
|
|
464
|
+
up_merge="${up_merge#refs/heads/}"
|
|
465
|
+
if [[ -n "$up_remote" && "$up_remote" != "." && "$up_remote" != -* && -n "$up_merge" ]] &&
|
|
466
|
+
git remote get-url "$up_remote" >/dev/null 2>&1 &&
|
|
467
|
+
_gb_valid_branch_name "$up_merge" && ! gb_is_protected "$up_merge"; then
|
|
468
|
+
remote="$up_remote"
|
|
469
|
+
target="$up_merge"
|
|
470
|
+
else
|
|
471
|
+
set_upstream=true
|
|
472
|
+
fi
|
|
442
473
|
if ! git remote get-url "$remote" >/dev/null 2>&1; then
|
|
443
474
|
print_error "No remote '$remote' configured."
|
|
444
475
|
return 1
|
|
445
476
|
fi
|
|
477
|
+
local refspec="$branch" where="$remote"
|
|
478
|
+
if [[ "$target" != "$branch" ]]; then
|
|
479
|
+
refspec="$branch:refs/heads/$target"
|
|
480
|
+
where="$remote/$target"
|
|
481
|
+
fi
|
|
446
482
|
|
|
447
483
|
local out
|
|
448
|
-
if ! out=$(git ls-remote --heads "$remote" "refs/heads/$
|
|
484
|
+
if ! out=$(git ls-remote --heads "$remote" "refs/heads/$target" 2>&1); then
|
|
449
485
|
print_error "Could not reach '$remote':"
|
|
450
486
|
printf '%s\n' "$out" >&2
|
|
451
487
|
return 1
|
|
@@ -453,40 +489,40 @@ gb_sync_and_push() {
|
|
|
453
489
|
|
|
454
490
|
# New branch: first push sets up tracking
|
|
455
491
|
if [[ -z "$out" ]]; then
|
|
456
|
-
print_info "Pushing new branch '$branch' to '$
|
|
457
|
-
if git push -u "$remote" "$
|
|
458
|
-
print_success "Pushed '$branch' to '$
|
|
492
|
+
print_info "Pushing new branch '$branch' to '$where'..."
|
|
493
|
+
if git push -u "$remote" "$refspec"; then
|
|
494
|
+
print_success "Pushed '$branch' to '$where'."
|
|
459
495
|
return 0
|
|
460
496
|
fi
|
|
461
|
-
print_error "Failed to push '$branch' to '$
|
|
497
|
+
print_error "Failed to push '$branch' to '$where'."
|
|
462
498
|
return 1
|
|
463
499
|
fi
|
|
464
500
|
|
|
465
|
-
if ! git fetch --quiet "$remote" "+refs/heads/$
|
|
466
|
-
print_error "Failed to fetch '$remote/$
|
|
501
|
+
if ! git fetch --quiet "$remote" "+refs/heads/$target:refs/remotes/$remote/$target"; then
|
|
502
|
+
print_error "Failed to fetch '$remote/$target'."
|
|
467
503
|
return 1
|
|
468
504
|
fi
|
|
469
505
|
|
|
470
506
|
local local_commit remote_commit
|
|
471
507
|
local_commit=$(git rev-parse HEAD)
|
|
472
|
-
remote_commit=$(git rev-parse "refs/remotes/$remote/$
|
|
508
|
+
remote_commit=$(git rev-parse "refs/remotes/$remote/$target")
|
|
473
509
|
|
|
474
510
|
if [[ "$local_commit" == "$remote_commit" ]]; then
|
|
475
|
-
print_info "'$remote/$
|
|
511
|
+
print_info "'$remote/$target' is already up to date."
|
|
476
512
|
return 0
|
|
477
513
|
fi
|
|
478
514
|
|
|
479
515
|
local push_args=()
|
|
480
|
-
if [[
|
|
516
|
+
if [[ "$set_upstream" == true ]]; then
|
|
481
517
|
push_args+=("-u")
|
|
482
518
|
fi
|
|
483
519
|
|
|
484
520
|
if git merge-base --is-ancestor "$remote_commit" "$local_commit"; then
|
|
485
521
|
: # Ahead of the remote: plain push
|
|
486
522
|
elif git merge-base --is-ancestor "$local_commit" "$remote_commit"; then
|
|
487
|
-
print_info "'$remote/$
|
|
488
|
-
if git merge --ff-only --quiet "refs/remotes/$remote/$
|
|
489
|
-
print_success "Up to date with '$remote/$
|
|
523
|
+
print_info "'$remote/$target' has new commits. Fast-forwarding..."
|
|
524
|
+
if git merge --ff-only --quiet "refs/remotes/$remote/$target"; then
|
|
525
|
+
print_success "Up to date with '$remote/$target'. Nothing to push."
|
|
490
526
|
return 0
|
|
491
527
|
fi
|
|
492
528
|
print_error "Fast-forward failed."
|
|
@@ -496,10 +532,10 @@ gb_sync_and_push() {
|
|
|
496
532
|
ahead=$(git rev-list --count "$remote_commit..$local_commit")
|
|
497
533
|
behind=$(git rev-list --count "$local_commit..$remote_commit")
|
|
498
534
|
if [[ "$amend" == true || "$force" == true ]]; then
|
|
499
|
-
print_warning "'$remote/$
|
|
500
|
-
if gb_confirm --strict "Overwrite '$remote/$
|
|
501
|
-
if git push "${push_args[@]+"${push_args[@]}"}" --force-with-lease="refs/heads/$
|
|
502
|
-
print_success "Force-pushed '$branch' to '$
|
|
535
|
+
print_warning "'$remote/$target' differs from your rewritten branch ($ahead local vs $behind remote commit(s))."
|
|
536
|
+
if gb_confirm --strict "Overwrite '$remote/$target' with your version (push --force-with-lease)?" n; then
|
|
537
|
+
if git push "${push_args[@]+"${push_args[@]}"}" --force-with-lease="refs/heads/$target:$remote_commit" "$remote" "$refspec"; then
|
|
538
|
+
print_success "Force-pushed '$branch' to '$where'."
|
|
503
539
|
return 0
|
|
504
540
|
fi
|
|
505
541
|
print_error "Force push failed (someone else may have pushed in the meantime)."
|
|
@@ -509,18 +545,18 @@ gb_sync_and_push() {
|
|
|
509
545
|
return 1
|
|
510
546
|
fi
|
|
511
547
|
|
|
512
|
-
print_warning "Your branch and '$remote/$
|
|
548
|
+
print_warning "Your branch and '$remote/$target' have diverged ($ahead local, $behind remote commit(s))."
|
|
513
549
|
local choice
|
|
514
|
-
gb_choice choice "[r]ebase onto '$remote/$
|
|
550
|
+
gb_choice choice "[r]ebase onto '$remote/$target', [m]erge it, or [a]bort? (r/m/A):" "rma" "a"
|
|
515
551
|
case "$choice" in
|
|
516
552
|
r)
|
|
517
|
-
if ! git rebase --rebase-merges "refs/remotes/$remote/$
|
|
553
|
+
if ! git rebase --rebase-merges "refs/remotes/$remote/$target"; then
|
|
518
554
|
print_error "Rebase stopped. Resolve the conflicts and run 'git rebase --continue', or 'git rebase --abort'."
|
|
519
555
|
return 1
|
|
520
556
|
fi
|
|
521
557
|
;;
|
|
522
558
|
m)
|
|
523
|
-
if ! git merge --no-edit "refs/remotes/$remote/$
|
|
559
|
+
if ! git merge --no-edit "refs/remotes/$remote/$target"; then
|
|
524
560
|
print_error "Merge stopped. Resolve the conflicts and commit, or run 'git merge --abort'."
|
|
525
561
|
return 1
|
|
526
562
|
fi
|
|
@@ -532,12 +568,12 @@ gb_sync_and_push() {
|
|
|
532
568
|
esac
|
|
533
569
|
fi
|
|
534
570
|
|
|
535
|
-
print_info "Pushing '$branch' to '$
|
|
536
|
-
if git push "${push_args[@]+"${push_args[@]}"}" "$remote" "$
|
|
537
|
-
print_success "Pushed '$branch' to '$
|
|
571
|
+
print_info "Pushing '$branch' to '$where'..."
|
|
572
|
+
if git push "${push_args[@]+"${push_args[@]}"}" "$remote" "$refspec"; then
|
|
573
|
+
print_success "Pushed '$branch' to '$where'."
|
|
538
574
|
return 0
|
|
539
575
|
fi
|
|
540
|
-
print_error "Failed to push '$branch' to '$
|
|
576
|
+
print_error "Failed to push '$branch' to '$where'."
|
|
541
577
|
return 1
|
|
542
578
|
}
|
|
543
579
|
|
package/commands/branch.sh
CHANGED
|
@@ -30,60 +30,12 @@ Features:
|
|
|
30
30
|
- Update: Update current branch with latest main/master
|
|
31
31
|
|
|
32
32
|
Navigation:
|
|
33
|
-
↑/↓
|
|
33
|
+
↑/↓ Navigate through options (typing filters the list)
|
|
34
34
|
Enter Select action
|
|
35
35
|
ESC/Ctrl-C Abort
|
|
36
36
|
|
|
37
37
|
Examples:
|
|
38
|
-
$ branch
|
|
39
|
-
Branch action >
|
|
40
|
-
> 🌿 Create - Create a new feature branch
|
|
41
|
-
🔀 Switch - Switch to another branch
|
|
42
|
-
⬆️ Update - Update current branch with main/master
|
|
43
|
-
✖ Abort
|
|
44
|
-
|
|
45
|
-
# Select "Create" and press Enter
|
|
46
|
-
Enter Jira link (e.g., https://jira.company.com/browse/PROJ-123):
|
|
47
|
-
> PROJ-123
|
|
48
|
-
Parsed issue number: PROJ-123
|
|
49
|
-
|
|
50
|
-
Enter branch title (will be converted to lowercase with dashes):
|
|
51
|
-
> add new feature
|
|
52
|
-
|
|
53
|
-
Branch name: feature/PROJ-123-add-new-feature
|
|
54
|
-
Updating 'main' from origin...
|
|
55
|
-
✓ 'main' is up to date.
|
|
56
|
-
✓ Successfully created and switched to branch: feature/PROJ-123-add-new-feature (from main)
|
|
57
|
-
|
|
58
|
-
---
|
|
59
|
-
|
|
60
|
-
$ branch
|
|
61
|
-
Branch action >
|
|
62
|
-
> 🌿 Create - Create a new feature branch
|
|
63
|
-
🔀 Switch - Switch to another branch
|
|
64
|
-
⬆️ Update - Update current branch with main/master
|
|
65
|
-
✖ Abort
|
|
66
|
-
|
|
67
|
-
# Select "Switch" and press Enter
|
|
68
|
-
Select branch:
|
|
69
|
-
Current: main
|
|
70
|
-
> local: main
|
|
71
|
-
local: feature/PROJ-123-add-new-feature
|
|
72
|
-
remote: origin/develop
|
|
73
|
-
|
|
74
|
-
---
|
|
75
|
-
|
|
76
|
-
$ branch
|
|
77
|
-
Branch action >
|
|
78
|
-
> 🌿 Create - Create a new feature branch
|
|
79
|
-
🔀 Switch - Switch to another branch
|
|
80
|
-
⬆️ Update - Update current branch with main/master
|
|
81
|
-
✖ Abort
|
|
82
|
-
|
|
83
|
-
# Select "Update" and press Enter
|
|
84
|
-
Fetching latest 'main' from origin...
|
|
85
|
-
Merging updated 'main' into 'feature/PROJ-123-add-new-feature'...
|
|
86
|
-
✓ 'feature/PROJ-123-add-new-feature' is now up-to-date with 'main'.
|
|
38
|
+
$ branch # pick Create, Switch or Update, then continue as in that command
|
|
87
39
|
|
|
88
40
|
Actions:
|
|
89
41
|
🌿 Create - Create a new feature branch with Jira parsing
|
|
@@ -102,6 +54,12 @@ EOF
|
|
|
102
54
|
return 0
|
|
103
55
|
fi
|
|
104
56
|
|
|
57
|
+
if [[ $# -gt 0 ]]; then
|
|
58
|
+
print_error "Unknown argument: $1"
|
|
59
|
+
echo "Usage: branch [-h|--help]" >&2
|
|
60
|
+
return 1
|
|
61
|
+
fi
|
|
62
|
+
|
|
105
63
|
# -----------------------------
|
|
106
64
|
# 1. Check for fzf
|
|
107
65
|
# -----------------------------
|
package/commands/cleanstash.sh
CHANGED
|
@@ -20,6 +20,7 @@ Delete git stashes without applying them.
|
|
|
20
20
|
Interactive fuzzy finder (fzf) with preview and multi-select support.
|
|
21
21
|
|
|
22
22
|
Options:
|
|
23
|
+
-y, --yes Delete the selected stashes without asking again
|
|
23
24
|
-h, --help Show this help message
|
|
24
25
|
|
|
25
26
|
Navigation:
|
|
@@ -40,6 +41,19 @@ EOF
|
|
|
40
41
|
return 0
|
|
41
42
|
fi
|
|
42
43
|
|
|
44
|
+
while [[ $# -gt 0 ]]; do
|
|
45
|
+
case "$1" in
|
|
46
|
+
-h|--help) cleanstash --help; return 0 ;;
|
|
47
|
+
-y|--yes) export GITBASH_ASSUME_YES=1 ;;
|
|
48
|
+
*)
|
|
49
|
+
print_error "Unknown argument: $1"
|
|
50
|
+
echo "Usage: cleanstash [-y|--yes]" >&2
|
|
51
|
+
return 1
|
|
52
|
+
;;
|
|
53
|
+
esac
|
|
54
|
+
shift
|
|
55
|
+
done
|
|
56
|
+
|
|
43
57
|
require_git_repo || return 1
|
|
44
58
|
|
|
45
59
|
local stash_list
|
package/commands/cleanup.sh
CHANGED
|
@@ -45,7 +45,7 @@ Find and delete local branches that are no longer needed.
|
|
|
45
45
|
Options:
|
|
46
46
|
-h, --help Show this help message
|
|
47
47
|
--json Output branch data as JSON (non-interactive)
|
|
48
|
-
--dry-run
|
|
48
|
+
-n, --dry-run List the branches that would be pre-selected, without deleting
|
|
49
49
|
--days=N Override stale threshold (default: 7 days, configurable via GITBASH_CLEANUP_DAYS)
|
|
50
50
|
-y, --yes Delete the pre-selected branches without the picker (safe delete only)
|
|
51
51
|
|
|
@@ -88,12 +88,17 @@ EOF
|
|
|
88
88
|
json_mode=true
|
|
89
89
|
shift
|
|
90
90
|
;;
|
|
91
|
-
|
|
91
|
+
-n|--dry-run)
|
|
92
92
|
dry_run=true
|
|
93
93
|
shift
|
|
94
94
|
;;
|
|
95
|
-
--days
|
|
96
|
-
|
|
95
|
+
--days=*|--days)
|
|
96
|
+
if [[ "$1" == --days ]]; then
|
|
97
|
+
days_threshold="${2:-}"
|
|
98
|
+
shift
|
|
99
|
+
else
|
|
100
|
+
days_threshold="${1#--days=}"
|
|
101
|
+
fi
|
|
97
102
|
if ! [[ "$days_threshold" =~ ^[1-9][0-9]*$ ]]; then
|
|
98
103
|
print_error "Invalid days value: $days_threshold"
|
|
99
104
|
return 1
|
|
@@ -101,7 +106,7 @@ EOF
|
|
|
101
106
|
shift
|
|
102
107
|
;;
|
|
103
108
|
-y|--yes)
|
|
104
|
-
GITBASH_ASSUME_YES=1
|
|
109
|
+
export GITBASH_ASSUME_YES=1
|
|
105
110
|
shift
|
|
106
111
|
;;
|
|
107
112
|
*)
|
package/commands/commit.sh
CHANGED
package/commands/commits.sh
CHANGED
|
@@ -13,7 +13,7 @@ commits() {
|
|
|
13
13
|
fi
|
|
14
14
|
if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
|
|
15
15
|
gb_help << 'EOF'
|
|
16
|
-
Usage: commits [-a|--all] [COUNT]
|
|
16
|
+
Usage: commits [-a|--all] [-y|--yes] [COUNT]
|
|
17
17
|
|
|
18
18
|
List the commits made on the current branch with option to revert selected ones.
|
|
19
19
|
|
|
@@ -26,6 +26,7 @@ Arguments:
|
|
|
26
26
|
|
|
27
27
|
Options:
|
|
28
28
|
-a, --all Show all recent commits reachable from HEAD
|
|
29
|
+
-y, --yes Revert the selected commits without asking again
|
|
29
30
|
|
|
30
31
|
Navigation:
|
|
31
32
|
↑/↓ Navigate through commits
|
|
@@ -59,6 +60,7 @@ EOF
|
|
|
59
60
|
while [[ $# -gt 0 ]]; do
|
|
60
61
|
case "$1" in
|
|
61
62
|
-a|--all) all=true ;;
|
|
63
|
+
-y|--yes) export GITBASH_ASSUME_YES=1 ;;
|
|
62
64
|
-*) print_error "Unknown option '$1'. See 'commits --help'."; return 1 ;;
|
|
63
65
|
*)
|
|
64
66
|
if [[ -n "$count" ]]; then
|
package/commands/create.sh
CHANGED
|
@@ -63,8 +63,9 @@ Options:
|
|
|
63
63
|
--bugfix Use 'bugfix/' type
|
|
64
64
|
--hotfix Use 'hotfix/' type
|
|
65
65
|
--release Use 'release/' type
|
|
66
|
-
--push
|
|
66
|
+
-p, --push Push the new branch to the remote (default: GITBASH_CREATE_AUTO_PUSH)
|
|
67
67
|
--no-push Don't push the new branch
|
|
68
|
+
-y, --yes Don't ask for confirmations (switches to an existing branch of the same name)
|
|
68
69
|
|
|
69
70
|
Configuration (run 'gitbash --config'):
|
|
70
71
|
- GITBASH_CREATE_BRANCH_PREFIX: Custom prefix between type and issue (default: "")
|
|
@@ -101,7 +102,8 @@ EOF
|
|
|
101
102
|
--bugfix) branch_type="bugfix/"; shift ;;
|
|
102
103
|
--hotfix) branch_type="hotfix/"; shift ;;
|
|
103
104
|
--release) branch_type="release/"; shift ;;
|
|
104
|
-
|
|
105
|
+
-p|--push) auto_push="yes"; shift ;;
|
|
106
|
+
-y|--yes) export GITBASH_ASSUME_YES=1; shift ;;
|
|
105
107
|
--no-push) auto_push="no"; shift ;;
|
|
106
108
|
--)
|
|
107
109
|
shift
|
package/commands/pr.sh
CHANGED
package/commands/stale.sh
CHANGED
|
@@ -84,8 +84,13 @@ EOF
|
|
|
84
84
|
my_mode=true
|
|
85
85
|
shift
|
|
86
86
|
;;
|
|
87
|
-
--age
|
|
88
|
-
|
|
87
|
+
--age=*|--age)
|
|
88
|
+
if [[ "$1" == --age ]]; then
|
|
89
|
+
stale_months="${2:-}"
|
|
90
|
+
shift
|
|
91
|
+
else
|
|
92
|
+
stale_months="${1#--age=}"
|
|
93
|
+
fi
|
|
89
94
|
if ! [[ "$stale_months" =~ ^[1-9][0-9]*$ ]]; then
|
|
90
95
|
print_error "Invalid age value: $stale_months"
|
|
91
96
|
return 1
|
|
@@ -273,7 +278,8 @@ TOGGLE_EOF
|
|
|
273
278
|
|
|
274
279
|
local failed=0 out
|
|
275
280
|
for branch in "${branches_to_delete[@]}"; do
|
|
276
|
-
|
|
281
|
+
# A refspec, not a bare name: branch names come from the remote
|
|
282
|
+
if out=$(git push "$remote" ":refs/heads/$branch" 2>&1); then
|
|
277
283
|
print_success "Deleted $remote/$branch"
|
|
278
284
|
else
|
|
279
285
|
print_error "Failed to delete $remote/$branch:"
|
package/commands/stash.sh
CHANGED
|
@@ -12,13 +12,14 @@ stash() {
|
|
|
12
12
|
fi
|
|
13
13
|
if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
|
|
14
14
|
gb_help << 'EOF'
|
|
15
|
-
Usage: stash [NAME...]
|
|
15
|
+
Usage: stash [--] [NAME...]
|
|
16
16
|
|
|
17
17
|
Create a git stash with a descriptive name.
|
|
18
18
|
If no name is provided, prompts for one interactively.
|
|
19
19
|
|
|
20
20
|
Options:
|
|
21
21
|
-h, --help Show this help message
|
|
22
|
+
-- Everything after this is the name (even if it starts with '-')
|
|
22
23
|
|
|
23
24
|
Features:
|
|
24
25
|
- Stashes all changes: staged, unstaged and untracked files
|
|
@@ -45,6 +46,20 @@ EOF
|
|
|
45
46
|
return 0
|
|
46
47
|
fi
|
|
47
48
|
|
|
49
|
+
local name_parts=()
|
|
50
|
+
while [[ $# -gt 0 ]]; do
|
|
51
|
+
case "$1" in
|
|
52
|
+
-h|--help) stash --help; return 0 ;;
|
|
53
|
+
--) shift; name_parts+=("$@"); break ;;
|
|
54
|
+
-*)
|
|
55
|
+
print_error "Unknown option: $1 (use 'stash -- $1' for a name starting with '-')"
|
|
56
|
+
return 1
|
|
57
|
+
;;
|
|
58
|
+
*) name_parts+=("$1") ;;
|
|
59
|
+
esac
|
|
60
|
+
shift
|
|
61
|
+
done
|
|
62
|
+
|
|
48
63
|
require_git_repo || return 1
|
|
49
64
|
|
|
50
65
|
if ! git rev-parse --verify --quiet HEAD >/dev/null; then
|
|
@@ -58,8 +73,8 @@ EOF
|
|
|
58
73
|
fi
|
|
59
74
|
|
|
60
75
|
local stash_name
|
|
61
|
-
if [[
|
|
62
|
-
stash_name="
|
|
76
|
+
if [[ ${#name_parts[@]} -gt 0 ]]; then
|
|
77
|
+
stash_name="${name_parts[*]}"
|
|
63
78
|
else
|
|
64
79
|
prompt_read "Stash name: " stash_name || true
|
|
65
80
|
if [[ -z "$stash_name" ]]; then
|
package/commands/stashes.sh
CHANGED
|
@@ -29,60 +29,12 @@ Features:
|
|
|
29
29
|
- Clean up: Delete stashes without applying them
|
|
30
30
|
|
|
31
31
|
Navigation:
|
|
32
|
-
↑/↓
|
|
32
|
+
↑/↓ Navigate through options (typing filters the list)
|
|
33
33
|
Enter Select action
|
|
34
34
|
ESC/Ctrl-C Abort
|
|
35
35
|
|
|
36
36
|
Examples:
|
|
37
|
-
$ stashes
|
|
38
|
-
Stash action >
|
|
39
|
-
> 💾 Stash - Create a new stash with a name
|
|
40
|
-
📦 Unstash - Apply and optionally drop a stash
|
|
41
|
-
🗑️ Clean up - Delete stashes without applying
|
|
42
|
-
✖ Abort
|
|
43
|
-
|
|
44
|
-
# Select "Stash" and press Enter
|
|
45
|
-
Stash name: work in progress
|
|
46
|
-
✓ Created stash: work in progress
|
|
47
|
-
|
|
48
|
-
---
|
|
49
|
-
|
|
50
|
-
$ stashes
|
|
51
|
-
Stash action >
|
|
52
|
-
> 💾 Stash - Create a new stash with a name
|
|
53
|
-
📦 Unstash - Apply and optionally drop a stash
|
|
54
|
-
🗑️ Clean up - Delete stashes without applying
|
|
55
|
-
✖ Abort
|
|
56
|
-
|
|
57
|
-
# Select "Unstash" and press Enter
|
|
58
|
-
Available stashes >
|
|
59
|
-
> stash@{0}: WIP on main: 1a2b3c4 commit message
|
|
60
|
-
stash@{1}: WIP on feature: 5d6e7f8 another commit
|
|
61
|
-
✖ Abort
|
|
62
|
-
|
|
63
|
-
Applying stash@{0} ...
|
|
64
|
-
Drop stash@{0} now? (Y/n): y
|
|
65
|
-
|
|
66
|
-
---
|
|
67
|
-
|
|
68
|
-
$ stashes
|
|
69
|
-
Stash action >
|
|
70
|
-
> 📦 Unstash - Apply and optionally drop a stash
|
|
71
|
-
🗑️ Clean up - Delete stashes without applying
|
|
72
|
-
✖ Abort
|
|
73
|
-
|
|
74
|
-
# Select "Clean up" and press Enter
|
|
75
|
-
Available stashes >
|
|
76
|
-
> stash@{0}: WIP on main: 1a2b3c4 commit message
|
|
77
|
-
stash@{1}: WIP on feature: 5d6e7f8 another commit
|
|
78
|
-
✖ Abort
|
|
79
|
-
|
|
80
|
-
# Use TAB to select multiple stashes
|
|
81
|
-
Selected stashes to delete:
|
|
82
|
-
- stash@{0}
|
|
83
|
-
- stash@{1}
|
|
84
|
-
|
|
85
|
-
Delete these 2 stash(es)? (y/N): y
|
|
37
|
+
$ stashes # pick Stash, Unstash or Clean up, then continue as in that command
|
|
86
38
|
|
|
87
39
|
Actions:
|
|
88
40
|
💾 Stash - Create a new stash with all changes
|
|
@@ -101,6 +53,12 @@ EOF
|
|
|
101
53
|
return 0
|
|
102
54
|
fi
|
|
103
55
|
|
|
56
|
+
if [[ $# -gt 0 ]]; then
|
|
57
|
+
print_error "Unknown argument: $1"
|
|
58
|
+
echo "Usage: stashes [-h|--help]" >&2
|
|
59
|
+
return 1
|
|
60
|
+
fi
|
|
61
|
+
|
|
104
62
|
# -----------------------------
|
|
105
63
|
# 1. Check for fzf
|
|
106
64
|
# -----------------------------
|
package/commands/status.sh
CHANGED
package/commands/switch.sh
CHANGED
|
@@ -139,6 +139,15 @@ EOF
|
|
|
139
139
|
;;
|
|
140
140
|
esac
|
|
141
141
|
|
|
142
|
+
# Branch names never start with '-': anything like that is a mistyped option
|
|
143
|
+
local arg
|
|
144
|
+
for arg in "$@"; do
|
|
145
|
+
case "$arg" in
|
|
146
|
+
-h|--help) switch --help; return 0 ;;
|
|
147
|
+
-*) print_error "Unknown option: $arg"; echo "Usage: switch [FILTER...]" >&2; return 1 ;;
|
|
148
|
+
esac
|
|
149
|
+
done
|
|
150
|
+
|
|
142
151
|
require_git_repo || return 1
|
|
143
152
|
require_fzf || return 1
|
|
144
153
|
|
package/commands/unstash.sh
CHANGED
|
@@ -32,6 +32,7 @@ Apply a git stash to your working directory with optional removal.
|
|
|
32
32
|
Interactive fuzzy finder (fzf) with preview support.
|
|
33
33
|
|
|
34
34
|
Options:
|
|
35
|
+
-y, --yes Don't ask for confirmations (drops the stash after applying it)
|
|
35
36
|
-h, --help Show this help message
|
|
36
37
|
|
|
37
38
|
Workflow:
|
|
@@ -49,6 +50,19 @@ EOF
|
|
|
49
50
|
return 0
|
|
50
51
|
fi
|
|
51
52
|
|
|
53
|
+
while [[ $# -gt 0 ]]; do
|
|
54
|
+
case "$1" in
|
|
55
|
+
-h|--help) unstash --help; return 0 ;;
|
|
56
|
+
-y|--yes) export GITBASH_ASSUME_YES=1 ;;
|
|
57
|
+
*)
|
|
58
|
+
print_error "Unknown argument: $1"
|
|
59
|
+
echo "Usage: unstash [-y|--yes]" >&2
|
|
60
|
+
return 1
|
|
61
|
+
;;
|
|
62
|
+
esac
|
|
63
|
+
shift
|
|
64
|
+
done
|
|
65
|
+
|
|
52
66
|
require_git_repo || return 1
|
|
53
67
|
|
|
54
68
|
local stash_list
|
package/commands/update.sh
CHANGED
package/docs/CONTRIBUTING.md
CHANGED
|
@@ -78,8 +78,8 @@ We use [Changesets](https://github.com/changesets/changesets) to manage versions
|
|
|
78
78
|
|
|
79
79
|
```bash
|
|
80
80
|
# 1. Create your feature branch
|
|
81
|
-
./bin/gitbash create
|
|
82
|
-
#
|
|
81
|
+
./bin/gitbash create -t
|
|
82
|
+
# Pick the type (feature/bugfix), enter the issue number or press Enter for NOISSUE, then a title
|
|
83
83
|
|
|
84
84
|
# 2. Make your changes
|
|
85
85
|
vim commands/stale.sh
|
|
@@ -98,13 +98,14 @@ npm run changeset
|
|
|
98
98
|
|
|
99
99
|
### What happens to changesets:
|
|
100
100
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
101
|
+
Releases run only in GitHub Actions ([release.yml](../.github/workflows/release.yml)), never from a laptop:
|
|
102
|
+
|
|
103
|
+
1. When your PR is merged, its changeset lands on `main`.
|
|
104
|
+
2. The Release workflow runs CI, then opens (or updates) the **`chore: release vX.Y.Z`** pull request: `changeset version` bumps `package.json` and adds the CHANGELOG.md section. More merged changesets are added to the same pull request.
|
|
105
|
+
3. On the release pull request, approve its CI run ("Approve workflows to run"): runs for pull requests opened by GitHub Actions wait for a maintainer. Merging it **stages** the version on npm with [trusted publishing](https://docs.npmjs.com/trusted-publishers) (no npm token, with provenance) and creates a draft GitHub release (no tag yet, not visible to `gitbash --update`).
|
|
106
|
+
4. A maintainer reviews and approves the staged version on npmjs.com or with `npm stage approve` ([staged publishing](https://docs.npmjs.com/staged-publishing/), needs 2FA; the workflow cannot approve).
|
|
107
|
+
5. Within 15 minutes a scheduled run sees the version live on npm and publishes the GitHub release, which creates the `vX.Y.Z` tag. To do it right away: `gh workflow run release.yml`.
|
|
108
|
+
6. If a run fails, re-run it: finished steps are skipped. To re-stage a rejected version, delete its draft release and re-run.
|
|
108
109
|
|
|
109
110
|
## Development Guidelines
|
|
110
111
|
|
package/docs/SECURITY.md
CHANGED
|
@@ -6,10 +6,10 @@ The following versions of this project are currently receiving security updates:
|
|
|
6
6
|
|
|
7
7
|
| Version | Supported |
|
|
8
8
|
|--------|-----------|
|
|
9
|
-
|
|
|
10
|
-
| <
|
|
9
|
+
| 3.x.x | ✅ |
|
|
10
|
+
| < 3.0 | ❌ |
|
|
11
11
|
|
|
12
|
-
Security fixes are only applied to the latest minor/patch release of the **
|
|
12
|
+
Security fixes are only applied to the latest minor/patch release of the **3.x.x** series. Older versions must be upgraded to receive patches.
|
|
13
13
|
|
|
14
14
|
Versions before 2.0 executed repository `.gitbashrc` files as shell code, so opening a cloned repository with a malicious `.gitbashrc` could run arbitrary commands. Upgrade to 2.0 or later.
|
|
15
15
|
|
|
@@ -19,11 +19,21 @@ Versions before 2.0 executed repository `.gitbashrc` files as shell code, so ope
|
|
|
19
19
|
|
|
20
20
|
- Configuration files (`~/.gitbashrc`, a repository's `.gitbashrc` and `.gitbashrc-user`) are **parsed, never executed**. Only plain `GITBASH_*="value"` lines from a fixed list of settings are read; values containing `$`, backticks, backslashes or quotes are rejected.
|
|
21
21
|
- A repository's committed `.gitbashrc` is treated as untrusted: it cannot set `GITBASH_MERGE_COMMAND` (the only setting that names a program to run). That setting is only read from `~/.gitbashrc` and `.gitbashrc-user`.
|
|
22
|
+
- Settings that reach git as arguments are validated: `GITBASH_BASE_BRANCH` (and a base branch taken from the remote's `HEAD`) must be a valid branch name that does not start with `-`, and `GITBASH_REMOTE` must not start with `-`. Before 3.0.0, a committed `.gitbashrc` could set `GITBASH_BASE_BRANCH="--output=<file>"` and make `switch` or `cleanup` overwrite that file.
|
|
22
23
|
- `gitbash --init` prints wrapper functions that call the installed `gitbash` binary; command code is not sourced into your shell.
|
|
23
24
|
- `pr` and `repo` never pass credentials from the remote URL to the browser.
|
|
24
25
|
|
|
25
26
|
---
|
|
26
27
|
|
|
28
|
+
## Releases
|
|
29
|
+
|
|
30
|
+
- Releases are staged only by the Release workflow in GitHub Actions, with npm trusted publishing (OIDC, no long-lived npm token) and [provenance](https://docs.npmjs.com/generating-provenance-statements). A version goes live only after a maintainer approves it with 2FA ([staged publishing](https://docs.npmjs.com/staged-publishing/)); neither the workflow nor a leaked GitHub token can publish on its own. Check an installed copy with `npm audit signatures`.
|
|
31
|
+
- The install script (`install.sh`, also used by `gitbash --update` for script installs) downloads that same npm package and installs it only if it matches the sha512 checksum npm records for the version, so a moved git tag cannot change what gets installed.
|
|
32
|
+
- The npm package is published before the GitHub release, which `gitbash --update` and the install script use.
|
|
33
|
+
- Third-party actions are pinned to commit SHAs and kept up to date by Dependabot; each workflow job gets only the permissions it needs.
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
27
37
|
## Reporting a Vulnerability
|
|
28
38
|
|
|
29
39
|
We take security vulnerabilities seriously and appreciate your efforts to responsibly disclose them.
|
package/docs/workflows.md
CHANGED
|
@@ -10,7 +10,7 @@ Gitbash reduces repetitive typing and provides interactive previews and safe cle
|
|
|
10
10
|
| Checkout base branch | `switch main` | `git switch main` |
|
|
11
11
|
| Create feature branch (from latest main) | `create PROJ-123 add login` | `git switch -c feature/PROJ-123-add-login main`<br>`git push -u origin feature/PROJ-123-add-login` |
|
|
12
12
|
| Create a stash (WIP) | `stash "WIP PROJ-123 implement login"` | `git stash push -u -m "WIP PROJ-123 implement login"` |
|
|
13
|
-
| Create + switch to another branch (ensure main up-to-date) | `create OTHER-456 fix typo`
|
|
13
|
+
| Create + switch to another branch (ensure main up-to-date) | `create --bugfix OTHER-456 fix typo` | `git switch main`<br>`git pull origin main`<br>`git switch -c bugfix/OTHER-456-fix-typo main`<br>`git push -u origin bugfix/OTHER-456-fix-typo` |
|
|
14
14
|
| Implement changes on other branch, commit & push | `commit -p "fix(OTHER-456): fix typo"` | `git add -A`<br>`git commit -m "fix(OTHER-456): fix typo"`<br>`git push -u origin bugfix/OTHER-456-fix-typo` |
|
|
15
15
|
| Switch back to original Jira branch | `switch PROJ-123` | `git switch feature/PROJ-123-add-login` |
|
|
16
16
|
| Verify main was up-to-date at creation time<br>Update feature branch by merging current `main` into it | `update` | `git fetch origin`<br>`git log --oneline HEAD..origin/main`<br>`git pull origin main` (run while on feature branch) |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "gitbash",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.0.1",
|
|
4
4
|
"description": "Opinionated git utilities for bash with fzf-powered menus",
|
|
5
5
|
"author": "jaggli",
|
|
6
6
|
"license": "MIT",
|
|
@@ -38,14 +38,17 @@
|
|
|
38
38
|
"linux",
|
|
39
39
|
"win32"
|
|
40
40
|
],
|
|
41
|
+
"publishConfig": {
|
|
42
|
+
"access": "public",
|
|
43
|
+
"provenance": true
|
|
44
|
+
},
|
|
41
45
|
"engines": {
|
|
42
46
|
"node": ">=14"
|
|
43
47
|
},
|
|
44
48
|
"scripts": {
|
|
45
49
|
"test": "bats test",
|
|
46
50
|
"changeset": "changeset",
|
|
47
|
-
"version": "changeset version"
|
|
48
|
-
"release": "scripts/release.sh"
|
|
51
|
+
"version": "changeset version"
|
|
49
52
|
},
|
|
50
53
|
"devDependencies": {
|
|
51
54
|
"@changesets/cli": "^2.29.8",
|