gitbash 1.9.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +100 -89
- package/bin/gitbash +345 -723
- package/commands/_utils.sh +485 -157
- package/commands/branch.sh +9 -12
- package/commands/cleanstash.sh +47 -122
- package/commands/cleanup.sh +305 -441
- package/commands/commit.sh +136 -172
- package/commands/commits.sh +81 -114
- package/commands/create.sh +231 -314
- package/commands/pr.sh +158 -146
- package/commands/stale.sh +137 -277
- package/commands/stash.sh +11 -39
- package/commands/stashes.sh +10 -13
- package/commands/status.sh +197 -250
- package/commands/switch.sh +186 -256
- package/commands/unstash.sh +45 -109
- package/commands/update.sh +123 -142
- package/docs/CONTRIBUTING.md +16 -5
- package/docs/SECURITY.md +14 -3
- package/package.json +5 -3
package/commands/create.sh
CHANGED
|
@@ -1,43 +1,60 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
|
-
# shellcheck disable=SC2155
|
|
3
2
|
|
|
4
3
|
# Source common utilities
|
|
5
|
-
SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]
|
|
4
|
+
SOURCE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
6
5
|
# shellcheck source=_utils.sh
|
|
7
6
|
source "$SOURCE_DIR/_utils.sh"
|
|
8
7
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
8
|
+
# Turn free text into a branch-name slug: "Über Café fix!" -> "ueber-cafe-fix"
|
|
9
|
+
# (iconv's transliteration differs between platforms, so common letters are mapped here)
|
|
10
|
+
_create_slugify() {
|
|
11
|
+
local map="ä:ae Ä:ae ö:oe Ö:oe ü:ue Ü:ue ß:ss à:a á:a â:a ã:a å:a À:a Á:a Â:a Ã:a Å:a
|
|
12
|
+
è:e é:e ê:e ë:e È:e É:e Ê:e Ë:e ì:i í:i î:i ï:i Ì:i Í:i Î:i Ï:i
|
|
13
|
+
ò:o ó:o ô:o õ:o ø:o Ò:o Ó:o Ô:o Õ:o Ø:o ù:u ú:u û:u Ù:u Ú:u Û:u ç:c Ç:c ñ:n Ñ:n"
|
|
14
|
+
local script="" pair
|
|
15
|
+
for pair in $map; do
|
|
16
|
+
script+="s/${pair%%:*}/${pair#*:}/g;"
|
|
17
|
+
done
|
|
18
|
+
printf '%s' "$1" | LC_ALL=C sed "$script" |
|
|
19
|
+
LC_ALL=C tr '[:upper:]' '[:lower:]' |
|
|
20
|
+
LC_ALL=C sed 's/[^a-z0-9]/-/g; s/--*/-/g; s/^-//; s/-$//'
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
# Extract a Jira issue key (e.g. PROJ-123, AB2-45) from a key or URL
|
|
24
|
+
_create_parse_issue() {
|
|
25
|
+
local input="$1" key=""
|
|
26
|
+
local re_key='^([A-Za-z][A-Za-z0-9]+-[0-9]+)$'
|
|
27
|
+
local re_url='(browse/|selectedIssue=)([A-Za-z][A-Za-z0-9]+-[0-9]+)'
|
|
28
|
+
if [[ "$input" =~ $re_key ]]; then
|
|
29
|
+
key="${BASH_REMATCH[1]}"
|
|
30
|
+
elif [[ "$input" =~ $re_url ]]; then
|
|
31
|
+
key="${BASH_REMATCH[2]}"
|
|
32
|
+
fi
|
|
33
|
+
[[ -z "$key" ]] && return 1
|
|
34
|
+
printf '%s' "$key" | tr '[:lower:]' '[:upper:]'
|
|
35
|
+
}
|
|
22
36
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
37
|
+
create() {
|
|
38
|
+
local no_issue_parsing="${GITBASH_CREATE_NO_ISSUE_PARSING:-no}"
|
|
39
|
+
local issue_fallback="${GITBASH_CREATE_ISSUE_PARSING_FALLBACK:-NOISSUE}"
|
|
40
|
+
local branch_prefix_config="${GITBASH_CREATE_BRANCH_PREFIX:-}"
|
|
41
|
+
local auto_push="${GITBASH_CREATE_AUTO_PUSH:-yes}"
|
|
42
|
+
|
|
43
|
+
local show_type_menu=false
|
|
44
|
+
local branch_type=""
|
|
45
|
+
local positional_args=()
|
|
46
|
+
|
|
47
|
+
while [[ $# -gt 0 ]]; do
|
|
48
|
+
case "$1" in
|
|
49
|
+
-v|--version)
|
|
50
|
+
echo "gitbash ${FUNCNAME[0]} v$VERSION"
|
|
51
|
+
return 0
|
|
52
|
+
;;
|
|
53
|
+
-h|--help)
|
|
54
|
+
cat << 'EOF'
|
|
38
55
|
Usage: create [OPTIONS] [JIRA_LINK] [TITLE...]
|
|
39
56
|
|
|
40
|
-
Create a new git branch with optional Jira issue parsing.
|
|
57
|
+
Create a new git branch from the latest base branch, with optional Jira issue parsing.
|
|
41
58
|
|
|
42
59
|
Options:
|
|
43
60
|
-h, --help Show this help message
|
|
@@ -46,314 +63,214 @@ Options:
|
|
|
46
63
|
--bugfix Use 'bugfix/' type
|
|
47
64
|
--hotfix Use 'hotfix/' type
|
|
48
65
|
--release Use 'release/' type
|
|
66
|
+
--push Push the new branch to the remote (default: GITBASH_CREATE_AUTO_PUSH)
|
|
67
|
+
--no-push Don't push the new branch
|
|
49
68
|
|
|
50
69
|
Configuration (run 'gitbash --config'):
|
|
51
70
|
- GITBASH_CREATE_BRANCH_PREFIX: Custom prefix between type and issue (default: "")
|
|
52
71
|
- GITBASH_CREATE_NO_ISSUE_PARSING: Disable Jira parsing (yes/no, default: "no")
|
|
53
72
|
- GITBASH_CREATE_ISSUE_PARSING_FALLBACK: Fallback when no issue (default: "NOISSUE")
|
|
54
|
-
|
|
55
|
-
Branch Types:
|
|
56
|
-
feature/ - New features and enhancements
|
|
57
|
-
bugfix/ - Bug fixes
|
|
58
|
-
hotfix/ - Urgent production fixes
|
|
59
|
-
release/ - Release preparation branches
|
|
73
|
+
- GITBASH_CREATE_AUTO_PUSH: Push new branches right away (yes/no, default: "yes")
|
|
60
74
|
|
|
61
75
|
Branch Name Format:
|
|
62
|
-
<type><custom-prefix
|
|
63
|
-
<type><custom-prefix
|
|
64
|
-
|
|
65
|
-
Examples with custom prefix "awesome-team" (no trailing slash needed):
|
|
66
|
-
|
|
67
|
-
With issue parsing enabled (default):
|
|
68
|
-
$ create PROJ-123 fix login bug
|
|
69
|
-
# → feature/awesome-team/PROJ-123-fix-login-bug
|
|
70
|
-
|
|
71
|
-
$ create fix bug
|
|
72
|
-
# → feature/awesome-team/NOISSUE-fix-bug (uses fallback)
|
|
73
|
-
|
|
74
|
-
$ create --hotfix PROJ-999 critical fix
|
|
75
|
-
# → hotfix/awesome-team/PROJ-999-critical-fix
|
|
76
|
-
|
|
77
|
-
With issue parsing disabled (GITBASH_CREATE_NO_ISSUE_PARSING="yes"):
|
|
78
|
-
$ create fix login bug
|
|
79
|
-
# → feature/awesome-team/fix-login-bug
|
|
80
|
-
|
|
81
|
-
$ create --hotfix enhance security
|
|
82
|
-
# → hotfix/awesome-team/enhance-security
|
|
76
|
+
<type><custom-prefix>/<ISSUE>-<title> (with issue parsing)
|
|
77
|
+
<type><custom-prefix>/<title> (without issue parsing)
|
|
83
78
|
|
|
84
|
-
|
|
79
|
+
Issue keys: PROJ-123, AB2-45 or a Jira URL (/browse/KEY or selectedIssue=KEY).
|
|
80
|
+
Titles are lower-cased; umlauts and accents are transliterated (ü → ue, é → e) and other
|
|
81
|
+
characters become dashes.
|
|
85
82
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
83
|
+
Behavior:
|
|
84
|
+
- Fetches the base branch and creates the new branch from '<remote>/<base>'
|
|
85
|
+
(falls back to the current HEAD if that fails)
|
|
86
|
+
- If the branch already exists locally, offers to switch to it
|
|
87
|
+
- If it already exists on the remote, stops (use 'switch' to check it out)
|
|
89
88
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
# → feature/enhance-login-screen
|
|
93
|
-
|
|
94
|
-
Interactive Mode:
|
|
95
|
-
$ create
|
|
96
|
-
# Prompts for Jira link (if parsing enabled) and title
|
|
97
|
-
|
|
98
|
-
More Examples:
|
|
89
|
+
Examples:
|
|
90
|
+
create PROJ-123 fix login bug # feature/PROJ-123-fix-login-bug
|
|
99
91
|
create https://jira.company.com/browse/PROJ-123 make some fixes
|
|
100
|
-
create
|
|
101
|
-
create
|
|
102
|
-
create
|
|
92
|
+
create fix bug # feature/NOISSUE-fix-bug
|
|
93
|
+
create --hotfix PROJ-999 critical fix # hotfix/PROJ-999-critical-fix
|
|
94
|
+
create -t PROJ-789 some work # Show type menu
|
|
103
95
|
|
|
104
96
|
EOF
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
shift
|
|
122
|
-
;;
|
|
123
|
-
--release)
|
|
124
|
-
branch_type="release/"
|
|
125
|
-
shift
|
|
126
|
-
;;
|
|
127
|
-
*)
|
|
128
|
-
positional_args+=("$1")
|
|
129
|
-
shift
|
|
130
|
-
;;
|
|
131
|
-
esac
|
|
132
|
-
done
|
|
133
|
-
|
|
134
|
-
# -----------------------------
|
|
135
|
-
# 1. Determine branch prefix
|
|
136
|
-
# -----------------------------
|
|
137
|
-
local branch_prefix
|
|
138
|
-
if [[ -n "$branch_type" ]]; then
|
|
139
|
-
branch_prefix="$branch_type"
|
|
140
|
-
elif [[ "$show_type_menu" == true ]]; then
|
|
141
|
-
if ! command -v fzf >/dev/null 2>&1; then
|
|
142
|
-
print_error "fzf is required for type selector. Install it or use --feature/--bugfix/--hotfix/--release flags."
|
|
143
|
-
return 1
|
|
144
|
-
fi
|
|
145
|
-
|
|
146
|
-
local type_options
|
|
147
|
-
type_options=$(cat << 'TYPES'
|
|
148
|
-
feature/ - New features and enhancements
|
|
149
|
-
bugfix/ - Bug fixes
|
|
150
|
-
hotfix/ - Urgent production fixes
|
|
151
|
-
release/ - Release preparation branches
|
|
152
|
-
TYPES
|
|
153
|
-
)
|
|
154
|
-
|
|
155
|
-
local selected_type
|
|
156
|
-
selected_type=$(echo "$type_options" | fzf --prompt="Branch type > " \
|
|
157
|
-
-i \
|
|
158
|
-
--reverse \
|
|
159
|
-
--border \
|
|
160
|
-
--header="Select branch type" \
|
|
161
|
-
--no-multi \
|
|
162
|
-
--bind=enter:accept \
|
|
163
|
-
) </dev/tty || true
|
|
164
|
-
|
|
165
|
-
if [[ -z "$selected_type" ]]; then
|
|
166
|
-
echo "Aborted."
|
|
167
|
-
return 1
|
|
168
|
-
fi
|
|
169
|
-
|
|
170
|
-
# Extract just the type prefix (first word)
|
|
171
|
-
branch_prefix=$(echo "$selected_type" | awk '{print $1}')
|
|
172
|
-
else
|
|
173
|
-
# Use default feature/ type
|
|
174
|
-
branch_prefix="feature/"
|
|
175
|
-
fi
|
|
176
|
-
|
|
177
|
-
# -----------------------------
|
|
178
|
-
# 2. Get Jira link from user (or from arguments) - skip if parsing disabled
|
|
179
|
-
# -----------------------------
|
|
180
|
-
local jira_link
|
|
181
|
-
local branch_title
|
|
182
|
-
|
|
183
|
-
if [[ "$no_issue_parsing" == "yes" ]]; then
|
|
184
|
-
# Issue parsing disabled - treat all args as branch title
|
|
185
|
-
if [[ ${#positional_args[@]} -gt 0 ]]; then
|
|
186
|
-
branch_title="${positional_args[*]}"
|
|
187
|
-
fi
|
|
188
|
-
jira_link=""
|
|
189
|
-
elif [[ ${#positional_args[@]} -gt 0 ]]; then
|
|
190
|
-
# Arguments provided - use one-liner mode
|
|
191
|
-
# Use array index 1 for zsh compatibility (zsh arrays are 1-indexed, bash uses 0)
|
|
192
|
-
if [[ -n "${ZSH_VERSION:-}" ]]; then
|
|
193
|
-
jira_link="${positional_args[1]}"
|
|
194
|
-
if [[ ${#positional_args[@]} -gt 1 ]]; then
|
|
195
|
-
branch_title="${positional_args[*]:1}"
|
|
196
|
-
else
|
|
197
|
-
branch_title=""
|
|
198
|
-
fi
|
|
199
|
-
else
|
|
200
|
-
jira_link="${positional_args[0]}"
|
|
201
|
-
if [[ ${#positional_args[@]} -gt 1 ]]; then
|
|
202
|
-
branch_title="${positional_args[*]:1}"
|
|
203
|
-
else
|
|
204
|
-
branch_title=""
|
|
205
|
-
fi
|
|
206
|
-
fi
|
|
207
|
-
else
|
|
208
|
-
# Interactive mode
|
|
209
|
-
echo "Enter Jira link (e.g., https://jira.company.com/browse/PROJ-123) or press Enter to skip:"
|
|
210
|
-
prompt_read " > " jira_link
|
|
211
|
-
fi
|
|
212
|
-
|
|
213
|
-
# -----------------------------
|
|
214
|
-
# 2. Parse issue number from Jira link
|
|
215
|
-
# -----------------------------
|
|
216
|
-
local issue_number
|
|
217
|
-
|
|
218
|
-
if [[ "$no_issue_parsing" == "yes" ]]; then
|
|
219
|
-
# Issue parsing disabled - no issue number in branch name
|
|
220
|
-
issue_number=""
|
|
221
|
-
elif [[ -z "$jira_link" ]]; then
|
|
222
|
-
# No Jira link provided, use configured fallback
|
|
223
|
-
issue_number="$issue_fallback"
|
|
224
|
-
print_info "No Jira link provided. Using $issue_fallback."
|
|
225
|
-
else
|
|
226
|
-
# First try to match just the issue number pattern (e.g., PROJ-123)
|
|
227
|
-
issue_number=$(echo "$jira_link" | grep -o -E '^[A-Z]+-[0-9]+$' | head -1 || true)
|
|
228
|
-
|
|
229
|
-
# If not a direct match, try to extract from URL
|
|
230
|
-
if [[ -z "$issue_number" ]]; then
|
|
231
|
-
# Match patterns like PROJ-123, ABC-456, etc.
|
|
232
|
-
# Supports both /browse/PROJ-123 and selectedIssue=PROJ-123 formats
|
|
233
|
-
issue_number=$(echo "$jira_link" | grep -o -E '(browse/|selectedIssue=)[A-Z]+-[0-9]+' | grep -o '[A-Z]\+-[0-9]\+' | head -1 || true)
|
|
234
|
-
fi
|
|
235
|
-
|
|
236
|
-
if [[ -z "$issue_number" ]]; then
|
|
237
|
-
print_warning "Could not parse issue number from Jira link. Using $issue_fallback."
|
|
238
|
-
issue_number="$issue_fallback"
|
|
239
|
-
# If parsing failed and we had arguments, include the first arg in the title
|
|
240
|
-
if [[ -n "$branch_title" ]]; then
|
|
241
|
-
branch_title="$jira_link $branch_title"
|
|
242
|
-
else
|
|
243
|
-
branch_title="$jira_link"
|
|
244
|
-
fi
|
|
245
|
-
else
|
|
246
|
-
echo "Parsed issue number: $issue_number"
|
|
247
|
-
fi
|
|
248
|
-
fi
|
|
249
|
-
|
|
250
|
-
# -----------------------------
|
|
251
|
-
# 3. Get branch title from user (if not already provided)
|
|
252
|
-
# -----------------------------
|
|
253
|
-
if [[ -z "$branch_title" ]]; then
|
|
254
|
-
echo "Enter branch title (will be converted to lowercase with dashes):"
|
|
255
|
-
prompt_read " > " branch_title
|
|
256
|
-
fi
|
|
257
|
-
|
|
258
|
-
if [[ -z "$branch_title" ]]; then
|
|
259
|
-
echo "Error: No branch title provided."
|
|
97
|
+
return 0
|
|
98
|
+
;;
|
|
99
|
+
-t|--type) show_type_menu=true; shift ;;
|
|
100
|
+
--feature) branch_type="feature/"; shift ;;
|
|
101
|
+
--bugfix) branch_type="bugfix/"; shift ;;
|
|
102
|
+
--hotfix) branch_type="hotfix/"; shift ;;
|
|
103
|
+
--release) branch_type="release/"; shift ;;
|
|
104
|
+
--push) auto_push="yes"; shift ;;
|
|
105
|
+
--no-push) auto_push="no"; shift ;;
|
|
106
|
+
--)
|
|
107
|
+
shift
|
|
108
|
+
positional_args+=("$@")
|
|
109
|
+
break
|
|
110
|
+
;;
|
|
111
|
+
-*)
|
|
112
|
+
print_error "Unknown option: $1"
|
|
260
113
|
return 1
|
|
114
|
+
;;
|
|
115
|
+
*)
|
|
116
|
+
positional_args+=("$1")
|
|
117
|
+
shift
|
|
118
|
+
;;
|
|
119
|
+
esac
|
|
120
|
+
done
|
|
121
|
+
|
|
122
|
+
require_git_repo || return 1
|
|
123
|
+
|
|
124
|
+
# -----------------------------
|
|
125
|
+
# 1. Branch type
|
|
126
|
+
# -----------------------------
|
|
127
|
+
local branch_prefix="feature/"
|
|
128
|
+
if [[ -n "$branch_type" ]]; then
|
|
129
|
+
branch_prefix="$branch_type"
|
|
130
|
+
elif [[ "$show_type_menu" == true ]]; then
|
|
131
|
+
require_fzf || return 1
|
|
132
|
+
local selected_type
|
|
133
|
+
selected_type=$(run_fzf --prompt="Branch type > " \
|
|
134
|
+
-i \
|
|
135
|
+
--reverse \
|
|
136
|
+
--border \
|
|
137
|
+
--header="Select branch type" \
|
|
138
|
+
--no-multi \
|
|
139
|
+
<<< "feature/ - New features and enhancements
|
|
140
|
+
bugfix/ - Bug fixes
|
|
141
|
+
hotfix/ - Urgent production fixes
|
|
142
|
+
release/ - Release preparation branches"
|
|
143
|
+
) || true
|
|
144
|
+
if [[ -z "$selected_type" ]]; then
|
|
145
|
+
echo "Aborted."
|
|
146
|
+
return 0
|
|
261
147
|
fi
|
|
148
|
+
branch_prefix="${selected_type%% *}"
|
|
149
|
+
fi
|
|
262
150
|
|
|
263
|
-
|
|
264
|
-
|
|
151
|
+
# -----------------------------
|
|
152
|
+
# 2. Issue number and title
|
|
153
|
+
# -----------------------------
|
|
154
|
+
local jira_link="" branch_title="" issue_number=""
|
|
265
155
|
|
|
266
|
-
|
|
267
|
-
#
|
|
268
|
-
|
|
269
|
-
# branch_prefix contains the type (feature/, hotfix/, etc.)
|
|
270
|
-
# branch_prefix_config is the custom prefix inserted between type and issue
|
|
271
|
-
# Format: <type>/<custom-prefix>/<issue>-<title> or <type>/<custom-prefix>/<title>
|
|
272
|
-
local branch_name
|
|
273
|
-
local custom_prefix_part=""
|
|
274
|
-
if [[ -n "$branch_prefix_config" ]]; then
|
|
275
|
-
custom_prefix_part="${branch_prefix_config}/"
|
|
156
|
+
if [[ "$no_issue_parsing" == "yes" ]]; then
|
|
157
|
+
if [[ ${#positional_args[@]} -gt 0 ]]; then
|
|
158
|
+
branch_title="${positional_args[*]}"
|
|
276
159
|
fi
|
|
277
|
-
|
|
278
|
-
if [[ -
|
|
279
|
-
|
|
160
|
+
else
|
|
161
|
+
if [[ ${#positional_args[@]} -gt 0 ]]; then
|
|
162
|
+
jira_link="${positional_args[0]}"
|
|
163
|
+
if [[ ${#positional_args[@]} -gt 1 ]]; then
|
|
164
|
+
branch_title="${positional_args[*]:1}"
|
|
165
|
+
fi
|
|
280
166
|
else
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
echo "Branch name: $branch_name"
|
|
285
|
-
|
|
286
|
-
# -----------------------------
|
|
287
|
-
# 5. Check if branch already exists
|
|
288
|
-
# -----------------------------
|
|
289
|
-
if git show-ref --verify --quiet "refs/heads/$branch_name"; then
|
|
290
|
-
print_warning "Branch '$branch_name' already exists locally."
|
|
291
|
-
prompt_read "Switch to this branch instead? (Y/n): " ans
|
|
292
|
-
case "$ans" in
|
|
293
|
-
[nN][oO]|[nN])
|
|
294
|
-
echo "Aborted."
|
|
295
|
-
return 1
|
|
296
|
-
;;
|
|
297
|
-
*)
|
|
298
|
-
git checkout "$branch_name"
|
|
299
|
-
print_success "Switched to existing branch: $branch_name"
|
|
300
|
-
return 0
|
|
301
|
-
;;
|
|
302
|
-
esac
|
|
167
|
+
echo "Enter Jira link or issue key (e.g. PROJ-123), or press Enter to skip:"
|
|
168
|
+
prompt_read " > " jira_link || true
|
|
303
169
|
fi
|
|
304
170
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
if git show-ref --verify --quiet refs/heads/main; then
|
|
311
|
-
base_branch="main"
|
|
312
|
-
elif git show-ref --verify --quiet refs/heads/master; then
|
|
313
|
-
base_branch="master"
|
|
171
|
+
if [[ -z "$jira_link" ]]; then
|
|
172
|
+
issue_number="$issue_fallback"
|
|
173
|
+
print_info "No issue given. Using $issue_fallback."
|
|
174
|
+
elif issue_number=$(_create_parse_issue "$jira_link"); then
|
|
175
|
+
echo "Parsed issue number: $issue_number"
|
|
314
176
|
else
|
|
315
|
-
|
|
316
|
-
|
|
177
|
+
issue_number="$issue_fallback"
|
|
178
|
+
print_warning "No issue key found in '$jira_link'. Using $issue_fallback."
|
|
179
|
+
# The first word was part of the title
|
|
180
|
+
if [[ -n "$branch_title" ]]; then
|
|
181
|
+
branch_title="$jira_link $branch_title"
|
|
182
|
+
else
|
|
183
|
+
branch_title="$jira_link"
|
|
184
|
+
fi
|
|
317
185
|
fi
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
186
|
+
fi
|
|
187
|
+
|
|
188
|
+
if [[ -z "$branch_title" ]]; then
|
|
189
|
+
echo "Enter branch title (will be converted to lowercase with dashes):"
|
|
190
|
+
prompt_read " > " branch_title || true
|
|
191
|
+
fi
|
|
192
|
+
branch_title=$(_create_slugify "$branch_title")
|
|
193
|
+
if [[ -z "$branch_title" ]]; then
|
|
194
|
+
print_error "No branch title provided."
|
|
195
|
+
return 1
|
|
196
|
+
fi
|
|
197
|
+
|
|
198
|
+
# -----------------------------
|
|
199
|
+
# 3. Branch name
|
|
200
|
+
# -----------------------------
|
|
201
|
+
local custom_prefix_part="" branch_name
|
|
202
|
+
if [[ -n "$branch_prefix_config" ]]; then
|
|
203
|
+
custom_prefix_part="${branch_prefix_config}/"
|
|
204
|
+
fi
|
|
205
|
+
if [[ -n "$issue_number" ]]; then
|
|
206
|
+
branch_name="${branch_prefix}${custom_prefix_part}${issue_number}-${branch_title}"
|
|
207
|
+
else
|
|
208
|
+
branch_name="${branch_prefix}${custom_prefix_part}${branch_title}"
|
|
209
|
+
fi
|
|
210
|
+
|
|
211
|
+
if ! git check-ref-format --branch "$branch_name" >/dev/null 2>&1; then
|
|
212
|
+
print_error "'$branch_name' is not a valid branch name. Check GITBASH_CREATE_BRANCH_PREFIX and GITBASH_CREATE_ISSUE_PARSING_FALLBACK."
|
|
213
|
+
return 1
|
|
214
|
+
fi
|
|
215
|
+
echo "Branch name: $branch_name"
|
|
216
|
+
|
|
217
|
+
# -----------------------------
|
|
218
|
+
# 4. Already exists?
|
|
219
|
+
# -----------------------------
|
|
220
|
+
if git show-ref --verify --quiet "refs/heads/$branch_name"; then
|
|
221
|
+
print_warning "Branch '$branch_name' already exists locally."
|
|
222
|
+
if gb_confirm "Switch to it instead?" y; then
|
|
223
|
+
git switch "$branch_name" && print_success "Switched to existing branch: $branch_name"
|
|
224
|
+
return $?
|
|
326
225
|
fi
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
226
|
+
echo "Aborted."
|
|
227
|
+
return 1
|
|
228
|
+
fi
|
|
229
|
+
|
|
230
|
+
local remote
|
|
231
|
+
remote=$(gb_remote)
|
|
232
|
+
if git remote get-url "$remote" >/dev/null 2>&1 &&
|
|
233
|
+
[[ -n "$(git ls-remote --heads "$remote" "refs/heads/$branch_name" 2>/dev/null)" ]]; then
|
|
234
|
+
print_error "Branch '$branch_name' already exists on '$remote'. Use 'switch $branch_title' to check it out."
|
|
235
|
+
return 1
|
|
236
|
+
fi
|
|
237
|
+
|
|
238
|
+
# -----------------------------
|
|
239
|
+
# 5. Create from the latest base branch
|
|
240
|
+
# -----------------------------
|
|
241
|
+
local base_branch start_point=""
|
|
242
|
+
if base_branch=$(gb_base_branch); then
|
|
243
|
+
print_info "Fetching latest '$base_branch' from '$remote'..."
|
|
244
|
+
if git fetch --quiet "$remote" "+refs/heads/$base_branch:refs/remotes/$remote/$base_branch" 2>/dev/null; then
|
|
245
|
+
start_point="$remote/$base_branch"
|
|
246
|
+
elif git show-ref --verify --quiet "refs/heads/$base_branch"; then
|
|
247
|
+
print_warning "Could not fetch '$base_branch'. Creating the branch from local '$base_branch'."
|
|
248
|
+
start_point="$base_branch"
|
|
348
249
|
fi
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
250
|
+
fi
|
|
251
|
+
if [[ -z "$start_point" ]]; then
|
|
252
|
+
print_warning "Could not find the base branch. Creating the branch from the current HEAD."
|
|
253
|
+
fi
|
|
254
|
+
|
|
255
|
+
print_info "Creating branch..."
|
|
256
|
+
if [[ -n "$start_point" ]]; then
|
|
257
|
+
git switch --quiet --no-track -c "$branch_name" "$start_point" || { print_error "Failed to create branch."; return 1; }
|
|
258
|
+
print_success "Created and switched to '$branch_name' (from $start_point)"
|
|
259
|
+
else
|
|
260
|
+
git switch --quiet -c "$branch_name" || { print_error "Failed to create branch."; return 1; }
|
|
261
|
+
print_success "Created and switched to '$branch_name'"
|
|
262
|
+
fi
|
|
263
|
+
|
|
264
|
+
# -----------------------------
|
|
265
|
+
# 6. Push and set up tracking
|
|
266
|
+
# -----------------------------
|
|
267
|
+
if [[ "$auto_push" == "yes" ]]; then
|
|
268
|
+
print_info "Pushing '$branch_name' to '$remote'..."
|
|
269
|
+
if git push --quiet -u "$remote" "$branch_name"; then
|
|
270
|
+
print_success "Pushed '$branch_name' to '$remote' with tracking."
|
|
356
271
|
else
|
|
357
|
-
|
|
272
|
+
print_warning "Failed to push. You can push it later with: git push -u $remote $branch_name"
|
|
358
273
|
fi
|
|
274
|
+
fi
|
|
275
|
+
return 0
|
|
359
276
|
}
|