gitbash 1.1.0 → 1.2.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.
@@ -11,6 +11,8 @@ source "$SOURCE_DIR/_utils.sh"
11
11
  commit() {
12
12
  local should_push=false
13
13
  local staged_only=false
14
+ local amend_mode=false
15
+ local show_prefix_menu=false
14
16
  local msg_parts=()
15
17
 
16
18
  # Parse arguments
@@ -27,9 +29,23 @@ Usage: commit [MESSAGE] [OPTIONS]
27
29
  Stage all changes (git add -A) and commit with a message.
28
30
 
29
31
  Options:
30
- -p, --push Push to origin after successful commit
31
- -s, --staged Commit only staged changes (skip prompt, ignore unstaged)
32
- -h, --help Show this help message
32
+ -p, --push Push to origin after successful commit
33
+ -s, --staged Commit only staged changes (skip prompt, ignore unstaged)
34
+ -a, --amend Amend the last commit instead of creating a new one
35
+ -t, --type Show conventional commit type selector (feat, fix, docs, etc.)
36
+ -h, --help Show this help message
37
+
38
+ Conventional Commit Types (with --type):
39
+ feat: A new feature
40
+ fix: A bug fix
41
+ docs: Documentation only changes
42
+ style: Code style changes (formatting, whitespace)
43
+ refactor: Code change that neither fixes a bug nor adds a feature
44
+ perf: Performance improvement
45
+ test: Adding or fixing tests
46
+ build: Build system or dependency changes
47
+ ci: CI/CD configuration changes
48
+ chore: Other changes that don't modify src or test files
33
49
 
34
50
  Interactive mode (no message):
35
51
  $ commit
@@ -42,6 +58,15 @@ With message argument:
42
58
  [main 5d6e7f8] implement new feature
43
59
  3 files changed, 42 insertions(+), 8 deletions(-)
44
60
 
61
+ With type selector:
62
+ $ commit -t fix broken tests
63
+ # Shows type menu, then commits as "fix: broken tests"
64
+
65
+ Amend last commit:
66
+ $ commit --amend fix typo in docs
67
+ [main abc123] fix typo in docs
68
+ 1 file changed, 1 insertion(+)
69
+
45
70
  With push option:
46
71
  $ commit update documentation -p
47
72
  [main 9a8b7c6] update documentation
@@ -49,18 +74,14 @@ With push option:
49
74
  Pushing 'main' to origin...
50
75
  ✓ Successfully pushed 'main' to origin.
51
76
 
52
- $ commit -p hotfix: critical bug
53
- [main 3c2d1e0] hotfix: critical bug
54
- 2 files changed, 15 insertions(+), 5 deletions(-)
55
- Pushing 'main' to origin...
56
- ✓ Successfully pushed 'main' to origin.
57
-
58
77
  Examples:
59
78
  commit # Interactive mode
60
79
  commit add user validation # Quick commit
61
80
  commit refactor auth module --push # Commit and push
62
81
  commit -p update dependencies # Commit and push (short flag)
63
82
  commit -s -p fix bug # Commit only staged and push
83
+ commit -t add user endpoint # Conventional commit with type menu
84
+ commit --amend fix typo # Amend last commit
64
85
 
65
86
  EOF
66
87
  return 0
@@ -73,9 +94,17 @@ EOF
73
94
  staged_only=true
74
95
  shift
75
96
  ;;
97
+ -a|--amend)
98
+ amend_mode=true
99
+ shift
100
+ ;;
101
+ -t|--type)
102
+ show_prefix_menu=true
103
+ shift
104
+ ;;
76
105
  -*)
77
106
  echo "Unknown option: $1"
78
- echo "Usage: commit [message] [-p|--push] [-s|--staged]"
107
+ echo "Usage: commit [message] [-p|--push] [-s|--staged] [-a|--amend] [-t|--type]"
79
108
  return 1
80
109
  ;;
81
110
  *)
