hiiro 0.1.93 → 0.1.94

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8f361a37f0791f6a855fe07229596c3f8848f13b82e2ee6c0fb55ae707a3a001
4
- data.tar.gz: 81be58360c900b6d74e3d33a59cfbe052a8ef8be823cc8143e9b6709c3c10e22
3
+ metadata.gz: 215c78065501f35e2e1e6534dd08a3adfc9d58b62650bf65be84c32004bcf651
4
+ data.tar.gz: b27dcfdb0aba3dc63d2d102c0d62dc67a4bc8176f304499e49574c7db28ea340
5
5
  SHA512:
6
- metadata.gz: 13bf9c867a91ae8c3cf006012d769212b16c1c17bf02cc4613f41e40faf50a2de88e0ab669e0dfa50ca7e5ca6ef4ef5a10f84a4acfa03f50e2dbf1c3e3c68750
7
- data.tar.gz: fe045f0ad9b13b19705f2e80e2b3dbe5fc36fb00bbe6eefb99f33d7bb6e76fe789bb1ed410539731f47a1bf69d0efb2eb81b8bb949a1d99c7a78599af763fdc6
6
+ metadata.gz: 361003e1b599d031c386aaad3f4fb476267f336193f89ae113dd9e5d96a3a609385068b29ba41c9d8bd8dd7899aa0ca10dbf639a4a05295cee10e38a011a375b
7
+ data.tar.gz: 1d1aa957c67ff43adc4194397e5e4ff8e789e76792e2a2f758139903bb8f5934856115f122755e0ba92fa87a1f229a5a57d69896b808de77effc511563633cfd
data/CLAUDE.md CHANGED
@@ -69,12 +69,14 @@ Plugins auto-load from `~/.config/hiiro/plugins/`. Load order matters when plugi
69
69
 
70
70
  ### Global Values Pattern
71
71
 
72
- Values passed to `Hiiro.init()` are available in subcommand handlers:
72
+ Values passed to `Hiiro.run()` are available in subcommand handlers:
73
73
 
74
74
  ```ruby
75
- hiiro = Hiiro.init(*ARGV, cwd: Dir.pwd)
76
- hiiro.add_subcmd(:pwd) do |*args, **values|
77
- puts values[:cwd]
75
+ Hiiro.run(*ARGV, cwd: Dir.pwd) do
76
+ add_subcmd(:pwd) { |*args|
77
+ cwd = get_value(:cwd)
78
+ puts cwd
79
+ }
78
80
  end
79
81
  ```
80
82
 
@@ -126,10 +128,10 @@ end
126
128
  def self.build_hiiro(parent_hiiro, tm)
127
129
  bin_name = [parent_hiiro.bin, parent_hiiro.subcmd || ''].join('-')
128
130
 
