noot
This commit is contained in:
parent
9470d7c36b
commit
97f8909001
4
Makefile
4
Makefile
@ -9,7 +9,9 @@ all: dist/repotool
|
||||
|
||||
install: dist/repotool shell/zsh/repotool.zsh shell/zsh/repotool.plugin.zsh
|
||||
mkdir -p ${REPOTOOL_PATH}/.bin/
|
||||
install dist/repotool shell/zsh/repotool.zsh shell/zsh/repotool.plugin.zsh ${REPOTOOL_PATH}/.bin/
|
||||
mkdir -p ${REPOTOOL_PATH}/.shell/
|
||||
install dist/repotool ${REPOTOOL_PATH}/.bin/
|
||||
install shell/zsh/repotool.zsh shell/zsh/repotool.plugin.zsh ${REPOTOOL_PATH}/.shell/
|
||||
|
||||
dist/repotool: $(SOURCES_SRC) $(LIBS_SRC) main.lua
|
||||
@mkdir -p dist
|
||||
|
||||
71
main.lua
71
main.lua
@ -11,7 +11,7 @@ local json = require("json")
|
||||
|
||||
-- Load command modules
|
||||
local get_command = require("get_command")
|
||||
local worktree_command = require("worktree_command")
|
||||
local worktree = require("worktree")
|
||||
local open_command = require("open_command")
|
||||
|
||||
-- Create the main command with subcommands
|
||||
@ -62,42 +62,61 @@ local app = cli.cmd {
|
||||
return 0
|
||||
end),
|
||||
},
|
||||
-- Worktree command
|
||||
-- Worktree command with subcommands
|
||||
cli.cmd {
|
||||
'worktree', 'w', 'wt',
|
||||
desc = 'goes to or creates a worktree with the name for the repo you are in',
|
||||
desc = 'manage git worktrees',
|
||||
subs = {
|
||||
-- List subcommand
|
||||
cli.cmd {
|
||||
'list', 'ls',
|
||||
desc = 'list existing worktrees for this repo',
|
||||
term = cli.val():and_then(function()
|
||||
worktree.handle_list()
|
||||
return 0
|
||||
end),
|
||||
},
|
||||
-- Get subcommand
|
||||
cli.cmd {
|
||||
'get',"new","create","n","c",
|
||||
desc = 'create or go to a worktree',
|
||||
term = cli.all {
|
||||
name = cli.arg {
|
||||
'name',
|
||||
desc = 'Name of the worktree',
|
||||
required = false,
|
||||
},
|
||||
list = cli.opt {
|
||||
'--list', '-l',
|
||||
desc = 'List existing worktrees for this repo',
|
||||
flag = true,
|
||||
},
|
||||
root = cli.opt {
|
||||
'--root', '-r',
|
||||
desc = 'Return the root directory of the original repo',
|
||||
flag = true,
|
||||
required = true,
|
||||
},
|
||||
}:and_then(function(args)
|
||||
-- Handle special cases: "list" and "ls" as commands
|
||||
local name = args.name
|
||||
if name == "list" or name == "ls" then
|
||||
args.list = true
|
||||
args.name = nil
|
||||
end
|
||||
|
||||
worktree_command({
|
||||
name = args.name,
|
||||
list = args.list,
|
||||
root = args.root,
|
||||
})
|
||||
worktree.handle_get(args.name)
|
||||
return 0
|
||||
end),
|
||||
},
|
||||
-- Root subcommand
|
||||
cli.cmd {
|
||||
'root', 'back', 'r', 'return',
|
||||
desc = 'return to the root directory of the original repo',
|
||||
term = cli.val():and_then(function()
|
||||
worktree.handle_root()
|
||||
return 0
|
||||
end),
|
||||
},
|
||||
-- Remove subcommand
|
||||
cli.cmd {
|
||||
'remove', 'rm', 'delete', 'del',
|
||||
desc = 'remove a worktree',
|
||||
term = cli.all {
|
||||
name = cli.arg {
|
||||
'name',
|
||||
desc = 'Name of the worktree to remove',
|
||||
required = true,
|
||||
},
|
||||
}:and_then(function(args)
|
||||
worktree.handle_remove(args.name)
|
||||
return 0
|
||||
end),
|
||||
},
|
||||
},
|
||||
},
|
||||
-- Open command
|
||||
cli.cmd {
|
||||
'open', 'o',
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env zsh
|
||||
|
||||
[[ -z "$REPOTOOL_PATH" ]] && export REPOTOOL_PATH="$HOME/repo"
|
||||
alias repo=". $REPOTOOL_PATH/.bin/repotool.zsh"
|
||||
alias repo=". $REPOTOOL_PATH/.shell/repotool.zsh"
|
||||
|
||||
36
src/cmd.lua
Normal file
36
src/cmd.lua
Normal file
@ -0,0 +1,36 @@
|
||||
local cmd = {}
|
||||
|
||||
-- Execute a command, redirecting stdout to stderr to avoid polluting our JSON output
|
||||
function cmd.execute(command)
|
||||
-- Redirect stdout to stderr so only our JSON goes to stdout
|
||||
local redirected_cmd = command .. " 1>&2"
|
||||
return os.execute(redirected_cmd)
|
||||
end
|
||||
|
||||
-- Execute a command and capture its output
|
||||
function cmd.read(command)
|
||||
local handle = io.popen(command .. " 2>&1")
|
||||
local result = handle:read("*a")
|
||||
local success = handle:close()
|
||||
return result, success
|
||||
end
|
||||
|
||||
-- Execute a command and capture stdout separately from stderr
|
||||
function cmd.read_stdout(command)
|
||||
local handle = io.popen(command .. " 2>/dev/null")
|
||||
local result = handle:read("*a")
|
||||
local success = handle:close()
|
||||
return result, success
|
||||
end
|
||||
|
||||
-- Execute a command and return only the exit status
|
||||
function cmd.run(command)
|
||||
return os.execute(command .. " >/dev/null 2>&1")
|
||||
end
|
||||
|
||||
-- Check if a command exists
|
||||
function cmd.exists(command_name)
|
||||
return cmd.run("command -v " .. command_name) == 0
|
||||
end
|
||||
|
||||
return cmd
|
||||
@ -1,3 +1,5 @@
|
||||
local cmd = require("cmd")
|
||||
|
||||
local fs = {}
|
||||
|
||||
-- Check if a file exists
|
||||
@ -13,17 +15,14 @@ function fs.dir_exists(path)
|
||||
if f then
|
||||
io.close(f)
|
||||
-- Check if it's actually a directory by trying to list it
|
||||
local handle = io.popen('test -d "' .. path .. '" && echo "yes" || echo "no"')
|
||||
local result = handle:read("*a"):gsub("\n", "")
|
||||
handle:close()
|
||||
return result == "yes"
|
||||
return cmd.run('test -d "' .. path .. '"') == 0
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
-- Create directory with parents
|
||||
function fs.mkdir_p(path)
|
||||
os.execute('mkdir -p "' .. path .. '"')
|
||||
cmd.execute('mkdir -p "' .. path .. '"')
|
||||
end
|
||||
|
||||
-- Get the parent directory of a path
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
local git = require("git")
|
||||
local json = require("json")
|
||||
local fs = require("fs")
|
||||
local cmd = require("cmd")
|
||||
|
||||
local function get_command(args)
|
||||
-- Validate URL
|
||||
@ -53,8 +54,7 @@ http_pass: %s
|
||||
fs.mkdir_p(target_dir)
|
||||
end
|
||||
|
||||
-- Change to target directory
|
||||
os.execute("cd '" .. target_dir .. "'")
|
||||
-- Note: cd command doesn't work in os.execute as it runs in a subshell
|
||||
|
||||
-- Construct repo URL based on method
|
||||
local clone_url
|
||||
@ -73,9 +73,9 @@ http_pass: %s
|
||||
local git_dir = fs.join(target_dir, ".git")
|
||||
if not fs.dir_exists(git_dir) then
|
||||
-- Check if remote exists
|
||||
local check_cmd = "cd '" .. target_dir .. "' && git ls-remote '" .. clone_url .. "' >/dev/null 2>&1"
|
||||
if os.execute(check_cmd) == 0 then
|
||||
os.execute("git clone '" .. clone_url .. "' '" .. target_dir .. "' >&2")
|
||||
local check_cmd = "cd '" .. target_dir .. "' && git ls-remote '" .. clone_url .. "'"
|
||||
if cmd.run(check_cmd) == 0 then
|
||||
cmd.execute("git clone '" .. clone_url .. "' '" .. target_dir .. "'")
|
||||
cloned = "true"
|
||||
else
|
||||
io.stderr:write("Could not find repo: " .. clone_url .. "\n")
|
||||
|
||||
20
src/git.lua
20
src/git.lua
@ -1,3 +1,5 @@
|
||||
local cmd = require("cmd")
|
||||
|
||||
local git = {}
|
||||
|
||||
-- Parse a git URL into domain and path components
|
||||
@ -34,9 +36,8 @@ end
|
||||
|
||||
-- Get domain and path from current git repository's origin
|
||||
function git.parse_origin()
|
||||
local handle = io.popen("git config --get remote.origin.url 2>/dev/null")
|
||||
local origin_url = handle:read("*a"):gsub("\n", "")
|
||||
handle:close()
|
||||
local origin_url = cmd.read_stdout("git config --get remote.origin.url")
|
||||
origin_url = origin_url:gsub("\n", "")
|
||||
|
||||
if origin_url == "" then
|
||||
return nil, nil
|
||||
@ -59,11 +60,8 @@ function git.valid_url(url)
|
||||
end
|
||||
|
||||
-- Execute command and return output
|
||||
function git.execute(cmd)
|
||||
local handle = io.popen(cmd .. " 2>&1")
|
||||
local result = handle:read("*a")
|
||||
local success = handle:close()
|
||||
return result, success
|
||||
function git.execute(command)
|
||||
return cmd.read(command)
|
||||
end
|
||||
|
||||
-- Check if we're in a git repository
|
||||
@ -93,10 +91,10 @@ end
|
||||
-- Get list of all worktrees with their properties
|
||||
function git.worktree_list()
|
||||
local worktrees = {}
|
||||
local handle = io.popen("git worktree list --porcelain")
|
||||
local output = cmd.read_stdout("git worktree list --porcelain")
|
||||
local current_worktree = nil
|
||||
|
||||
for line in handle:lines() do
|
||||
for line in output:gmatch("[^\n]+") do
|
||||
local worktree_path = line:match("^worktree (.+)$")
|
||||
if worktree_path then
|
||||
-- Save previous worktree if any
|
||||
@ -137,8 +135,6 @@ function git.worktree_list()
|
||||
table.insert(worktrees, current_worktree)
|
||||
end
|
||||
|
||||
handle:close()
|
||||
|
||||
return worktrees
|
||||
end
|
||||
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
local git = require("git")
|
||||
local json = require("json")
|
||||
local cmd = require("cmd")
|
||||
|
||||
local function open_command(args)
|
||||
-- Check if we're in a git repository
|
||||
@ -9,9 +10,8 @@ local function open_command(args)
|
||||
end
|
||||
|
||||
-- Get the remote URL
|
||||
local handle = io.popen("git ls-remote --get-url")
|
||||
local raw_url = handle:read("*a"):gsub("\n", "")
|
||||
handle:close()
|
||||
local raw_url = cmd.read_stdout("git ls-remote --get-url")
|
||||
raw_url = raw_url:gsub("\n", "")
|
||||
|
||||
if raw_url == "" then
|
||||
io.stderr:write("Error: No remote URL found\n")
|
||||
@ -30,29 +30,22 @@ local function open_command(args)
|
||||
|
||||
-- Detect platform and open URL
|
||||
local open_cmd
|
||||
local result = os.execute("command -v xdg-open >/dev/null 2>&1")
|
||||
if result == true or result == 0 then
|
||||
if cmd.exists("xdg-open") then
|
||||
-- Linux
|
||||
open_cmd = "xdg-open"
|
||||
else
|
||||
result = os.execute("command -v open >/dev/null 2>&1")
|
||||
if result == true or result == 0 then
|
||||
elseif cmd.exists("open") then
|
||||
-- macOS
|
||||
open_cmd = "open"
|
||||
else
|
||||
result = os.execute("command -v start >/dev/null 2>&1")
|
||||
if result == true or result == 0 then
|
||||
elseif cmd.exists("start") then
|
||||
-- Windows
|
||||
open_cmd = "start"
|
||||
else
|
||||
io.stderr:write("Error: Unable to detect platform open command\n")
|
||||
os.exit(1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Open the URL
|
||||
os.execute(open_cmd .. " '" .. https_url .. "' 2>/dev/null")
|
||||
cmd.execute(open_cmd .. " '" .. https_url .. "'")
|
||||
|
||||
-- Output JSON
|
||||
print(json.encode({
|
||||
|
||||
207
src/worktree.lua
Normal file
207
src/worktree.lua
Normal file
@ -0,0 +1,207 @@
|
||||
local git = require("git")
|
||||
local json = require("json")
|
||||
local fs = require("fs")
|
||||
local cmd = require("cmd")
|
||||
|
||||
local worktree = {}
|
||||
|
||||
-- Handle the root/return subcommand
|
||||
function worktree.handle_root()
|
||||
-- Check if we're in a git repository
|
||||
if not git.in_repo() then
|
||||
io.stderr:write("Error: Not in a git repository\n")
|
||||
os.exit(1)
|
||||
end
|
||||
|
||||
-- Get repository root
|
||||
local repo_root = git.get_repo_root()
|
||||
|
||||
-- Check if we're in a worktree
|
||||
local git_common_dir = git.get_common_dir()
|
||||
local cd_path = repo_root
|
||||
|
||||
if git_common_dir ~= ".git" and git_common_dir ~= "" then
|
||||
-- We're in a worktree, get the main repo path
|
||||
cd_path = git_common_dir:match("(.+)/.git")
|
||||
end
|
||||
|
||||
print(json.encode({cd = cd_path, hook = "worktree"}))
|
||||
end
|
||||
|
||||
-- Handle the list subcommand
|
||||
function worktree.handle_list()
|
||||
-- Check if we're in a git repository
|
||||
if not git.in_repo() then
|
||||
io.stderr:write("Error: Not in a git repository\n")
|
||||
os.exit(1)
|
||||
end
|
||||
|
||||
-- Parse origin URL
|
||||
local domain, path = git.parse_origin()
|
||||
if not domain or not path then
|
||||
io.stderr:write("Error: Unable to parse repository origin URL\n")
|
||||
os.exit(1)
|
||||
end
|
||||
|
||||
-- Get repository root
|
||||
local repo_root = git.get_repo_root()
|
||||
|
||||
-- Calculate worktree base directory
|
||||
local repotool_path = os.getenv("REPOTOOL_PATH") or os.getenv("HOME") .. "/repo"
|
||||
local worktree_base = repotool_path .. "/.worktree/" .. domain .. "/" .. path
|
||||
|
||||
-- Get all worktrees using the git library
|
||||
local worktrees = git.worktree_list()
|
||||
|
||||
-- Filter and display worktrees under our worktree base
|
||||
io.stderr:write("Worktrees for " .. domain .. "/" .. path .. ":\n")
|
||||
local found_any = false
|
||||
|
||||
local any_prunable = false
|
||||
for _, wt in ipairs(worktrees) do
|
||||
if wt.path == repo_root then
|
||||
-- Skip the main repository
|
||||
else
|
||||
found_any = true
|
||||
local wt_name = wt.path:match(".*/([^/]+)$")
|
||||
local exists = fs.dir_exists(wt.path)
|
||||
|
||||
local status = ""
|
||||
if not exists then
|
||||
if wt.prunable then
|
||||
any_prunable = true
|
||||
status = " (prunable)"
|
||||
else
|
||||
status = " (missing)"
|
||||
end
|
||||
elseif wt.locked then
|
||||
status = " (locked)"
|
||||
elseif wt.detached then
|
||||
status = " (detached)"
|
||||
end
|
||||
io.stderr:write(" - " .. wt_name .. status .. "\n")
|
||||
end
|
||||
end
|
||||
|
||||
if any_prunable then
|
||||
io.stderr:write("Run 'git worktree prune' to remove prunable worktrees\n")
|
||||
end
|
||||
|
||||
if not found_any then
|
||||
io.stderr:write(" No worktrees found\n")
|
||||
end
|
||||
|
||||
print(json.encode({hook = "worktree.list"}))
|
||||
end
|
||||
|
||||
-- Handle the get subcommand
|
||||
function worktree.handle_get(worktree_name)
|
||||
-- Check if we're in a git repository
|
||||
if not git.in_repo() then
|
||||
io.stderr:write("Error: Not in a git repository\n")
|
||||
os.exit(1)
|
||||
end
|
||||
|
||||
-- Parse origin URL
|
||||
local domain, path = git.parse_origin()
|
||||
if not domain or not path then
|
||||
io.stderr:write("Error: Unable to parse repository origin URL\n")
|
||||
os.exit(1)
|
||||
end
|
||||
|
||||
-- Calculate worktree base directory
|
||||
local repotool_path = os.getenv("REPOTOOL_PATH") or os.getenv("HOME") .. "/repo"
|
||||
local worktree_base = repotool_path .. "/.worktree/" .. domain .. "/" .. path
|
||||
|
||||
-- Construct worktree path
|
||||
local worktree_path = worktree_base .. "/" .. worktree_name
|
||||
|
||||
-- Check if a prunable worktree exists at this path
|
||||
local prunable_output = cmd.read_stdout("git worktree list | grep '" .. worktree_path .. ".*prunable'")
|
||||
if prunable_output ~= "" then
|
||||
io.stderr:write("Found prunable worktree at " .. worktree_path .. ", cleaning up...\n")
|
||||
cmd.execute("git worktree prune")
|
||||
end
|
||||
|
||||
-- Check if worktree already exists
|
||||
local created = "false"
|
||||
local exists_output = cmd.read_stdout("git worktree list | grep '" .. worktree_path .. "'")
|
||||
if exists_output == "" then
|
||||
-- Create parent directories if they don't exist
|
||||
fs.mkdir_p(fs.dirname(worktree_path))
|
||||
|
||||
-- Create the worktree (try different methods)
|
||||
local success = cmd.run("git worktree add '" .. worktree_path .. "' -b '" .. worktree_name .. "'") == 0
|
||||
if not success then
|
||||
success = cmd.run("git worktree add '" .. worktree_path .. "' '" .. worktree_name .. "'") == 0
|
||||
end
|
||||
if not success then
|
||||
cmd.execute("git worktree add '" .. worktree_path .. "'")
|
||||
end
|
||||
created = "true"
|
||||
end
|
||||
|
||||
-- Output JSON
|
||||
print(json.encode({
|
||||
cd = worktree_path,
|
||||
domain = domain,
|
||||
path = path,
|
||||
worktree_name = worktree_name,
|
||||
created = created,
|
||||
hook = "worktree"
|
||||
}))
|
||||
end
|
||||
|
||||
-- Handle the remove/delete subcommand
|
||||
function worktree.handle_remove(worktree_name)
|
||||
-- Check if we're in a git repository
|
||||
if not git.in_repo() then
|
||||
io.stderr:write("Error: Not in a git repository\n")
|
||||
os.exit(1)
|
||||
end
|
||||
|
||||
-- Parse origin URL
|
||||
local domain, path = git.parse_origin()
|
||||
if not domain or not path then
|
||||
io.stderr:write("Error: Unable to parse repository origin URL\n")
|
||||
os.exit(1)
|
||||
end
|
||||
|
||||
-- Calculate worktree base directory
|
||||
local repotool_path = os.getenv("REPOTOOL_PATH") or os.getenv("HOME") .. "/repo"
|
||||
local worktree_base = repotool_path .. "/.worktree/" .. domain .. "/" .. path
|
||||
|
||||
-- Construct worktree path
|
||||
local worktree_path = worktree_base .. "/" .. worktree_name
|
||||
|
||||
-- Check if worktree exists
|
||||
local exists_output = cmd.read_stdout("git worktree list | grep '" .. worktree_path .. "'")
|
||||
if exists_output == "" then
|
||||
io.stderr:write("Error: Worktree '" .. worktree_name .. "' not found\n")
|
||||
os.exit(1)
|
||||
end
|
||||
|
||||
-- Remove the worktree
|
||||
io.stderr:write("Removing worktree '" .. worktree_name .. "'...\n")
|
||||
local success = cmd.run("git worktree remove '" .. worktree_path .. "'") == 0
|
||||
|
||||
if not success then
|
||||
-- Try with --force if normal remove fails
|
||||
io.stderr:write("Normal remove failed, trying with --force...\n")
|
||||
success = cmd.run("git worktree remove --force '" .. worktree_path .. "'") == 0
|
||||
end
|
||||
|
||||
if success then
|
||||
io.stderr:write("Successfully removed worktree '" .. worktree_name .. "'\n")
|
||||
print(json.encode({
|
||||
removed = worktree_name,
|
||||
path = worktree_path,
|
||||
hook = "worktree.remove"
|
||||
}))
|
||||
else
|
||||
io.stderr:write("Error: Failed to remove worktree '" .. worktree_name .. "'\n")
|
||||
os.exit(1)
|
||||
end
|
||||
end
|
||||
|
||||
return worktree
|
||||
@ -1,139 +0,0 @@
|
||||
local git = require("git")
|
||||
local json = require("json")
|
||||
local fs = require("fs")
|
||||
|
||||
local function worktree_command(args)
|
||||
-- Check if we're in a git repository
|
||||
if not git.in_repo() then
|
||||
io.stderr:write("Error: Not in a git repository\n")
|
||||
os.exit(1)
|
||||
end
|
||||
|
||||
-- Get repository root
|
||||
local repo_root = git.get_repo_root()
|
||||
|
||||
-- Handle --root flag
|
||||
if args.root then
|
||||
-- Check if we're in a worktree
|
||||
local git_common_dir = git.get_common_dir()
|
||||
local cd_path = repo_root
|
||||
|
||||
if git_common_dir ~= ".git" and git_common_dir ~= "" then
|
||||
-- We're in a worktree, get the main repo path
|
||||
cd_path = git_common_dir:match("(.+)/.git")
|
||||
end
|
||||
|
||||
print(json.encode({cd = cd_path, hook = "worktree"}))
|
||||
return
|
||||
end
|
||||
|
||||
-- Parse origin URL
|
||||
local domain, path = git.parse_origin()
|
||||
if not domain or not path then
|
||||
io.stderr:write("Error: Unable to parse repository origin URL\n")
|
||||
os.exit(1)
|
||||
end
|
||||
|
||||
-- Calculate worktree base directory
|
||||
local repotool_path = os.getenv("REPOTOOL_PATH") or os.getenv("HOME") .. "/repo"
|
||||
local worktree_base = repotool_path .. "/worktree/" .. domain .. "/" .. path
|
||||
|
||||
-- Handle --list flag
|
||||
if args.list then
|
||||
-- Get all worktrees using the git library
|
||||
local worktrees = git.worktree_list()
|
||||
|
||||
-- Filter and display worktrees under our worktree base
|
||||
io.stderr:write("Worktrees for " .. domain .. "/" .. path .. ":\n")
|
||||
local found_any = false
|
||||
|
||||
local any_prunable = false
|
||||
for _, wt in ipairs(worktrees) do
|
||||
if wt.path == repo_root then
|
||||
else
|
||||
found_any = true
|
||||
local wt_name = wt.path:match(".*/([^/]+)$")
|
||||
local exists = fs.dir_exists(wt.path)
|
||||
|
||||
local status = ""
|
||||
if not exists then
|
||||
if wt.prunable then
|
||||
any_prunable = true
|
||||
status = " (prunable)"
|
||||
else
|
||||
status = " (missing)"
|
||||
end
|
||||
elseif wt.locked then
|
||||
status = " (locked)"
|
||||
elseif wt.detached then
|
||||
status = " (detached)"
|
||||
end
|
||||
io.stderr:write(" - " .. wt_name .. status .. "\n")
|
||||
end
|
||||
end
|
||||
|
||||
if any_prunable then
|
||||
io.stderr:write("Run 'git worktree prune' to remove prunable worktrees\n")
|
||||
end
|
||||
|
||||
if not found_any then
|
||||
io.stderr:write(" No worktrees found\n")
|
||||
end
|
||||
|
||||
print(json.encode({hook = "worktree.list"}))
|
||||
return
|
||||
end
|
||||
|
||||
-- Get worktree name from arguments
|
||||
local worktree_name = args.name
|
||||
|
||||
-- Check if name is provided
|
||||
if not worktree_name or worktree_name == "" then
|
||||
io.stderr:write([[Error: Missing required argument: name
|
||||
Run 'repo worktree --help' for usage information
|
||||
]])
|
||||
os.exit(1)
|
||||
end
|
||||
|
||||
-- Construct worktree path
|
||||
local worktree_path = worktree_base .. "/" .. worktree_name
|
||||
|
||||
-- Check if a prunable worktree exists at this path
|
||||
local check_prunable = io.popen("git worktree list | grep '" .. worktree_path .. ".*prunable'")
|
||||
if check_prunable:read("*a") ~= "" then
|
||||
io.stderr:write("Found prunable worktree at " .. worktree_path .. ", cleaning up...\n")
|
||||
os.execute("git worktree prune")
|
||||
end
|
||||
check_prunable:close()
|
||||
|
||||
-- Check if worktree already exists
|
||||
local created = "false"
|
||||
local check_exists = io.popen("git worktree list | grep '" .. worktree_path .. "'")
|
||||
if check_exists:read("*a") == "" then
|
||||
-- Create parent directories if they don't exist
|
||||
fs.mkdir_p(fs.dirname(worktree_path))
|
||||
|
||||
-- Create the worktree (try different methods)
|
||||
local success = os.execute("git worktree add '" .. worktree_path .. "' -b '" .. worktree_name .. "' 2>/dev/null") == 0
|
||||
if not success then
|
||||
success = os.execute("git worktree add '" .. worktree_path .. "' '" .. worktree_name .. "' 2>/dev/null") == 0
|
||||
end
|
||||
if not success then
|
||||
os.execute("git worktree add '" .. worktree_path .. "'")
|
||||
end
|
||||
created = "true"
|
||||
end
|
||||
check_exists:close()
|
||||
|
||||
-- Output JSON
|
||||
print(json.encode({
|
||||
cd = worktree_path,
|
||||
domain = domain,
|
||||
path = path,
|
||||
worktree_name = worktree_name,
|
||||
created = created,
|
||||
hook = "worktree"
|
||||
}))
|
||||
end
|
||||
|
||||
return worktree_command
|
||||
Loading…
Reference in New Issue
Block a user