@@ -98,6 +127,58 @@ EOF
98
127
  prompt_read "Commit message: " msg
99
128
  fi
100
129
 
130
+ # Show conventional commit type menu if requested
131
+ if [[ "$show_prefix_menu" == true ]]; then
132
+ if ! command -v fzf >/dev/null 2>&1; then
133
+ print_error "fzf is required for type selector. Install it or provide message directly."
134
+ return 1
135
+ fi
136
+
137
+ local type_options
138
+ type_options=$(cat << 'TYPES'
139
+ feat - A new feature
140
+ fix - A bug fix
141
+ docs - Documentation only changes
142
+ style - Code style changes (formatting, whitespace)
143
+ refactor - Code change that neither fixes nor adds a feature
144
+ perf - Performance improvement
145
+ test - Adding or fixing tests
146
+ build - Build system or dependency changes
147
+ ci - CI/CD configuration changes
148
+ chore - Other changes that don't modify src/test files
149
+ TYPES
150
+ )
151
+
152
+ local selected_type
153
+ selected_type=$(echo "$type_options" | fzf --prompt="Commit type > " \
154
+ -i \
155
+ --reverse \
156
+ --border \
157
+ --header="Select conventional commit type" \
158
+ --no-multi \
159
+ --bind=enter:accept \
160
+ ) </dev/tty || true
161
+
162
+ if [[ -z "$selected_type" ]]; then
163
+ echo "Aborted."
164
+ return 1
165
+ fi
166
+
167
+ # Extract just the type keyword (first word)
168
+ local type_keyword
169
+ type_keyword=$(echo "$selected_type" | awk '{print $1}')
170
+
171
+ # Prepend to message
172
+ msg="${type_keyword}: ${msg}"
173
+ print_info "Commit message: $msg"
174
+ fi
175
+
176
+ # Build commit flags
177
+ local commit_flags=()
178
+ if [[ "$amend_mode" == true ]]; then
179
+ commit_flags+=("--amend")
180
+ fi
181
+
101
182
  # Check if there are staged changes
102
183
  local has_staged
103
184
  has_staged=$(git diff --cached --name-only)
@@ -105,8 +186,28 @@ EOF
105
186
  local has_unstaged
106
187
  has_unstaged=$(git diff --name-only)
107
188
 
189
+ # For amend mode, we might not need new changes
190
+ if [[ "$amend_mode" == true ]]; then
191
+ if [[ -z "$has_staged" && -z "$has_unstaged" ]]; then
192
+ print_info "Amending commit message only..."
193
+ git commit --amend -m "$msg"
194
+ else
195
+ # Has changes to add
196
+ if [[ "$staged_only" == true ]]; then
197
+ if [[ -z "$has_staged" ]]; then
198
+ print_info "Amending commit message only (no staged changes)..."
199
+ git commit --amend -m "$msg"
200
+ else
201
+ print_info "Amending with staged changes..."
202
+ git commit --amend -m "$msg"
203
+ fi
204
+ else
205
+ print_info "Amending with all changes..."
206
+ git add -A && git commit --amend -m "$msg"
207
+ fi
208
+ fi
108
209
  # If --staged flag is set, only commit staged changes
109
- if [[ "$staged_only" == true ]]; then
210
+ elif [[ "$staged_only" == true ]]; then
110
211
  if [[ -z "$has_staged" ]]; then
111
212
  echo "No staged changes to commit."
112
213
  return 1
@@ -153,31 +254,31 @@ EOF
153
254
  if [[ -n "$remote_commit" && "$local_commit" != "$remote_commit" ]]; then
154
255
  # Check if we're behind the remote
155
256
  if git merge-base --is-ancestor "$local_commit" "$remote_commit" 2>/dev/null; then
156
- echo "Remote has updates. Pulling first..."
257
+ print_info "Remote has updates. Pulling first..."
157
258
  git pull --rebase origin "$current_branch"
158
259
  if [[ $? -ne 0 ]]; then
