kk-git 0.1.6 → 0.1.7
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.
- checksums.yaml +4 -4
- data/exe/kk-git +23 -17
- data/lib/kk/git/commit_message.rb +55 -55
- data/lib/kk/git/rake_tasks.rb +20 -20
- data/lib/kk/git/version.rb +1 -1
- metadata +5 -5
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: bf8344aceea8482a3025d31bbcc1293cd6a4fd6aaa3235c3907cf173538e83e5
|
|
4
|
+
data.tar.gz: 553a278a015110d0205d9da2e2df75d83429b169428c23fb1d75ca40a139c140
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: f9a2764f0d336ef4ce214133e63d9b8cad0c68d481d95b88ff0f00feca8d358199a1687c37e95bc563eea8758f85c46ee90f9826621cfe5db168cd75087a46e3
|
|
7
|
+
data.tar.gz: 58e748e4640395c28e9e27c805e36d3b5ed1fc997e55fcfc9c0d4649fdbe593aaf3c22e39d3d25f82acca5408e71516211118691690a288b6181bc8f01a758c6
|
data/exe/kk-git
CHANGED
|
@@ -25,45 +25,51 @@ parser = OptionParser.new do |opts|
|
|
|
25
25
|
opts.banner = "Usage:\n" \
|
|
26
26
|
" kk-git --version\n" \
|
|
27
27
|
" kk-git commit-message [options]\n\n" \
|
|
28
|
-
"
|
|
28
|
+
"Generate Conventional Commits messages from git changes."
|
|
29
29
|
|
|
30
|
-
opts.on('--repo DIR', '
|
|
30
|
+
opts.on('--repo DIR', 'Git repo directory (default: current dir)') { |v| options[:repo_dir] = v }
|
|
31
31
|
|
|
32
|
-
opts.on('--staged', '
|
|
33
|
-
opts.on('--worktree', '
|
|
34
|
-
opts.on('--all', '
|
|
32
|
+
opts.on('--staged', 'Use staged changes only (default)') { options[:mode] = :staged }
|
|
33
|
+
opts.on('--worktree', 'Use working-tree changes only (includes untracked)') { options[:mode] = :worktree }
|
|
34
|
+
opts.on('--all', 'Combine staged + working-tree changes') { options[:mode] = :all }
|
|
35
35
|
|
|
36
|
-
opts.on('--[no-]body', '
|
|
36
|
+
opts.on('--[no-]body', 'Include body for multi-file changes (default: yes)') { |v| options[:include_body] = v }
|
|
37
37
|
|
|
38
|
-
opts.on('--type TYPE', '
|
|
39
|
-
opts.on('--scope SCOPE', '
|
|
40
|
-
opts.on('--subject SUBJECT', '
|
|
41
|
-
opts.on('--[no-]detect-breaking', '
|
|
38
|
+
opts.on('--type TYPE', 'Override inferred type (feat/fix/docs/...)') { |v| options[:type] = v }
|
|
39
|
+
opts.on('--scope SCOPE', 'Override inferred scope') { |v| options[:scope] = v }
|
|
40
|
+
opts.on('--subject SUBJECT', 'Override inferred subject') { |v| options[:subject] = v }
|
|
41
|
+
opts.on('--[no-]detect-breaking', 'Detect BREAKING markers (default: yes)') { |v| options[:detect_breaking] = v }
|
|
42
42
|
|
|
43
|
-
opts.on('--format FORMAT', '
|
|
43
|
+
opts.on('--format FORMAT', 'Output format: text/json (default: text)') do |v|
|
|
44
44
|
options[:format] = v.to_s.downcase.to_sym
|
|
45
45
|
end
|
|
46
46
|
|
|
47
|
-
opts.on('-h', '--help', '
|
|
47
|
+
opts.on('-h', '--help', 'Show help') do
|
|
48
48
|
puts opts
|
|
49
49
|
exit 0
|
|
50
50
|
end
|
|
51
51
|
|
|
52
|
-
opts.on('-v', '--version', '
|
|
52
|
+
opts.on('-v', '--version', 'Show version') do
|
|
53
53
|
puts KKGit::VERSION
|
|
54
54
|
exit 0
|
|
55
55
|
end
|
|
56
56
|
end
|
|
57
57
|
|
|
58
|
-
#
|
|
58
|
+
# Support `kk-git --version` without subcommand
|
|
59
59
|
if ['--version', '-v'].include?(ARGV[0])
|
|
60
60
|
puts KKGit::VERSION
|
|
61
61
|
exit 0
|
|
62
62
|
end
|
|
63
63
|
|
|
64
|
+
# Support `kk-git --help` without subcommand
|
|
65
|
+
if ['--help', '-h'].include?(ARGV[0])
|
|
66
|
+
puts parser
|
|
67
|
+
exit 0
|
|
68
|
+
end
|
|
69
|
+
|
|
64
70
|
subcommand = ARGV.shift
|
|
65
71
|
if subcommand != 'commit-message'
|
|
66
|
-
warn "
|
|
72
|
+
warn "Unknown command: #{subcommand}\n\n#{parser}"
|
|
67
73
|
exit 2
|
|
68
74
|
end
|
|
69
75
|
|
|
@@ -72,8 +78,8 @@ parser.parse!(ARGV)
|
|
|
72
78
|
def to_utf8(str)
|
|
73
79
|
return nil if str.nil?
|
|
74
80
|
s = str.to_s.dup
|
|
75
|
-
# ARGV
|
|
76
|
-
#
|
|
81
|
+
# In some locales ARGV may be tagged as ASCII-8BIT/US-ASCII, but bytes are usually UTF-8.
|
|
82
|
+
# Prefer interpreting bytes as UTF-8 and scrub invalid sequences.
|
|
77
83
|
s.force_encoding(Encoding::UTF_8)
|
|
78
84
|
s.scrub('�')
|
|
79
85
|
end
|
|
@@ -4,13 +4,13 @@ require 'json'
|
|
|
4
4
|
require 'open3'
|
|
5
5
|
|
|
6
6
|
module KKGit
|
|
7
|
-
#
|
|
7
|
+
# Generate Conventional Commits messages from git changes.
|
|
8
8
|
#
|
|
9
|
-
# -
|
|
10
|
-
# -
|
|
11
|
-
# -
|
|
9
|
+
# - Supports staged and working-tree changes
|
|
10
|
+
# - Supports untracked files
|
|
11
|
+
# - Output format: "<type>(<scope>): <subject>\n\n<body>"
|
|
12
12
|
class CommitMessage
|
|
13
|
-
#
|
|
13
|
+
# Change entry (supports rename/copy old/new paths)
|
|
14
14
|
Change = Struct.new(:status, :path, :old_path, :source, keyword_init: true)
|
|
15
15
|
|
|
16
16
|
TYPE_PRIORITY = {
|
|
@@ -25,19 +25,19 @@ module KKGit
|
|
|
25
25
|
'chore' => 9
|
|
26
26
|
}.freeze
|
|
27
27
|
|
|
28
|
-
#
|
|
28
|
+
# Generate a commit message.
|
|
29
29
|
#
|
|
30
|
-
# @param repo_dir [String]
|
|
31
|
-
# @param mode [Symbol] :staged
|
|
32
|
-
# @param include_body [Boolean]
|
|
33
|
-
# @param fallback_scope [String]
|
|
34
|
-
# @param type_override [String, nil]
|
|
35
|
-
# @param scope_override [String, nil]
|
|
36
|
-
# @param subject_override [String, nil]
|
|
37
|
-
# @param detect_breaking [Boolean]
|
|
38
|
-
# @param max_diff_bytes [Integer] diff
|
|
30
|
+
# @param repo_dir [String] git repo directory (default: current dir)
|
|
31
|
+
# @param mode [Symbol] :staged / :worktree / :all
|
|
32
|
+
# @param include_body [Boolean] include body for multi-file changes
|
|
33
|
+
# @param fallback_scope [String] scope used when inference can't decide
|
|
34
|
+
# @param type_override [String, nil] force type (feat/fix/docs/...)
|
|
35
|
+
# @param scope_override [String, nil] force scope
|
|
36
|
+
# @param subject_override [String, nil] force subject
|
|
37
|
+
# @param detect_breaking [Boolean] detect "BREAKING" markers and emit "type(scope)!:" (default: true)
|
|
38
|
+
# @param max_diff_bytes [Integer] cap diff size for breaking detection
|
|
39
39
|
#
|
|
40
|
-
# @return [String, nil]
|
|
40
|
+
# @return [String, nil] returns nil when there are no changes
|
|
41
41
|
def self.generate(
|
|
42
42
|
repo_dir: '.',
|
|
43
43
|
mode: :staged,
|
|
@@ -69,7 +69,7 @@ module KKGit
|
|
|
69
69
|
message
|
|
70
70
|
end
|
|
71
71
|
|
|
72
|
-
#
|
|
72
|
+
# Generate structured data (useful for scripts/CI).
|
|
73
73
|
#
|
|
74
74
|
# @return [Hash]
|
|
75
75
|
def self.generate_hash(
|
|
@@ -169,7 +169,7 @@ module KKGit
|
|
|
169
169
|
end
|
|
170
170
|
|
|
171
171
|
def self.normalize_and_dedup(changes)
|
|
172
|
-
#
|
|
172
|
+
# Keyed by new_path; same path can show up in staged + worktree.
|
|
173
173
|
dedup = {}
|
|
174
174
|
changes.each do |c|
|
|
175
175
|
next if c.path.nil? || c.path.strip.empty?
|
|
@@ -181,10 +181,10 @@ module KKGit
|
|
|
181
181
|
next
|
|
182
182
|
end
|
|
183
183
|
|
|
184
|
-
#
|
|
185
|
-
# - staged
|
|
186
|
-
# - rename/copy
|
|
187
|
-
# - A(
|
|
184
|
+
# Priority:
|
|
185
|
+
# - staged wins over worktree (closer to what will be committed)
|
|
186
|
+
# - rename/copy wins over plain modifications
|
|
187
|
+
# - A(add) wins over M(modify)
|
|
188
188
|
priority = change_priority(c)
|
|
189
189
|
existing_priority = change_priority(existing)
|
|
190
190
|
dedup[key] = c if priority < existing_priority
|
|
@@ -212,16 +212,16 @@ module KKGit
|
|
|
212
212
|
|
|
213
213
|
def self.run_git(args, repo_dir:)
|
|
214
214
|
stdout, stderr, status = Open3.capture3('git', *args, chdir: repo_dir)
|
|
215
|
-
# Open3
|
|
215
|
+
# Open3 stdout/stderr may be ASCII-8BIT (BINARY). Normalize to UTF-8 to avoid concat errors.
|
|
216
216
|
stdout = stdout.to_s.encode(Encoding::UTF_8, invalid: :replace, undef: :replace, replace: '�')
|
|
217
217
|
stderr = stderr.to_s.encode(Encoding::UTF_8, invalid: :replace, undef: :replace, replace: '�')
|
|
218
218
|
|
|
219
|
-
raise "git #{args.join(' ')}
|
|
219
|
+
raise "git #{args.join(' ')} failed: #{stderr.strip}" unless status.success?
|
|
220
220
|
|
|
221
221
|
stdout
|
|
222
222
|
end
|
|
223
223
|
|
|
224
|
-
#
|
|
224
|
+
# Infer type/scope/subject (with optional breaking detection)
|
|
225
225
|
#
|
|
226
226
|
# @return [Hash] {:type,:scope,:subject,:breaking}
|
|
227
227
|
def self.infer(changes:, repo_dir:, mode:, detect_breaking:, max_diff_bytes:, fallback_scope:)
|
|
@@ -243,14 +243,14 @@ module KKGit
|
|
|
243
243
|
return fallback_scope if uniq.empty?
|
|
244
244
|
return uniq.first if uniq.length == 1
|
|
245
245
|
|
|
246
|
-
#
|
|
246
|
+
# When multiple scopes exist, prefer "repo"; otherwise fallback.
|
|
247
247
|
return 'repo' if uniq.include?('repo')
|
|
248
248
|
|
|
249
249
|
fallback_scope
|
|
250
250
|
end
|
|
251
251
|
|
|
252
252
|
def self.infer_scope(paths, fallback_scope:)
|
|
253
|
-
#
|
|
253
|
+
# Tooling/script/build changes: prefer a stable scope
|
|
254
254
|
if paths.any? && paths.all? { |p| tooling_path?(p) || doc_path?(p) || ci_path?(p) }
|
|
255
255
|
return 'tools'
|
|
256
256
|
end
|
|
@@ -261,7 +261,7 @@ module KKGit
|
|
|
261
261
|
return uniq.first if uniq.length == 1
|
|
262
262
|
return 'repo' if uniq.include?('repo')
|
|
263
263
|
|
|
264
|
-
#
|
|
264
|
+
# Multiple top-level dirs: use repo to keep scope stable/short.
|
|
265
265
|
'repo'
|
|
266
266
|
end
|
|
267
267
|
|
|
@@ -277,7 +277,7 @@ module KKGit
|
|
|
277
277
|
def self.infer_type(changes)
|
|
278
278
|
paths = changes.map(&:path)
|
|
279
279
|
|
|
280
|
-
#
|
|
280
|
+
# Fast paths
|
|
281
281
|
only_docs = paths.all? { |p| doc_path?(p) }
|
|
282
282
|
return 'docs' if only_docs
|
|
283
283
|
|
|
@@ -290,12 +290,12 @@ module KKGit
|
|
|
290
290
|
only_deps = paths.all? { |p| deps_path?(p) }
|
|
291
291
|
return 'chore' if only_deps
|
|
292
292
|
|
|
293
|
-
#
|
|
293
|
+
# Tooling/script/build related: prefer chore (even if code is added)
|
|
294
294
|
if paths.any? && paths.all? { |p| tooling_path?(p) || doc_path?(p) || ci_path?(p) || deps_path?(p) }
|
|
295
295
|
return 'chore'
|
|
296
296
|
end
|
|
297
297
|
|
|
298
|
-
#
|
|
298
|
+
# Heuristics for code changes
|
|
299
299
|
has_code = paths.any? { |p| code_path?(p) }
|
|
300
300
|
has_new_code = changes.any? { |c| c.status == 'A' && code_path?(c.path) }
|
|
301
301
|
has_fix_keyword = paths.any? { |p| p.match?(/fix|bug|error|issue/i) }
|
|
@@ -305,7 +305,7 @@ module KKGit
|
|
|
305
305
|
return 'fix' if has_code && has_fix_keyword
|
|
306
306
|
return 'refactor' if has_code && has_delete
|
|
307
307
|
|
|
308
|
-
#
|
|
308
|
+
# Mixed: aggregate by priority
|
|
309
309
|
types = changes.map { |c| type_by_path(c.path) }
|
|
310
310
|
pick_main_type(types)
|
|
311
311
|
end
|
|
@@ -321,7 +321,7 @@ module KKGit
|
|
|
321
321
|
|
|
322
322
|
return 'chore' unless code_path?(path)
|
|
323
323
|
|
|
324
|
-
#
|
|
324
|
+
# Default: treat code changes as fix (conservative). Adds are handled as feat by infer_type.
|
|
325
325
|
'fix'
|
|
326
326
|
end
|
|
327
327
|
|
|
@@ -409,11 +409,11 @@ module KKGit
|
|
|
409
409
|
c = changes.first
|
|
410
410
|
action =
|
|
411
411
|
case c.status
|
|
412
|
-
when 'A' then '
|
|
413
|
-
when 'D' then '
|
|
414
|
-
when 'R' then '
|
|
415
|
-
when 'C' then '
|
|
416
|
-
else '
|
|
412
|
+
when 'A' then 'Add'
|
|
413
|
+
when 'D' then 'Remove'
|
|
414
|
+
when 'R' then 'Rename'
|
|
415
|
+
when 'C' then 'Copy'
|
|
416
|
+
else 'Update'
|
|
417
417
|
end
|
|
418
418
|
|
|
419
419
|
if %w[R C].include?(c.status) && c.old_path
|
|
@@ -424,21 +424,21 @@ module KKGit
|
|
|
424
424
|
|
|
425
425
|
label =
|
|
426
426
|
case scope
|
|
427
|
-
when 'repo' then '
|
|
428
|
-
when 'tools' then '
|
|
427
|
+
when 'repo' then 'project'
|
|
428
|
+
when 'tools' then 'tools'
|
|
429
429
|
else scope
|
|
430
430
|
end
|
|
431
431
|
|
|
432
432
|
case type
|
|
433
|
-
when 'feat' then "
|
|
434
|
-
when 'fix' then "
|
|
435
|
-
when 'docs' then "
|
|
436
|
-
when 'refactor' then "
|
|
437
|
-
when 'style' then "
|
|
438
|
-
when 'perf' then "
|
|
439
|
-
when 'test' then "
|
|
440
|
-
when 'ci' then "
|
|
441
|
-
else "
|
|
433
|
+
when 'feat' then "Add #{label} features"
|
|
434
|
+
when 'fix' then "Fix #{label} issues"
|
|
435
|
+
when 'docs' then "Update #{label} docs"
|
|
436
|
+
when 'refactor' then "Refactor #{label}"
|
|
437
|
+
when 'style' then "Format #{label}"
|
|
438
|
+
when 'perf' then "Improve #{label} performance"
|
|
439
|
+
when 'test' then "Update #{label} tests"
|
|
440
|
+
when 'ci' then "Update #{label} CI"
|
|
441
|
+
else "Update #{label}"
|
|
442
442
|
end
|
|
443
443
|
end
|
|
444
444
|
|
|
@@ -458,12 +458,12 @@ module KKGit
|
|
|
458
458
|
end
|
|
459
459
|
|
|
460
460
|
lines = []
|
|
461
|
-
append_group(lines, '
|
|
462
|
-
append_group(lines, '
|
|
463
|
-
append_group(lines, '
|
|
464
|
-
append_group(lines, '
|
|
465
|
-
append_group(lines, '
|
|
466
|
-
append_group(lines, '
|
|
461
|
+
append_group(lines, 'Added', groups['A'])
|
|
462
|
+
append_group(lines, 'Changed', groups['M'])
|
|
463
|
+
append_group(lines, 'Removed', groups['D'])
|
|
464
|
+
append_group(lines, 'Renamed', groups['R'])
|
|
465
|
+
append_group(lines, 'Copied', groups['C'])
|
|
466
|
+
append_group(lines, 'Other', groups['?'])
|
|
467
467
|
lines.join("\n")
|
|
468
468
|
end
|
|
469
469
|
|
data/lib/kk/git/rake_tasks.rb
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require 'rake'
|
|
4
|
-
|
|
4
|
+
require_relative '../git'
|
|
5
5
|
require 'open3'
|
|
6
6
|
require 'tempfile'
|
|
7
7
|
|
|
8
8
|
module KKGit
|
|
9
|
-
# Rake
|
|
9
|
+
# Rake integration: `require 'kk/git/rake_tasks'` to register tasks.
|
|
10
10
|
#
|
|
11
|
-
#
|
|
12
|
-
# -
|
|
13
|
-
# -
|
|
11
|
+
# Notes:
|
|
12
|
+
# - These tasks do NOT exit/abort so they can be invoked by other tasks.
|
|
13
|
+
# - The generated message is stored in `ENV['KK_GIT_COMMIT_MESSAGE']`.
|
|
14
14
|
module RakeTasks
|
|
15
15
|
def self.run_cmd(*cmd)
|
|
16
16
|
stdout, stderr, status = Open3.capture3(*cmd)
|
|
@@ -20,7 +20,7 @@ module KKGit
|
|
|
20
20
|
def self.ensure_ok!(ok, title, stdout: nil, stderr: nil)
|
|
21
21
|
return if ok
|
|
22
22
|
|
|
23
|
-
msg = +"#{title}
|
|
23
|
+
msg = +"#{title} failed"
|
|
24
24
|
msg << "\n#{stderr}" unless stderr.to_s.strip.empty?
|
|
25
25
|
msg << "\n#{stdout}" unless stdout.to_s.strip.empty?
|
|
26
26
|
raise msg
|
|
@@ -28,13 +28,13 @@ module KKGit
|
|
|
28
28
|
|
|
29
29
|
def self.current_branch
|
|
30
30
|
out, err, ok = run_cmd('git', 'rev-parse', '--abbrev-ref', 'HEAD')
|
|
31
|
-
ensure_ok!(ok, '
|
|
31
|
+
ensure_ok!(ok, 'Get current branch', stdout: out, stderr: err)
|
|
32
32
|
out.strip
|
|
33
33
|
end
|
|
34
34
|
|
|
35
35
|
def self.working_tree_clean?
|
|
36
36
|
out, err, ok = run_cmd('git', 'status', '--porcelain')
|
|
37
|
-
ensure_ok!(ok, '
|
|
37
|
+
ensure_ok!(ok, 'Check git status', stdout: out, stderr: err)
|
|
38
38
|
out.strip.empty?
|
|
39
39
|
end
|
|
40
40
|
|
|
@@ -42,31 +42,31 @@ module KKGit
|
|
|
42
42
|
extend Rake::DSL
|
|
43
43
|
|
|
44
44
|
namespace :git do
|
|
45
|
-
desc '
|
|
45
|
+
desc 'Generate commit message from staged changes (Conventional Commits)'
|
|
46
46
|
task :commit_message do
|
|
47
47
|
msg = KKGit::CommitMessage.generate(mode: :staged)
|
|
48
48
|
ENV['KK_GIT_COMMIT_MESSAGE'] = msg.to_s
|
|
49
49
|
puts msg if msg
|
|
50
50
|
end
|
|
51
51
|
|
|
52
|
-
desc '
|
|
52
|
+
desc 'Generate commit message from working-tree changes (includes untracked)'
|
|
53
53
|
task :commit_message_worktree do
|
|
54
54
|
msg = KKGit::CommitMessage.generate(mode: :worktree)
|
|
55
55
|
ENV['KK_GIT_COMMIT_MESSAGE'] = msg.to_s
|
|
56
56
|
puts msg if msg
|
|
57
57
|
end
|
|
58
58
|
|
|
59
|
-
desc '
|
|
59
|
+
desc 'Generate commit message from staged + working-tree changes'
|
|
60
60
|
task :auto_commit do
|
|
61
61
|
msg = KKGit::CommitMessage.generate(mode: :all)
|
|
62
62
|
ENV['KK_GIT_COMMIT_MESSAGE'] = msg.to_s
|
|
63
63
|
puts msg if msg
|
|
64
64
|
end
|
|
65
65
|
|
|
66
|
-
desc '
|
|
66
|
+
desc 'Auto add/commit/pull/push (uses git:auto_commit)'
|
|
67
67
|
task :auto_commit_push do
|
|
68
68
|
if working_tree_clean?
|
|
69
|
-
puts '
|
|
69
|
+
puts 'No changes to commit'
|
|
70
70
|
next
|
|
71
71
|
end
|
|
72
72
|
|
|
@@ -77,28 +77,28 @@ module KKGit
|
|
|
77
77
|
out, err, ok = run_cmd('git', 'add', '.')
|
|
78
78
|
ensure_ok!(ok, 'git add', stdout: out, stderr: err)
|
|
79
79
|
|
|
80
|
-
# 2)
|
|
80
|
+
# 2) generate commit message (allow re-invoke)
|
|
81
81
|
Rake::Task['git:auto_commit'].reenable
|
|
82
82
|
Rake::Task['git:auto_commit'].invoke
|
|
83
83
|
commit_message = ENV['KK_GIT_COMMIT_MESSAGE'].to_s.strip
|
|
84
|
-
commit_message = "chore(repo):
|
|
84
|
+
commit_message = "chore(repo): update project files\n\n#{Time.now}" if commit_message.empty?
|
|
85
85
|
|
|
86
|
-
# 3) commit
|
|
86
|
+
# 3) commit (use a tempfile to avoid escaping issues)
|
|
87
87
|
Tempfile.create('commit_message') do |f|
|
|
88
88
|
f.write(commit_message)
|
|
89
89
|
f.flush
|
|
90
90
|
out, err, ok = run_cmd('git', 'commit', '-F', f.path)
|
|
91
|
-
#
|
|
91
|
+
# If there are no staged changes, git commit fails; show a friendlier message.
|
|
92
92
|
unless ok
|
|
93
93
|
if err.include?('nothing to commit') || out.include?('nothing to commit')
|
|
94
|
-
puts '
|
|
94
|
+
puts 'No staged changes to commit'
|
|
95
95
|
next
|
|
96
96
|
end
|
|
97
97
|
end
|
|
98
98
|
ensure_ok!(ok, 'git commit', stdout: out, stderr: err)
|
|
99
99
|
end
|
|
100
100
|
|
|
101
|
-
# 4) pull
|
|
101
|
+
# 4) pull (default: --ff-only to avoid interactive merges)
|
|
102
102
|
pull_args = ENV.fetch('KK_GIT_PULL_ARGS', '--ff-only').split
|
|
103
103
|
out, err, ok = run_cmd('git', 'pull', *pull_args)
|
|
104
104
|
ensure_ok!(ok, 'git pull', stdout: out, stderr: err)
|
|
@@ -107,7 +107,7 @@ module KKGit
|
|
|
107
107
|
out, err, ok = run_cmd('git', 'push', remote, branch)
|
|
108
108
|
ensure_ok!(ok, 'git push', stdout: out, stderr: err)
|
|
109
109
|
|
|
110
|
-
puts "
|
|
110
|
+
puts "Pushed: #{remote} #{branch}"
|
|
111
111
|
end
|
|
112
112
|
end
|
|
113
113
|
end
|
data/lib/kk/git/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: kk-git
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.1.
|
|
4
|
+
version: 0.1.7
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- kk
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: exe
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-01-
|
|
11
|
+
date: 2026-01-25 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
|
-
description:
|
|
14
|
-
Rake
|
|
13
|
+
description: Generate Conventional Commits commit messages from current git changes
|
|
14
|
+
(staged/worktree), designed for Rake/script usage.
|
|
15
15
|
email:
|
|
16
16
|
- ''
|
|
17
17
|
executables:
|
|
@@ -47,5 +47,5 @@ requirements: []
|
|
|
47
47
|
rubygems_version: 3.5.22
|
|
48
48
|
signing_key:
|
|
49
49
|
specification_version: 4
|
|
50
|
-
summary: Git
|
|
50
|
+
summary: 'Git helper: generate Conventional Commits messages'
|
|
51
51
|
test_files: []
|