129
- Hiiro.init(bin_name:, args: parent_hiiro.args) do |h|
130
- h.add_subcmd(:list) { tm.list }
131
- h.add_subcmd(:start) { |name| tm.start_task(name) }
132
- h.add_subcmd(:switch) { |name=nil|
131
+ Hiiro.run(bin_name:, args: parent_hiiro.args) do
132
+ add_subcmd(:list) { tm.list }
133
+ add_subcmd(:start) { |name| tm.start_task(name) }
134
+ add_subcmd(:switch) { |name=nil|
133
135
  name ||= tm.select_task_interactive
134
136
  tm.switch_to_task(tm.task_by_name(name))
135
137
  }
@@ -150,7 +152,7 @@ The `lib/hiiro.rb` file and `lib/hiiro/` directory contain the core framework cl
150
152
 
151
153
  Main entry point with class methods:
152
154
  - `Hiiro.run(*ARGV, plugins: [...]) { ... }` - Initialize and run immediately
153
- - `Hiiro.init(*ARGV, plugins: [...]) { ... }` - Initialize without running (returns hiiro instance)
155
+ - `Hiiro.init(*ARGV, plugins: [...]) { ... }` - Initialize without running (returns hiiro instance). **NEVER USE THIS** without a good reason, always favor `Hiiro.run`
154
156
 
155
157
  Instance methods available in subcommand blocks:
156
158
  - `git` - Returns `Hiiro::Git` instance for git operations
@@ -264,3 +266,17 @@ All config lives in `~/.config/hiiro/`:
264
266
  - `tasks/` - Task metadata for worktree management
265
267
  - `projects.yml` - Project directory aliases
266
268
  - `apps.yml` - App directory mappings for task plugin
269
+
270
+
271
+ # Groups of files
272
+
273
+ ## tmux-related files
274
+
275
+ - bin/h-buffer
276
+ - bin/h-pane
277
+ - bin/h-window
278
+ - bin/h-session
279
+ - lib/hiiro/tmux.rb
280
+ - lib/hiiro/tmux/*
281
+
282
+
data/bin/h-branch CHANGED
@@ -5,7 +5,6 @@ require "fileutils"
5
5
  require "yaml"
6
6
 
7
7
  Hiiro.load_env
8
- hiiro = Hiiro.init(*ARGV, plugins: [Tasks])
9
8
 
10
9
  class BranchManager
11
10
  attr_reader :hiiro
@@ -117,344 +116,284 @@ class BranchManager
117
116
  end
118
117
  end
119
118
 
120
- manager = BranchManager.new(hiiro)
119
+ Hiiro.run(*ARGV, plugins: [Tasks]) do
120
+ manager = BranchManager.new(self)
121
121
 
122
- hiiro.add_subcmd(:edit) { system(ENV['EDITOR'] || 'nvim', __FILE__) }
123
- hiiro.add_subcmd(:save) { manager.save }
124
- hiiro.add_subcmd(:current) { print `git branch --show-current` }
125
- hiiro.add_subcmd(:info) { manager.current }
126
- hiiro.add_subcmd(:select) do |*args|
127
- branches = hiiro.git.branches(sort_by: 'authordate', ignore_case: true)
122
+ add_subcmd(:edit) { system(ENV['EDITOR'] || 'nvim', __FILE__) }
123
+ add_subcmd(:save) { manager.save }
124
+ add_subcmd(:current) { print `git branch --show-current` }
125
+ add_subcmd(:info) { manager.current }
128
126
 
129
- lines = branches.each_with_object({}) do |name, h|
130
- h[" #{name}"] = name
131
- end
132
-
133
- if args.any?
134
- lines = hash_matches?(lines, *args)
135
- end
136
-
137
- require 'open3'
138
- selected, status = Open3.capture2('sk', '--no-sort', '--tac', stdin_data: lines.keys.join("\n"))
139
-
140
- if status.success? && !selected.strip.empty?
141
- puts lines[selected.chomp]
142
- end
143
- end
127
+ add_subcmd(:select) do |*select_args|
128
+ branches = git.branches(sort_by: 'authordate', ignore_case: true)
144
129
 
145
- checkout_branch = lambda { |branch = nil, *args|
146
- unless branch
147
- # Use sk to select a branch
148
- branches = hiiro.git.branches(sort_by: 'authordate', ignore_case: true)
149
- require 'open3'
150
- selected, status = Open3.capture2('sk', '--no-sort', '--tac', stdin_data: branches.join("\n"))
151
- unless status.success? && !selected.strip.empty?
152
- puts "No branch selected"
153
- next
130
+ lines = branches.each_with_object({}) do |name, h|
131
+ h[" #{name}"] = name
154
132
  end
155
- branch = selected.strip
156
- end
157
-
158
- system('git', 'checkout', branch, *args)
159
- }
160
-
161
- hiiro.add_subcmd(:checkout, &checkout_branch)
162
- hiiro.add_subcmd(:co, &checkout_branch)
163
133
 
164
- remove_branch = lambda { |branch = nil, *args|
165
- unless branch
166
- # Use sk to select a branch
167
- branches = hiiro.git.branches(sort_by: 'authordate', ignore_case: true)
168
- require 'open3'
169
- selected, status = Open3.capture2('sk', '--no-sort', '--tac', stdin_data: branches.join("\n"))
170
- unless status.success? && !selected.strip.empty?
171
- puts "No branch selected"
172
- next
134
+ if select_args.any?
135
+ lines = hash_matches?(lines, *select_args)
173
136
  end
174
- branch = selected.strip
175
- end
176
137
 
177
- system('git', 'branch', '-d', branch, *args)
178
- }
179
-
180
- hiiro.add_subcmd(:remove, &remove_branch)
181
- hiiro.add_subcmd(:rm, &remove_branch)
138
+ require 'open3'
139
+ selected, status = Open3.capture2('sk', '--no-sort', '--tac', stdin_data: lines.keys.join("\n"))
182
140
 
183
- hiiro.add_subcmd(:duplicate) { |new_name = nil, source = nil|
184
- unless new_name
185
- puts "Usage: h branch duplicate <new_name> [source_branch]"
186
- puts " Creates a copy of source_branch (or current branch) as new_name"
187
- next
141
+ if status.success? && !selected.strip.empty?
142
+ puts lines[selected.chomp]
143
+ end
188
144
  end
189
145
 
190
- source ||= hiiro.git.branch
191
- system('git', 'branch', new_name, source)
192
- puts "Created branch '#{new_name}' from '#{source}'"
193
- }
194
-
195
- hiiro.add_subcmd(:test) { |*args|
196
- opts = Hiiro::Options.parse(args) do
197
- option :remote, short: 'r', default: 'origin', desc: 'Remote name'
198
- option :from, short: 'f', desc: 'Local branch or commit to push'
199
- option :to, short: 't', desc: 'Remote branch name'
200
- flag :force, short: 'F', desc: 'Force push'
201
- flag :set_upstream, short: 'u', desc: 'Set upstream tracking'
202
- end
146
+ checkout_branch = lambda { |branch = nil, *checkout_args|
147
+ unless branch
148
+ # Use sk to select a branch
149
+ branches = git.branches(sort_by: 'authordate', ignore_case: true)
150
+ require 'open3'
151
+ selected, status = Open3.capture2('sk', '--no-sort', '--tac', stdin_data: branches.join("\n"))
152
+ unless status.success? && !selected.strip.empty?
153
+ puts "No branch selected"
154
+ next
155
+ end
156
+ branch = selected.strip
157
+ end
203
158
 
204
- if opts.help?
205
- hiiro.help(opts)
206
- return
207
- end
159
+ system('git', 'checkout', branch, *checkout_args)
160
+ }
208
161
 
209
- {
210
- remote_as_method: opts.remote,
211
- remote_as_sym_key: opts[:remote],
212
- remote_as_string_key: opts['remote'],
213
- force_as_method: opts.force,
214
- force_as_sym_key: opts[:force],
215
- force_as_string_key: opts['force'],
216
- }.each do |k,v|
217
- puts "#{k} => #{v}"
218
- end
219
- }
220
-
221
- hiiro.add_subcmd(:push) { |*args|
222
- opts = Hiiro::Options.parse(args) do
223
- option :remote, short: 'r', default: 'origin', desc: 'Remote name'
224
- option :from, short: 'f', desc: 'Local branch or commit to push'
225
- option :to, short: 't', desc: 'Remote branch name'
226
- flag :force, short: 'F', desc: 'Force push'
227
- flag :set_upstream, short: 'u', desc: 'Set upstream tracking'
228
- end
162
+ add_subcmd(:checkout, &checkout_branch)
163
+ add_subcmd(:co, &checkout_branch)
164
+
165
+ remove_branch = lambda { |branch = nil, *remove_args|
166
+ unless branch
167
+ # Use sk to select a branch
168
+ branches = git.branches(sort_by: 'authordate', ignore_case: true)
169
+ require 'open3'
170
+ selected, status = Open3.capture2('sk', '--no-sort', '--tac', stdin_data: branches.join("\n"))
171
+ unless status.success? && !selected.strip.empty?
172
+ puts "No branch selected"
173
+ next
174
+ end
175
+ branch = selected.strip
176
+ end
229
177
 
230
- local_ref = opts[:from] || hiiro.git.branch
231
- remote_branch = opts[:to] || local_ref
232
-
233
- git_args = ['git', 'push']
234
- git_args << '--force' if opts[:force]
235
- git_args << '-u' if opts[:set_upstream]
236
- git_args << opts[:remote]
237
- git_args << "#{local_ref}:#{remote_branch}"
238
-
239
- puts "Pushing #{local_ref} to #{opts[:remote]}/#{remote_branch}..."
240
- system(*git_args)
241
- }
242
-
243
- hiiro.add_subcmd(:diff) { |*args|
244
- case args.length
245
- when 0
246
- # Compare current branch to main/master
247
- base = %w[main master].find { |b| system("git rev-parse --verify #{b} >/dev/null 2>&1") } || 'HEAD~1'
248
- range = "#{base}..HEAD"
249
- when 1
250
- # Compare current branch to specified ref
251
- range = "#{args[0]}..HEAD"
252
- else
253
- # Compare two refs (from..to or from...to based on args)
254
- from, to = args[0..1]
255
- range = "#{from}..#{to}"
256
- end
178
+ system('git', 'branch', '-d', branch, *remove_args)
179
+ }
257
180
 
258
- system('git', 'log', '--oneline', '--decorate', range)
259
- }
181
+ add_subcmd(:remove, &remove_branch)
182
+ add_subcmd(:rm, &remove_branch)
260
183
 
261
- hiiro.add_subcmd(:changed) { |*args|
262
- show_all = args.delete('-a') || args.delete('--all')
263
- upstream = args.first
184
+ add_subcmd(:duplicate) { |new_name = nil, source = nil|
185
+ unless new_name
186
+ puts "Usage: h branch duplicate <new_name> [source_branch]"
187
+ puts " Creates a copy of source_branch (or current branch) as new_name"
188
+ next
189
+ end
264
190
 
265
- upstream ||= %w[origin/master master origin/main main].find { |ref|
266
- system("git rev-parse --verify #{ref} >/dev/null 2>&1")
191
+ source ||= git.branch
192
+ system('git', 'branch', new_name, source)
193
+ puts "Created branch '#{new_name}' from '#{source}'"
267
194
  }
268
195
 
269
- unless upstream
270
- puts "Cannot find master or origin/master"
271
- next
272
- end
196
+ add_subcmd(:test) { |*test_args|
197
+ opts = Hiiro::Options.parse(test_args) do
198
+ option :remote, short: 'r', default: 'origin', desc: 'Remote name'
199
+ option :from, short: 'f', desc: 'Local branch or commit to push'
200
+ option :to, short: 't', desc: 'Remote branch name'
201
+ flag :force, short: 'F', desc: 'Force push'
202
+ flag :set_upstream, short: 'u', desc: 'Set upstream tracking'
203
+ end
273
204
 
274
- forkpoint = `git merge-base --fork-point #{upstream} HEAD 2>/dev/null`.strip
275
- if forkpoint.empty?
276
- forkpoint = `git merge-base #{upstream} HEAD 2>/dev/null`.strip
277
- end
205
+ if opts.help?
206
+ help(opts)
207
+ return
208
+ end
278
209
 
279
- if forkpoint.empty?
280
- puts "Could not find fork point"
281
- next
282
- end
210
+ {
211
+ remote_as_method: opts.remote,
212
+ remote_as_sym_key: opts[:remote],
213
+ remote_as_string_key: opts['remote'],
214
+ force_as_method: opts.force,
215
+ force_as_sym_key: opts[:force],
216
+ force_as_string_key: opts['force'],
217
+ }.each do |k,v|
218
+ puts "#{k} => #{v}"
219
+ end
220
+ }
283
221
 
284
- if show_all
285
- system('git', 'diff', '--name-only', "#{forkpoint}...HEAD")
286
- else
287
- system('git', 'diff', '--name-only', '--relative', "#{forkpoint}...HEAD")
288
- end
289
- }
290
-
291
- hiiro.add_subcmd(:ahead) { |*args|
292
- case args.length
293
- when 0
294
- base = %w[main master].find { |b| system("git rev-parse --verify #{b} >/dev/null 2>&1") } || 'HEAD~1'
295
- ahead_of = base
296
- branch = 'HEAD'
297
- when 1
298
- ahead_of = args[0]
299
- branch = 'HEAD'
300
- else
301
- ahead_of, branch = args[0..1]
302
- end
222
+ add_subcmd(:push) { |*push_args|
223
+ opts = Hiiro::Options.parse(push_args) do
224
+ option :remote, short: 'r', default: 'origin', desc: 'Remote name'
225
+ option :from, short: 'f', desc: 'Local branch or commit to push'
226
+ option :to, short: 't', desc: 'Remote branch name'
227
+ flag :force, short: 'F', desc: 'Force push'
228
+ flag :set_upstream, short: 'u', desc: 'Set upstream tracking'
229
+ end
303
230
 
304
- count = `git rev-list --count #{ahead_of}..#{branch}`.strip.to_i
305
- puts "#{branch} is #{count} commit(s) ahead of #{ahead_of}"
306
- }
307
-
308
- hiiro.add_subcmd(:behind) { |*args|
309
- case args.length
310
- when 0
311
- base = %w[main master].find { |b| system("git rev-parse --verify #{b} >/dev/null 2>&1") } || 'HEAD~1'
312
- behind_of = base
313
- branch = 'HEAD'
314
- when 1
315
- behind_of = args[0]
316
- branch = 'HEAD'
317
- else
318
- behind_of, branch = args[0..1]
319
- end
231
+ local_ref = opts[:from] || git.branch
232
+ remote_branch = opts[:to] || local_ref
320
233
 
321
- count = `git rev-list --count #{branch}..#{behind_of}`.strip.to_i
322
- puts "#{branch} is #{count} commit(s) behind #{behind_of}"
323
- }
234
+ git_args = ['git', 'push']
235
+ git_args << '--force' if opts[:force]
236
+ git_args << '-u' if opts[:set_upstream]
237
+ git_args << opts[:remote]
238
+ git_args << "#{local_ref}:#{remote_branch}"
324
239
 
325
- hiiro.add_subcmd(:log) { |upstream = nil|
326
- upstream ||= %w[origin/master master origin/main main].find { |ref|
327
- system("git rev-parse --verify #{ref} >/dev/null 2>&1")
240
+ puts "Pushing #{local_ref} to #{opts[:remote]}/#{remote_branch}..."
241
+ system(*git_args)
328
242
  }
329
243
 
330
- unless upstream
331
- puts "Cannot find master or origin/master"
332
- next
333
- end
334
-
335
- forkpoint = `git merge-base --fork-point #{upstream} HEAD 2>/dev/null`.strip
336
- if forkpoint.empty?
337
- forkpoint = `git merge-base #{upstream} HEAD 2>/dev/null`.strip
338
- end
244
+ add_subcmd(:diff) { |*diff_args|
245
+ case diff_args.length
246
+ when 0
247
+ # Compare current branch to main/master
248
+ base = %w[main master].find { |b| system("git rev-parse --verify #{b} >/dev/null 2>&1") } || 'HEAD~1'
249
+ range = "#{base}..HEAD"
250
+ when 1
251
+ # Compare current branch to specified ref
252
+ range = "#{diff_args[0]}..HEAD"
253
+ else
254
+ # Compare two refs (from..to or from...to based on args)
255
+ from, to = diff_args[0..1]
256
+ range = "#{from}..#{to}"
257
+ end
339
258
 
340
- if forkpoint.empty?
341
- puts "Could not find fork point"
342
- next
343
- end
259
+ system('git', 'log', '--oneline', '--decorate', range)
260
+ }
344
261
 
345
- system('git', 'log', '--oneline', '--decorate', "#{forkpoint}..HEAD")
346
- }
262
+ add_subcmd(:changed) { |*changed_args|
263
+ show_all = changed_args.delete('-a') || changed_args.delete('--all')
264
+ upstream = changed_args.first
347
265
 
348
- hiiro.add_subcmd(:forkpoint) { |upstream = nil, branch = nil|
349
- branch ||= 'HEAD'
350
- upstream ||= %w[origin/master master origin/main main].find { |ref|
351
- system("git rev-parse --verify #{ref} >/dev/null 2>&1")
352
- }
266
+ upstream ||= %w[origin/master master origin/main main].find { |ref|
267
+ system("git rev-parse --verify #{ref} >/dev/null 2>&1")
268
+ }
353
269
 
354
- unless upstream
355
- puts "Cannot find master or origin/master"
356
- next
357
- end
270
+ unless upstream
271
+ puts "Cannot find master or origin/master"
272
+ next
273
+ end
358
274
 
359
- forkpoint = `git merge-base --fork-point #{upstream} #{branch} 2>/dev/null`.strip
275
+ forkpoint = `git merge-base --fork-point #{upstream} HEAD 2>/dev/null`.strip
276
+ if forkpoint.empty?
277
+ forkpoint = `git merge-base #{upstream} HEAD 2>/dev/null`.strip
278
+ end
360
279
 
361
- if forkpoint.empty?
362
- # Fallback to regular merge-base if fork-point fails
363
- forkpoint = `git merge-base #{upstream} #{branch} 2>/dev/null`.strip
364
- end
280
+ if forkpoint.empty?
281
+ puts "Could not find fork point"
282
+ next
283
+ end
365
284
 
366
- if forkpoint.empty?
367
- puts "Could not find fork point between #{upstream} and #{branch}"
368
- else
369
- puts forkpoint
370
- end
371
- }
285
+ if show_all
286
+ system('git', 'diff', '--name-only', "#{forkpoint}...HEAD")
287
+ else
288
+ system('git', 'diff', '--name-only', '--relative', "#{forkpoint}...HEAD")
289
+ end
290
+ }
372
291
 
373
- hiiro.add_subcmd(:changed) { |*args|
374
- show_all = args.delete('-a') || args.delete('--all')
375
- upstream = args.first
292
+ add_subcmd(:ahead) { |*ahead_args|
293
+ case ahead_args.length
294
+ when 0
295
+ base = %w[main master].find { |b| system("git rev-parse --verify #{b} >/dev/null 2>&1") } || 'HEAD~1'
296
+ ahead_of = base
297
+ branch = 'HEAD'
298
+ when 1
299
+ ahead_of = ahead_args[0]
300
+ branch = 'HEAD'
301
+ else
302
+ ahead_of, branch = ahead_args[0..1]
303
+ end
376
304
 
377
- upstream ||= %w[origin/master master origin/main main].find { |ref|
378
- system("git rev-parse --verify #{ref} >/dev/null 2>&1")
305
+ count = `git rev-list --count #{ahead_of}..#{branch}`.strip.to_i
306
+ puts "#{branch} is #{count} commit(s) ahead of #{ahead_of}"
379
307
  }
380
308
 
381
- unless upstream
382
- puts "Cannot find master or origin/master"
383
- next
384
- end
309
+ add_subcmd(:behind) { |*behind_args|
310
+ case behind_args.length
311
+ when 0
312
+ base = %w[main master].find { |b| system("git rev-parse --verify #{b} >/dev/null 2>&1") } || 'HEAD~1'
313
+ behind_of = base
314
+ branch = 'HEAD'
315
+ when 1
316
+ behind_of = behind_args[0]
317
+ branch = 'HEAD'
318
+ else
319
+ behind_of, branch = behind_args[0..1]
320
+ end
385
321
 
386
- forkpoint = `git merge-base --fork-point #{upstream} HEAD 2>/dev/null`.strip
387
- if forkpoint.empty?
388
- forkpoint = `git merge-base #{upstream} HEAD 2>/dev/null`.strip
389
- end
322
+ count = `git rev-list --count #{branch}..#{behind_of}`.strip.to_i
323
+ puts "#{branch} is #{count} commit(s) behind #{behind_of}"
324
+ }
390
325
 
391
- if forkpoint.empty?
392
- puts "Could not find fork point"
393
- next
394
- end
326
+ add_subcmd(:log) { |upstream = nil|
327
+ upstream ||= %w[origin/master master origin/main main].find { |ref|
328
+ system("git rev-parse --verify #{ref} >/dev/null 2>&1")
329
+ }
395
330
 
396
- if show_all
397
- system('git', 'diff', '--name-only', "#{forkpoint}...HEAD")
398
- else
399
- system('git', 'diff', '--name-only', '--relative', "#{forkpoint}...HEAD")
400
- end
401
- }
331
+ unless upstream
332
+ puts "Cannot find master or origin/master"
333
+ next
334
+ end
402
335
 
336
+ forkpoint = `git merge-base --fork-point #{upstream} HEAD 2>/dev/null`.strip
337
+ if forkpoint.empty?
338
+ forkpoint = `git merge-base #{upstream} HEAD 2>/dev/null`.strip
339
+ end
403
340
 
404
- hiiro.add_subcmd(:changed) { |*args|
405
- show_all = args.delete('-a') || args.delete('--all')
406
- upstream = args.first
341
+ if forkpoint.empty?
342
+ puts "Could not find fork point"
343
+ next
344
+ end
407
345
 
408
- upstream ||= %w[origin/master master origin/main main].find { |ref|
409
- system("git rev-parse --verify #{ref} >/dev/null 2>&1")
346
+ system('git', 'log', '--oneline', '--decorate', "#{forkpoint}..HEAD")
410
347
  }
411
348
 
412
- unless upstream
413
- puts "Cannot find master or origin/master"
414
- next
415
- end
349
+ add_subcmd(:forkpoint) { |upstream = nil, branch = nil|
350
+ branch ||= 'HEAD'
351
+ upstream ||= %w[origin/master master origin/main main].find { |ref|
352
+ system("git rev-parse --verify #{ref} >/dev/null 2>&1")
353
+ }
416
354
 
417
- forkpoint = `git merge-base --fork-point #{upstream} HEAD 2>/dev/null`.strip
418
- if forkpoint.empty?
419
- forkpoint = `git merge-base #{upstream} HEAD 2>/dev/null`.strip
420
- end
355
+ unless upstream
356
+ puts "Cannot find master or origin/master"
357
+ next
358
+ end
421
359
 
422
- if forkpoint.empty?
423
- puts "Could not find fork point"
424
- next
425
- end
360
+ forkpoint = `git merge-base --fork-point #{upstream} #{branch} 2>/dev/null`.strip
426
361
 
427
- if show_all
428
- system('git', 'diff', '--name-only', "#{forkpoint}...HEAD")
429
- else
430
- system('git', 'diff', '--name-only', '--relative', "#{forkpoint}...HEAD")
431
- end
432
- }
433
-
434
- hiiro.add_subcmd(:ancestor) { |*args|
435
- case args.length
436
- when 0
437
- # Check if main/master is ancestor of HEAD
438
- base = %w[main master].find { |b| system("git rev-parse --verify #{b} >/dev/null 2>&1") }
439
- unless base
440
- puts "Cannot find main or master branch"
441
- next
362
+ if forkpoint.empty?
363
+ # Fallback to regular merge-base if fork-point fails
364
+ forkpoint = `git merge-base #{upstream} #{branch} 2>/dev/null`.strip
442
365
  end
443
- ancestor = base
444
- descendant = 'HEAD'
445
- when 1
446
- # Check if arg is ancestor of HEAD
447
- ancestor = args[0]
448
- descendant = 'HEAD'
449
- else
450
- ancestor, descendant = args[0..1]
451
- end
452
366
 
453
- if system("git merge-base --is-ancestor #{ancestor} #{descendant}")
454
- puts "Yes, #{ancestor} is an ancestor of #{descendant}"
455
- else
456
- puts "No, #{ancestor} is NOT an ancestor of #{descendant}"
457
- end
458
- }
367
+ if forkpoint.empty?
368
+ puts "Could not find fork point between #{upstream} and #{branch}"
369
+ else
370
+ puts forkpoint
371
+ end
372
+ }
373
+
374
+ add_subcmd(:ancestor) { |*ancestor_args|
375
+ case ancestor_args.length
376
+ when 0
377
+ # Check if main/master is ancestor of HEAD
378
+ base = %w[main master].find { |b| system("git rev-parse --verify #{b} >/dev/null 2>&1") }
379
+ unless base
380
+ puts "Cannot find main or master branch"
381
+ next
382
+ end
383
+ ancestor = base
384
+ descendant = 'HEAD'
385
+ when 1
386
+ # Check if arg is ancestor of HEAD
387
+ ancestor = ancestor_args[0]
388
+ descendant = 'HEAD'
389
+ else
390
+ ancestor, descendant = ancestor_args[0..1]
391
+ end
459
392
 
460
- hiiro.run
393
+ if system("git merge-base --is-ancestor #{ancestor} #{descendant}")
394
+ puts "Yes, #{ancestor} is an ancestor of #{descendant}"
395
+ else
396
+ puts "No, #{ancestor} is NOT an ancestor of #{descendant}"
397
+ end
398
+ }
399
+ end