159
- echo "⚠ Failed to pull remote changes. Please resolve conflicts and try again."
260
+ print_warning "Failed to pull remote changes. Please resolve conflicts and try again."
160
261
  return 1
161
262
  fi
162
- echo "✓ Pulled latest changes."
263
+ print_success "Pulled latest changes."
163
264
  elif ! git merge-base --is-ancestor "$remote_commit" "$local_commit" 2>/dev/null; then
164
265
  # Branches have diverged
165
- echo "Remote has diverged. Pulling with rebase..."
266
+ print_info "Remote has diverged. Pulling with rebase..."
166
267
  git pull --rebase origin "$current_branch"
167
268
  if [[ $? -ne 0 ]]; then
168
- echo "⚠ Failed to pull remote changes. Please resolve conflicts and try again."
269
+ print_warning "Failed to pull remote changes. Please resolve conflicts and try again."
169
270
  return 1
170
271
  fi
171
- echo "✓ Rebased on latest changes."
272
+ print_success "Rebased on latest changes."
172
273
  fi
173
274
  fi
174
275
 
175
- echo "Pushing '$current_branch' to origin..."
276
+ print_info "Pushing '$current_branch' to origin..."
176
277
  git push origin "$current_branch"
177
278
  if [[ $? -eq 0 ]]; then
178
- echo "✓ Successfully pushed '$current_branch' to origin."
279
+ print_success "Successfully pushed '$current_branch' to origin."
179
280
  else
180
- echo "⚠ Failed to push '$current_branch' to origin."
281
+ print_warning "Failed to push '$current_branch' to origin."
181
282
  return 1
182
283
  fi
183
284
  fi
@@ -55,29 +55,8 @@ EOF
55
55
  # -----------------------------
56
56
  # 1. Check prerequisites
57
57
  # -----------------------------
58
- if ! git rev-parse --is-inside-work-tree >/dev/null 2>&1; then
59
- echo "Not inside a git repository."
60
- return 1
61
- fi
62
-
63
- if ! command -v fzf >/dev/null 2>&1; then
64
- echo "fzf is not installed."
65
- prompt_read "Install fzf with Homebrew? (y/N): " ans
66
- case "$ans" in
67
- [yY][eE][sS]|[yY])
68
- echo "Installing fzf with brew..."
69
- if ! command -v brew >/dev/null 2>&1; then
70
- echo "Homebrew is not installed. Aborting."
71
- return 1
72
- fi
73
- brew install fzf || { echo "fzf install failed. Aborting."; return 1; }
74
- ;;
75
- *)
76
- echo "Aborted (skipped fzf installation)."
77
- return 1
78
- ;;
79
- esac
80
- fi
58
+ require_git_repo || return 1
59
+ require_fzf || return 1
81
60
 
82
61
  # -----------------------------
83
62
  # 2. Get commit count
@@ -193,7 +172,7 @@ Showing last $count commits" \
193
172
  prompt_read "Revert these ${#commits_to_revert[@]} commit(s)? (y/N): " confirm
194
173
  case "$confirm" in
195
174
  [yY][eE][sS]|[yY])
196
- echo "Reverting commits..."
175
+ print_info "Reverting commits..."
197
176
 
198
177
  # Reverse the array to revert oldest first (avoids conflicts)
199
178
  local reversed=()
@@ -204,15 +183,15 @@ Showing last $count commits" \
204
183
  for hash in "${reversed[@]}"; do
205
184
  echo "Reverting $hash ..."
206
185
  if git revert --no-edit "$hash"; then
207
- echo "✓ Reverted $hash"
186
+ print_success "Reverted $hash"
208
187
  else
209
- echo "✗ Failed to revert $hash (conflict?)"
188
+ print_error "Failed to revert $hash (conflict?)"
210
189
  echo " Resolve the conflict and run 'git revert --continue'"
211
190
  return 1
212
191
  fi
213
192
  done
214
193
  echo ""
