mirror of
https://github.com/zoriya/jj.nvim.git
synced 2026-08-05 18:56:13 +00:00
feat(push): Add the possibility to push to arbitrary remotes through the vim command (#124)
This commit is contained in:
@@ -392,6 +392,9 @@ The plugin provides a `:J` command that accepts jj subcommands:
|
||||
:J new
|
||||
:J push " Push all changes
|
||||
:J push main " Push only main bookmark
|
||||
:J push --remote origin " Push all changes to a specific remote
|
||||
:J push main --remote origin " Push only main bookmark to a specific remote
|
||||
:J push --deleted --remote origin " Push deleted bookmarks to a specific remote
|
||||
:J fetch " Fetch from remote
|
||||
:J open_pr " Open PR for current change's bookmark
|
||||
:J open_pr --list " Select bookmark from all and open PR
|
||||
@@ -788,13 +791,26 @@ The `push` function accepts an options table:
|
||||
```lua
|
||||
local cmd = require("jj.cmd")
|
||||
cmd.push({
|
||||
bookmark = "main" -- Push specific bookmark (default: all changes)
|
||||
bookmark = "main", -- Push specific bookmark (default: all changes)
|
||||
remote = "origin", -- Optional target remote
|
||||
-- deleted = true, -- Push deleted bookmarks instead of a bookmark
|
||||
})
|
||||
|
||||
-- Examples:
|
||||
cmd.push() -- Push all changes
|
||||
cmd.push({ bookmark = "main" }) -- Push only main bookmark
|
||||
cmd.push({ bookmark = "feature" }) -- Push only feature bookmark
|
||||
cmd.push() -- Push all changes
|
||||
cmd.push({ bookmark = "main" }) -- Push only main bookmark
|
||||
cmd.push({ bookmark = "feature" }) -- Push only feature bookmark
|
||||
cmd.push({ remote = "origin" }) -- Push all changes to a specific remote
|
||||
cmd.push({ bookmark = "main", remote = "origin" }) -- Push only main to a specific remote
|
||||
cmd.push({ deleted = true, remote = "origin" }) -- Push deleted bookmarks to a specific remote
|
||||
```
|
||||
|
||||
The `:J push` command also supports these forms:
|
||||
|
||||
```sh
|
||||
:J push --remote origin
|
||||
:J push main --remote origin
|
||||
:J push --deleted --remote origin
|
||||
```
|
||||
|
||||
### Bookmark Management Command Options
|
||||
|
||||
+66
-15
@@ -132,6 +132,7 @@ local split_module = require("jj.cmd.split")
|
||||
--- @class jj.cmd.push_opts
|
||||
--- @field bookmark? string Specific bookmark to push (default: all)
|
||||
--- @field deleted? boolean Push deleted revisions
|
||||
--- @field remote? string Specific remote to push too
|
||||
|
||||
--- @class jj.cmd.open_pr_opts
|
||||
--- @field list_bookmarks? boolean Whether to select from all bookmarks instead of current revision
|
||||
@@ -756,6 +757,56 @@ function M.fetch()
|
||||
end
|
||||
end
|
||||
|
||||
--- Parse args for `:J push`.
|
||||
--- @param args string[]
|
||||
--- @return jj.cmd.push_opts|nil opts
|
||||
--- @return string|nil err
|
||||
function M.parse_push_args(args)
|
||||
local opts = {} --[[@as jj.cmd.push_opts]]
|
||||
local already_set = {
|
||||
bookmark = false,
|
||||
remote = false,
|
||||
}
|
||||
|
||||
local i = 1
|
||||
while i <= #args do
|
||||
local arg = args[i]
|
||||
|
||||
if arg == "--deleted" then
|
||||
opts.deleted = true
|
||||
elseif arg == "--remote" then
|
||||
local remote = args[i + 1]
|
||||
if not remote or remote:sub(1, 2) == "--" then
|
||||
return nil, "Missing remote name after --remote"
|
||||
end
|
||||
if already_set.remote then
|
||||
return nil, "Remote already set. Cannot specify multiple remotes."
|
||||
end
|
||||
|
||||
opts.remote = remote
|
||||
already_set.remote = true
|
||||
i = i + 1
|
||||
elseif arg:sub(1, 2) == "--" then
|
||||
return nil, string.format("Unknown option: %s", arg)
|
||||
else
|
||||
if already_set.bookmark then
|
||||
return nil, "Only one bookmark can be provided"
|
||||
end
|
||||
|
||||
opts.bookmark = arg
|
||||
already_set.bookmark = true
|
||||
end
|
||||
|
||||
i = i + 1
|
||||
end
|
||||
|
||||
if opts.deleted and opts.bookmark then
|
||||
return nil, "Cannot specify both --deleted and a bookmark"
|
||||
end
|
||||
|
||||
return opts, nil
|
||||
end
|
||||
|
||||
-- Jujutsu push
|
||||
--- @param opts? jj.cmd.push_opts Optional push options
|
||||
function M.push(opts)
|
||||
@@ -768,17 +819,24 @@ function M.push(opts)
|
||||
-- Save the lop one state to refresh
|
||||
local log_open = terminal.is_log_buffer_open()
|
||||
|
||||
local notify_msg = "Pushing bookmarks `ALL` bookmarks"
|
||||
|
||||
local cmd = "jj git push"
|
||||
if opts.bookmark then
|
||||
utils.notify(string.format("Pushing `%s` bookmark ...", opts.bookmark), vim.log.levels.INFO, 1000)
|
||||
notify_msg = string.format("Pushing bookmark `%s`", opts.bookmark)
|
||||
cmd = string.format("%s --bookmark %s", cmd, opts.bookmark)
|
||||
elseif opts.deleted then
|
||||
utils.notify("Pushing deleted bookmarks...", vim.log.levels.INFO, 1000)
|
||||
notify_msg = "Pushing deleted bookmarks"
|
||||
cmd = cmd .. " --deleted"
|
||||
else
|
||||
utils.notify(string.format("Pushing `ALL` bookmarks...", opts.bookmark), vim.log.levels.INFO, 1000)
|
||||
end
|
||||
|
||||
if opts.remote then
|
||||
cmd = string.format("%s --remote %s", cmd, opts.remote)
|
||||
notify_msg = string.format("%s to remote `%s`", notify_msg, opts.remote)
|
||||
end
|
||||
|
||||
utils.notify(notify_msg .. "...", vim.log.levels.INFO, 1000)
|
||||
|
||||
runner.execute_command_async(cmd, function()
|
||||
utils.notify("Successfully pushed to remote", vim.log.levels.INFO)
|
||||
if log_open then
|
||||
@@ -1311,19 +1369,12 @@ function M.j(args)
|
||||
M.abandon()
|
||||
end,
|
||||
push = function()
|
||||
local opts = {}
|
||||
for _, arg in ipairs(remaining_args) do
|
||||
if arg == "--deleted" then
|
||||
opts.deleted = true
|
||||
else
|
||||
opts.bookmark = arg
|
||||
end
|
||||
end
|
||||
|
||||
if opts.deleted and opts.bookmark then
|
||||
utils.notify("Cannot specify both --deleted and --bookmark", vim.log.levels.ERROR)
|
||||
local opts, err = M.parse_push_args(remaining_args)
|
||||
if err then
|
||||
utils.notify(err, vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
|
||||
M.push(opts)
|
||||
end,
|
||||
fetch = function()
|
||||
|
||||
@@ -399,6 +399,64 @@ run_test("parse_default_cmd: returns nil for nil", function()
|
||||
assert_is_nil(parser.parse_default_cmd(nil))
|
||||
end)
|
||||
|
||||
print("\n=== Running parse_push_args tests ===\n")
|
||||
|
||||
local cmd = require("jj.cmd")
|
||||
|
||||
run_test("parse_push_args: parses bookmark and remote", function()
|
||||
local opts, err = cmd.parse_push_args({ "my-bookmark", "--remote", "origin" })
|
||||
assert_is_nil(err)
|
||||
assert_table_equals({ bookmark = "my-bookmark", remote = "origin" }, opts)
|
||||
end)
|
||||
|
||||
run_test("parse_push_args: parses deleted flag", function()
|
||||
local opts, err = cmd.parse_push_args({ "--deleted" })
|
||||
assert_is_nil(err)
|
||||
assert_table_equals({ deleted = true }, opts)
|
||||
end)
|
||||
|
||||
run_test("parse_push_args: allows remote before bookmark", function()
|
||||
local opts, err = cmd.parse_push_args({ "--remote", "origin", "my-bookmark" })
|
||||
assert_is_nil(err)
|
||||
assert_table_equals({ bookmark = "my-bookmark", remote = "origin" }, opts)
|
||||
end)
|
||||
|
||||
run_test("parse_push_args: errors on missing remote value", function()
|
||||
local opts, err = cmd.parse_push_args({ "--remote" })
|
||||
assert_is_nil(opts)
|
||||
assert_equals("Missing remote name after --remote", err)
|
||||
end)
|
||||
|
||||
run_test("parse_push_args: errors when remote value is another option", function()
|
||||
local opts, err = cmd.parse_push_args({ "--remote", "--deleted" })
|
||||
assert_is_nil(opts)
|
||||
assert_equals("Missing remote name after --remote", err)
|
||||
end)
|
||||
|
||||
run_test("parse_push_args: errors on duplicate remotes", function()
|
||||
local opts, err = cmd.parse_push_args({ "--remote", "origin", "--remote", "upstream" })
|
||||
assert_is_nil(opts)
|
||||
assert_equals("Remote already set. Cannot specify multiple remotes.", err)
|
||||
end)
|
||||
|
||||
run_test("parse_push_args: errors on multiple bookmarks", function()
|
||||
local opts, err = cmd.parse_push_args({ "bookmark-1", "bookmark-2" })
|
||||
assert_is_nil(opts)
|
||||
assert_equals("Only one bookmark can be provided", err)
|
||||
end)
|
||||
|
||||
run_test("parse_push_args: errors on unknown option", function()
|
||||
local opts, err = cmd.parse_push_args({ "--foo" })
|
||||
assert_is_nil(opts)
|
||||
assert_equals("Unknown option: --foo", err)
|
||||
end)
|
||||
|
||||
run_test("parse_push_args: errors on deleted with bookmark", function()
|
||||
local opts, err = cmd.parse_push_args({ "--deleted", "my-bookmark" })
|
||||
assert_is_nil(opts)
|
||||
assert_equals("Cannot specify both --deleted and a bookmark", err)
|
||||
end)
|
||||
|
||||
print("\n=== Running build_log_cmd tests ===\n")
|
||||
|
||||
local log = require("jj.cmd.log")
|
||||
|
||||
Reference in New Issue
Block a user