Module: Portless::Worktree
- Defined in:
- lib/portless/worktree.rb
Overview
Git-worktree-aware hostname prefix. In a linked worktree (one created via
git worktree add, not the root checkout) sitting on a non-default branch,
the branch's last path segment becomes a subdomain prefix so each worktree
gets its own URL — feature/auth → auth.<name>.localhost. Returns nil in
the root worktree, on main/master, on detached HEAD, or outside git.
Mirrors portless's detectWorktreePrefix (git-CLI path).
Constant Summary collapse
- DEFAULT_BRANCHES =
%w[main master].freeze
Class Method Summary collapse
-
.branch_to_prefix(branch) ⇒ Object
Last
/-segment of the branch, sanitized; nil for default/detached HEAD. - .git(dir, *args) ⇒ Object
- .prefix(dir = Dir.pwd) ⇒ Object
-
.via_cli(dir) ⇒ Object
Authoritative path: ask git directly.
-
.via_filesystem(dir) ⇒ Object
Fallback when the git binary isn't available: walk up for a
.gitfile (worktrees use a file, not a dir) whose gitdir points into /worktrees/, and read the branch from that gitdir's HEAD.
Class Method Details
.branch_to_prefix(branch) ⇒ Object
Last /-segment of the branch, sanitized; nil for default/detached HEAD.
62 63 64 65 66 67 68 |
# File 'lib/portless/worktree.rb', line 62 def branch_to_prefix(branch) return nil if branch.nil? || branch.empty? || branch == "HEAD" return nil if DEFAULT_BRANCHES.include?(branch) label = branch.split("/").last.to_s.downcase.gsub(/[^a-z0-9-]+/, "-").gsub(/\A-+|-+\z/, "") label.empty? ? nil : label end |
.git(dir, *args) ⇒ Object
70 71 72 73 74 75 |
# File 'lib/portless/worktree.rb', line 70 def git(dir, *args) out = IO.popen([ "git", "-C", dir, *args ], err: File::NULL, &:read) $?.success? ? out.strip : nil rescue StandardError nil end |
.prefix(dir = Dir.pwd) ⇒ Object
15 16 17 18 19 |
# File 'lib/portless/worktree.rb', line 15 def prefix(dir = Dir.pwd) Portless.which("git") ? via_cli(dir) : via_filesystem(dir) rescue StandardError nil end |
.via_cli(dir) ⇒ Object
Authoritative path: ask git directly.
22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
# File 'lib/portless/worktree.rb', line 22 def via_cli(dir) list = git(dir, "worktree", "list", "--porcelain") return nil if list.nil? return nil if list.lines.count { |l| l.start_with?("worktree ") } <= 1 # Only a *linked* worktree gets a prefix: there --git-dir differs from # --git-common-dir; in the root worktree they're the same path. git_dir = git(dir, "rev-parse", "--git-dir") common = git(dir, "rev-parse", "--git-common-dir") return nil if git_dir.nil? || common.nil? return nil if File.(git_dir, dir) == File.(common, dir) branch_to_prefix(git(dir, "rev-parse", "--abbrev-ref", "HEAD")) end |
.via_filesystem(dir) ⇒ Object
Fallback when the git binary isn't available: walk up for a .git file
(worktrees use a file, not a dir) whose gitdir points into /worktrees/, and
read the branch from that gitdir's HEAD. Submodules (/modules/) are ignored.
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/portless/worktree.rb', line 40 def via_filesystem(dir) current = File.(dir) loop do git_path = File.join(current, ".git") return nil if File.directory?(git_path) # root checkout, not a worktree if File.file?(git_path) gitdir = File.read(git_path)[/^gitdir:\s*(.+)$/, 1] return nil unless gitdir&.match?(%r{[/\\]worktrees[/\\][^/\\]+$}) head = File.read(File.join(File.(gitdir, current), "HEAD")) return branch_to_prefix(head[%r{^ref: refs/heads/(.+)$}, 1]) end parent = File.dirname(current) return nil if parent == current current = parent end end |