215
- echo "✓ All selected commits reverted."
194
+ print_success "All selected commits reverted."
216
195
  ;;
217
196
  *)
218
197
  echo "Revert cancelled."
@@ -8,24 +8,41 @@ source "$SOURCE_DIR/_utils.sh"
8
8
 
9
9
  create() {
10
10
  # -----------------------------
11
- # 0. Check for help/version flag
11
+ # 0. Check for help/version flag and parse options
12
12
  # -----------------------------
13
- if [[ "${1:-}" == "-v" || "${1:-}" == "--version" ]]; then
14
- echo "gitbash ${FUNCNAME[0]} v$VERSION"
15
- return 0
16
- fi
17
- if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
18
- cat << 'EOF'
19
- Usage: create [JIRA_LINK] [TITLE...]
13
+ local show_type_menu=false
14
+ local branch_type=""
15
+ local positional_args=()
16
+
17
+ while [[ $# -gt 0 ]]; do
18
+ case "$1" in
19
+ -v|--version)
20
+ echo "gitbash ${FUNCNAME[0]} v$VERSION"
21
+ return 0
22
+ ;;
23
+ -h|--help)
24
+ cat << 'EOF'
25
+ Usage: create [OPTIONS] [JIRA_LINK] [TITLE...]
20
26
 
21
- Create a new git branch with the pattern: feature/<ISSUE>-<title>
27
+ Create a new git branch with the pattern: <prefix>/<ISSUE>-<title>
22
28
 
23
29
  Options:
24
- -h, --help Show this help message
30
+ -h, --help Show this help message
31
+ -t, --type Show branch type selector menu (feature, bugfix, hotfix, release)
32
+ --feature Use 'feature/' prefix (default)
33
+ --bugfix Use 'bugfix/' prefix
34
+ --hotfix Use 'hotfix/' prefix
35
+ --release Use 'release/' prefix
25
36
 
26
37
  Configuration:
27
- - Branch prefix can be changed by editing the 'GITBASH_FEATURE_BRANCH_PREFIX' variable
28
- - Default: "feature/"
38
+ - Default branch prefix can be set via GITBASH_FEATURE_BRANCH_PREFIX in ~/.gitbashrc
39
+ - Run 'gitbash --config' to set default prefix
40
+
41
+ Branch Types:
42
+ feature/ - New features and enhancements
43
+ bugfix/ - Bug fixes
44
+ hotfix/ - Urgent production fixes
45
+ release/ - Release preparation branches
29
46
 
30
47
  Interactive mode (no arguments):
31
48
  $ create
@@ -39,6 +56,20 @@ Interactive mode (no arguments):
39
56
  Branch name: feature/PROJ-123-fix-login-bug
40
57
  Create this branch? (y/N): y
41
58
 
59
+ With type selector:
60
+ $ create -t PROJ-123 urgent fix
61
+ Branch type >
62
+ > feature/ - New features and enhancements
63
+ bugfix/ - Bug fixes
64
+ hotfix/ - Urgent production fixes
65
+ release/ - Release preparation branches
66
+
67
+ # Select hotfix/, creates: hotfix/PROJ-123-urgent-fix
68
+
69
+ Quick type flags:
70
+ $ create --bugfix PROJ-456 fix crash
71
+ # Creates: bugfix/PROJ-456-fix-crash
72
+
42
73
  One-liner mode (with arguments):
43
74
  $ create https://jira.company.com/browse/PROJ-123 fix login bug
44
75
  Parsed issue number: PROJ-123
@@ -46,33 +77,99 @@ One-liner mode (with arguments):
46
77
  Branch name: feature/PROJ-123-fix-login-bug
47
78
  Create this branch? (y/N): y
48
79
 
49
- $ create PROJ-456 add user settings
50
- Parsed issue number: PROJ-456
51
-
52
- Branch name: feature/PROJ-456-add-user-settings
53
- Create this branch? (y/N): y
54
-
55
80
  Examples:
56
81
  create https://jira.company.com/browse/PROJ-123 make some fixes
57
82
  create PROJ-456 implement new feature
58
- create https://company.atlassian.net/browse/ABC-789 refactor code
83
+ create -t PROJ-789 some work # Show type menu
84
+ create --hotfix PROJ-999 critical fix # Use hotfix prefix
59
85
 
60
86
  EOF
61
- return 0
87
+ return 0
88
+ ;;
89
+ -t|--type)
90
+ show_type_menu=true
91
+ shift
92
+ ;;
93
+ --feature)
94
+ branch_type="feature/"
95
+ shift
96
+ ;;
97
+ --bugfix)
98
+ branch_type="bugfix/"
99
+ shift
100
+ ;;
101
+ --hotfix)
102
+ branch_type="hotfix/"
103
+ shift
104
+ ;;
105
+ --release)
106
+ branch_type="release/"
107
+ shift
108
+ ;;
109
+ *)
110
+ positional_args+=("$1")
111
+ shift
112
+ ;;
113
+ esac
114
+ done
115
+
116
+ # -----------------------------
117
+ # 1. Determine branch prefix
118
+ # -----------------------------
119
+ local branch_prefix
120
+ if [[ -n "$branch_type" ]]; then
121
+ branch_prefix="$branch_type"
122
+ elif [[ "$show_type_menu" == true ]]; then
123
+ if ! command -v fzf >/dev/null 2>&1; then
124
+ print_error "fzf is required for type selector. Install it or use --feature/--bugfix/--hotfix/--release flags."
125
+ return 1
126
+ fi
127
+
128
+ local type_options
129
+ type_options=$(cat << 'TYPES'
130
+ feature/ - New features and enhancements
131
+ bugfix/ - Bug fixes
132
+ hotfix/ - Urgent production fixes
133
+ release/ - Release preparation branches
134
+ TYPES
135
+ )
136
+
137
+ local selected_type
138
+ selected_type=$(echo "$type_options" | fzf --prompt="Branch type > " \
139
+ -i \
140
+ --reverse \
141
+ --border \
142
+ --header="Select branch type" \
143
+ --no-multi \
144
+ --bind=enter:accept \
145
+ ) </dev/tty || true
146
+
147
+ if [[ -z "$selected_type" ]]; then
148
+ echo "Aborted."
149
+ return 1
150
+ fi
151
+
152
+ # Extract just the prefix (first word)
153
+ branch_prefix=$(echo "$selected_type" | awk '{print $1}')
154
+ else
155
+ branch_prefix="${GITBASH_FEATURE_BRANCH_PREFIX:-feature/}"
62
156
  fi
63
157
 
64
158
  # -----------------------------
65
- # 1. Get Jira link from user (or from arguments)
159
+ # 2. Get Jira link from user (or from arguments)
66
160
  # -----------------------------
67
161
  local jira_link
68
162
  local branch_title
69
163
 
70
- if [[ -n "${1:-}" ]]; then
164
+ if [[ ${#positional_args[@]} -gt 0 ]]; then
71
165
  # Arguments provided - use one-liner mode
72
- jira_link="$1"
73
- shift
166
+ jira_link="${positional_args[0]}"
74
167
  # Join remaining arguments as title
75
- branch_title="$*"
168
+ if [[ ${#positional_args[@]} -gt 1 ]]; then
169
+ branch_title="${positional_args[*]:1}"
170
+ else
171
+ branch_title=""
172
+ fi
76
173
  else
77
174
  # Interactive mode
78
175
  echo "Enter Jira link (e.g., https://jira.company.com/browse/PROJ-123):"
@@ -131,7 +228,7 @@ EOF
131
228
  # -----------------------------
132
229
  # 4. Construct branch name
133
230
  # -----------------------------
134
- local branch_prefix="${GITBASH_FEATURE_BRANCH_PREFIX:-feature/}"
231
+ # branch_prefix is set earlier from type menu, flag, or config
135
232
  local branch_name="${branch_prefix}${issue_number}-${branch_title}"
136
233
 
137
234
  echo
@@ -142,7 +239,7 @@ EOF
142
239
  # 5. Check if branch already exists
143
240
  # -----------------------------
144
241
  if git show-ref --verify --quiet "refs/heads/$branch_name"; then
145
- echo "⚠ Branch '$branch_name' already exists locally."
242
+ print_warning "Branch '$branch_name' already exists locally."
146
243
  prompt_read "Switch to this branch instead? (Y/n): " ans
147
244
  case "$ans" in
148
245
  [nN][oO]|[nN])
@@ -151,7 +248,7 @@ EOF
151
248
  ;;
152
249
  *)
153
250
  git checkout "$branch_name"
154
- echo "✓ Switched to existing branch: $branch_name"
251
+ print_success "Switched to existing branch: $branch_name"
155
252
  return 0
156
253
  ;;
157
254
  esac
@@ -167,37 +264,37 @@ EOF
167
264
  elif git show-ref --verify --quiet refs/heads/master; then
168
265
  base_branch="master"
169
266
  else
170
- echo "⚠ Could not detect 'main' or 'master' branch. Creating branch from current HEAD."
267
+ print_warning "Could not detect 'main' or 'master' branch. Creating branch from current HEAD."
171
268
  base_branch=""
172
269
  fi
173
270
 
174
271
  if [[ -n "$base_branch" ]]; then
175
- echo "Updating '$base_branch' from origin..."
272
+ print_info "Updating '$base_branch' from origin..."
176
273
  if git fetch origin "$base_branch:$base_branch" 2>/dev/null; then
177
- echo "✓ '$base_branch' is up to date."
274
+ print_success "'$base_branch' is up to date."
178
275
  else
179
- echo "⚠ Could not update '$base_branch' from origin. Creating branch from local '$base_branch'."
276
+ print_warning "Could not update '$base_branch' from origin. Creating branch from local '$base_branch'."
180
277
  fi
181
278
  fi
182
279
 
183
280
  # -----------------------------
184
281
  # 7. Create branch
185
282
  # -----------------------------
186
- echo "Creating branch..."
283
+ print_info "Creating branch..."
187
284
  if [[ -n "$base_branch" ]]; then
188
285
  # Create branch from updated base branch
189
286
  if git checkout -b "$branch_name" "$base_branch"; then
190
- echo "✓ Successfully created and switched to branch: $branch_name (from $base_branch)"
287
+ print_success "Successfully created and switched to branch: $branch_name (from $base_branch)"
191
288
  else
192
- echo "✗ Failed to create branch."
289
+ print_error "Failed to create branch."
193
290
  return 1
194
291
  fi
195
292
  else
196
293
  # Fallback: create from current HEAD
197
294
  if git checkout -b "$branch_name"; then
198
- echo "✓ Successfully created and switched to branch: $branch_name"
295
+ print_success "Successfully created and switched to branch: $branch_name"
199
296
  else
200
- echo "✗ Failed to create branch."
297
+ print_error "Failed to create branch."
201
298
  return 1
202
299
  fi
203
300
  fi
@@ -205,10 +302,10 @@ EOF
205
302
  # -----------------------------
206
303
  # 8. Push branch to origin and set up tracking
207
304
  # -----------------------------
208
- echo "Pushing branch to origin and setting up tracking..."
305
+ print_info "Pushing branch to origin and setting up tracking..."
209
306
  if git push -u origin "$branch_name"; then
210
- echo "✓ Successfully pushed '$branch_name' to origin with tracking."
307
+ print_success "Successfully pushed '$branch_name' to origin with tracking."
211
308
  else
212
- echo "⚠ Failed to push branch to origin. You can push it later with: git push -u origin $branch_name"
309
+ print_warning "Failed to push branch to origin. You can push it later with: git push -u origin $branch_name"
213
310
  fi
214
311
  }