diff --git a/doc/neogit.txt b/doc/neogit.txt index 905329bf7..8c9a02f53 100644 --- a/doc/neogit.txt +++ b/doc/neogit.txt @@ -186,17 +186,21 @@ NeogitFold Folded text highlight NeogitRebaseDone Current position within rebase STATUS BUFFER SECTION HEADERS -NeogitUnpushedTo -NeogitUnmergedInto -NeogitUnpulledFrom -NeogitUntrackedfiles -NeogitUnstagedchanges -NeogitUnmergedchanges -NeogitUnpulledchanges -NeogitRecentcommits -NeogitStagedchanges -NeogitStashes -NeogitRebasing +NeogitSectionHeader + +NeogitUnpushedTo Linked to NeogitSectionHeader +NeogitUnmergedInto ^ +NeogitUnpulledFrom ^ +NeogitUntrackedfiles ^ +NeogitUnstagedchanges ^ +NeogitUnmergedchanges ^ +NeogitUnpulledchanges ^ +NeogitRecentcommits ^ +NeogitStagedchanges ^ +NeogitStashes ^ +NeogitRebasing ^ +NeogitReverting ^ +NeogitPicking ^ STATUS BUFFER FILE Applied to the label on the left of filenames. @@ -778,7 +782,6 @@ Arguments: *neogit_fetch_popup_args* pruning, even if --prune is used (though tags may be pruned anyway if they are also the destination of an explicit refspec; see --prune). - Actions: *neogit_fetch_popup_actions* • Fetch from pushRemote *neogit_fetch_pushremote* @@ -815,4 +818,44 @@ Actions: *neogit_fetch_popup_actions* • Set Variables *neogit_fetch_set_variables* Opens Branch Config popup for the current branch. +============================================================================== +Revert Popup *neogit_revert_popup* + +Arguments: *neogit_revert_popup_args* +• --mainline + Usually you cannot revert a merge because you do not know which side of the + merge should be considered the mainline. This option specifies the parent + number (starting from 1) of the mainline and allows revert to reverse the + change relative to the specified parent. + + Reverting a merge commit declares that you will never want the tree changes + brought in by the merge. As a result, later merges will only bring in tree + changes introduced by commits that are not ancestors of the previously + reverted merge. This may or may not be what you want. + +• --edit + With this option, git revert will let you edit the commit message prior to + committing the revert. This is the default. + + Cannot be used with --no-edit + +• --no-edit + With this option, git revert will auto-generate the commit message without + bringing up the commit message editor. + + Cannot be used with --edit + +Actions: *neogit_fetch_revert_actions* + +• Revert Commit(s) *neogit_revert_commits* + Reverts one or more commits. If any commits are under the cursor, or + selected, they will be used. Otherwise a selector interface will come up. + + Will create a commit of the reverted changes. + +• Revert Changes *neogit_revert_changes* + Reverts one or more commits WITHOUT committing the worktree. If any commits + are under the cursor, or selected, they will be used. Otherwise a selector + interface will come up. + vim:tw=78:ts=8:ft=help diff --git a/lua/neogit/buffers/commit_select_view/init.lua b/lua/neogit/buffers/commit_select_view/init.lua index 15aa430fa..62e794ae1 100644 --- a/lua/neogit/buffers/commit_select_view/init.lua +++ b/lua/neogit/buffers/commit_select_view/init.lua @@ -32,7 +32,6 @@ end function M:open(action) -- TODO: Pass this in as a param instead of reading state from object local _, item = require("neogit.status").get_current_section_item() - print("Found item: ", vim.inspect(item)) ---@type fun(commit: CommitLogEntry[])|nil local action = action @@ -44,15 +43,7 @@ function M:open(action) mappings = { v = { [""] = function() - local commits = util.filter_map( - self.buffer.ui:get_component_stack_in_linewise_selection(), - function(c) - if c.options.oid then - return c.options.oid - end - end - ) - + local commits = self.buffer.ui:get_commits_in_selection() if action and commits[1] then vim.schedule(function() self:close() @@ -74,9 +65,7 @@ function M:open(action) self:close() end, [""] = function() - local stack = self.buffer.ui:get_component_stack_under_cursor() - local commit = stack[#stack].options.oid - + local commit = self.buffer.ui:get_commit_under_cursor() if action and commit then vim.schedule(function() self:close() diff --git a/lua/neogit/buffers/commit_view/init.lua b/lua/neogit/buffers/commit_view/init.lua index 35c07d033..2c69c9832 100644 --- a/lua/neogit/buffers/commit_view/init.lua +++ b/lua/neogit/buffers/commit_view/init.lua @@ -4,9 +4,7 @@ local parser = require("neogit.buffers.commit_view.parsing") local ui = require("neogit.buffers.commit_view.ui") local log = require("neogit.lib.git.log") local config = require("neogit.config") - -local CherryPickPopup = require("neogit.popups.cherry_pick") -local RevertPopup = require("neogit.popups.revert") +local popups = require("neogit.popups") local api = vim.api @@ -127,12 +125,21 @@ function M:open() vim.cmd("normal! zt") end end, - ["A"] = function() - CherryPickPopup.create { commits = { self.commit_info.oid } } - end, - ["v"] = function() - RevertPopup.create { commits = { self.commit_info.oid } } - end, + ["A"] = popups.open("cherry_pick", function(p) + p { commits = { self.commit_info.oid } } + end), + ["b"] = popups.open("branch", function(p) + p { revisions = { self.commit_info.oid } } + end), + ["c"] = popups.open("commit", function(p) + p { commit = self.commit_info.oid } + end), + ["r"] = popups.open("rebase", function(p) + p { commit = self.commit_info.oid } + end), + ["v"] = popups.open("revert", function(p) + p { commits = { self.commit_info.oid } } + end), ["q"] = function() self:close() end, diff --git a/lua/neogit/buffers/log_view/init.lua b/lua/neogit/buffers/log_view/init.lua index 9194e77ba..42cc62b56 100644 --- a/lua/neogit/buffers/log_view/init.lua +++ b/lua/neogit/buffers/log_view/init.lua @@ -1,11 +1,9 @@ local Buffer = require("neogit.lib.buffer") -local util = require("neogit.lib.util") local ui = require("neogit.buffers.log_view.ui") local config = require("neogit.config") +local popups = require("neogit.popups") local CommitViewBuffer = require("neogit.buffers.commit_view") -local CherryPickPopup = require("neogit.popups.cherry_pick") -local RevertPopup = require("neogit.popups.revert") ---@class LogViewBuffer ---@field commits CommitLogEntry[] @@ -43,35 +41,21 @@ function M:open() context_highlight = false, mappings = { v = { - ["A"] = function() - local commits = util.filter_map( - self.buffer.ui:get_component_stack_in_linewise_selection(), - function(c) - if c.options.oid then - return c.options.oid - end - end - ) - - CherryPickPopup.create { commits = util.reverse(commits) } - end, - ["c"] = function() - local stack = self.buffer.ui:get_component_stack_under_cursor() - require("neogit.popups.commit").create { commit = stack[#stack].options.oid } - end, - ["v"] = function() - require("neogit.lib.notification").error("Multiple commits not yet implimented") - -- local commits = util.filter_map( - -- self.buffer.ui:get_component_stack_in_linewise_selection(), - -- function(c) - -- if c.options.oid then - -- return c.options.oid - -- end - -- end - -- ) - -- - -- RevertPopup.create { commits = util.reverse(commits) } - end, + ["A"] = popups.open("cherry_pick", function(p) + p { commits = self.buffer.ui:get_commits_in_selection() } + end), + ["b"] = popups.open("branch", function(p) + p { revisions = self.buffer.ui:get_commits_in_selection() } + end), + ["c"] = popups.open("commit", function(p) + p { commit = self.buffer.ui:get_commit_under_cursor() } + end), + ["r"] = popups.open("rebase", function(p) + p { commit = self.buffer.ui:get_commit_under_cursor() } + end), + ["v"] = popups.open("revert", function(p) + p { commits = self.buffer.ui:get_commits_in_selection() } + end), }, n = { ["q"] = function() @@ -80,21 +64,23 @@ function M:open() [""] = function() self:close() end, - ["A"] = function() - local stack = self.buffer.ui:get_component_stack_under_cursor() - CherryPickPopup.create { commits = { stack[#stack].options.oid } } - end, - ["c"] = function() - local stack = self.buffer.ui:get_component_stack_under_cursor() - require("neogit.popups.commit").create { commit = stack[#stack].options.oid } - end, - ["v"] = function() - local stack = self.buffer.ui:get_component_stack_under_cursor() - RevertPopup.create { commits = { stack[#stack].options.oid } } - end, + ["A"] = popups.open("cherry_pick", function(p) + p { commits = { self.buffer.ui:get_commit_under_cursor() } } + end), + ["b"] = popups.open("branch", function(p) + p { revisions = { self.buffer.ui:get_commit_under_cursor() } } + end), + ["c"] = popups.open("commit", function(p) + p { commit = self.buffer.ui:get_commit_under_cursor() } + end), + ["r"] = popups.open("rebase", function(p) + p { commit = self.buffer.ui:get_commit_under_cursor() } + end), + ["v"] = popups.open("revert", function(p) + p { commits = { self.buffer.ui:get_commit_under_cursor() } } + end), [""] = function() - local stack = self.buffer.ui:get_component_stack_under_cursor() - CommitViewBuffer.new(stack[#stack].options.oid):open() + CommitViewBuffer.new(self.buffer.ui:get_commit_under_cursor()):open() end, [""] = function(buffer) local stack = self.buffer.ui:get_component_stack_under_cursor() @@ -136,15 +122,9 @@ function M:open() return end - local stack = self.buffer.ui:get_component_stack_under_cursor() local dv = require("neogit.integrations.diffview") - dv.open("log", stack[#stack].options.oid) + dv.open("log", self.buffer.ui:get_commit_under_cursor()) end, - ["b"] = require("neogit.popups").open("branch", function(p) - local stack = self.buffer.ui:get_component_stack_under_cursor() - local commit = stack[#stack].options.oid - p { revisions = { commit } } - end), }, }, after = function(buffer, win) diff --git a/lua/neogit/buffers/reflog_view/init.lua b/lua/neogit/buffers/reflog_view/init.lua index c428b60c9..2ed99b138 100644 --- a/lua/neogit/buffers/reflog_view/init.lua +++ b/lua/neogit/buffers/reflog_view/init.lua @@ -1,11 +1,9 @@ local Buffer = require("neogit.lib.buffer") -local util = require("neogit.lib.util") local ui = require("neogit.buffers.reflog_view.ui") local config = require("neogit.config") +local popups = require("neogit.popups") local CommitViewBuffer = require("neogit.buffers.commit_view") -local CherryPickPopup = require("neogit.popups.cherry_pick") -local RevertPopup = require("neogit.popups.revert") ---@class ReflogViewBuffer ---@field entries ReflogEntry[] @@ -38,35 +36,21 @@ function M:open() context_highlight = true, mappings = { v = { - ["A"] = function() - local commits = util.filter_map( - self.buffer.ui:get_component_stack_in_linewise_selection(), - function(c) - if c.options.oid then - return c.options.oid - end - end - ) - - CherryPickPopup.create { commits = util.reverse(commits) } - end, - ["c"] = function() - local stack = self.buffer.ui:get_component_stack_under_cursor() - require("neogit.popups.commit").create { commit = stack[#stack].options.oid } - end, - ["v"] = function() - print("Multiple commits not yet implimented") - -- local commits = util.filter_map( - -- self.buffer.ui:get_component_stack_in_linewise_selection(), - -- function(c) - -- if c.options.oid then - -- return c.options.oid - -- end - -- end - -- ) - -- - -- RevertPopup.create { commits = util.reverse(commits) } - end, + ["A"] = popups.open("cherry_pick", function(p) + p { commits = self.buffer.ui:get_commits_in_selection() } + end), + ["b"] = popups.open("branch", function(p) + p { revisions = self.buffer.ui:get_commits_in_selection() } + end), + ["c"] = popups.open("commit", function(p) + p { commit = self.buffer.ui:get_commit_under_cursor() } + end), + ["r"] = popups.open("rebase", function(p) + p { commit = self.buffer.ui:get_commit_under_cursor() } + end), + ["v"] = popups.open("revert", function(p) + p { commits = self.buffer.ui:get_commits_in_selection() } + end), }, n = { ["q"] = function() @@ -75,18 +59,21 @@ function M:open() [""] = function() self:close() end, - ["A"] = function() - local stack = self.buffer.ui:get_component_stack_under_cursor() - CherryPickPopup.create { commits = { stack[#stack].options.oid } } - end, - ["c"] = function() - local stack = self.buffer.ui:get_component_stack_under_cursor() - require("neogit.popups.commit").create { commit = stack[#stack].options.oid } - end, - ["v"] = function() - local stack = self.buffer.ui:get_component_stack_under_cursor() - RevertPopup.create { commits = { stack[#stack].options.oid } } - end, + ["A"] = popups.open("cherry_pick", function(p) + p { commits = { self.buffer.ui:get_commit_under_cursor() } } + end), + ["b"] = popups.open("branch", function(p) + p { revisions = { self.buffer.ui:get_commit_under_cursor() } } + end), + ["c"] = popups.open("commit", function(p) + p { commit = self.buffer.ui:get_commit_under_cursor() } + end), + ["r"] = popups.open("rebase", function(p) + p { commit = self.buffer.ui:get_commit_under_cursor() } + end), + ["v"] = popups.open("revert", function(p) + p { commits = { self.buffer.ui:get_commit_under_cursor() } } + end), [""] = function() local stack = self.buffer.ui:get_component_stack_under_cursor() CommitViewBuffer.new(stack[#stack].options.oid):open() @@ -97,9 +84,8 @@ function M:open() return end - local stack = self.buffer.ui:get_component_stack_under_cursor() local dv = require("neogit.integrations.diffview") - dv.open("log", stack[#stack].options.oid) + dv.open("log", self.buffer.ui:get_commit_under_cursor()) end, }, }, diff --git a/lua/neogit/config.lua b/lua/neogit/config.lua index 37078c56a..a1ac4461c 100644 --- a/lua/neogit/config.lua +++ b/lua/neogit/config.lua @@ -151,6 +151,9 @@ function M.get_default_values() diffview = nil, }, sections = { + sequencer = { + folded = false, + }, untracked = { folded = false, }, diff --git a/lua/neogit/lib/git/cherry_pick.lua b/lua/neogit/lib/git/cherry_pick.lua index eeedf5144..ff9b4fdd5 100644 --- a/lua/neogit/lib/git/cherry_pick.lua +++ b/lua/neogit/lib/git/cherry_pick.lua @@ -12,6 +12,12 @@ function M.pick(commits, args) end function M.apply(commits, args) + args = util.filter_map(args, function(arg) + if arg ~= "--ff" then + return arg + end + end) + local result = cli["cherry-pick"].no_commit.arg_list(util.merge(args, commits)).call() if result.code ~= 0 then notif.create("Cherry Pick failed. Resolve conflicts before continuing", vim.log.levels.ERROR) diff --git a/lua/neogit/lib/git/cli.lua b/lua/neogit/lib/git/cli.lua index b53aec69d..f8823cbae 100644 --- a/lua/neogit/lib/git/cli.lua +++ b/lua/neogit/lib/git/cli.lua @@ -155,7 +155,14 @@ local configurations = { }, }, - revert = config {}, + revert = config { + flags = { + no_commit = "--no-commit", + continue = "--continue", + skip = "--skip", + abort = "--abort", + }, + }, checkout = config { short_opts = { @@ -239,12 +246,20 @@ local configurations = { commit = config { flags = { all = "--all", + no_verify = "--no-verify", amend = "--amend", only = "--only", dry_run = "--dry-run", no_edit = "--no-edit", edit = "--edit", }, + aliases = { + with_message = function(tbl) + return function(message) + return tbl.args("-F", "-").input(message) + end + end, + }, options = { commit_message_file = "--file", }, diff --git a/lua/neogit/lib/git/log.lua b/lua/neogit/lib/git/log.lua index aae2a6dc8..f80f6e623 100644 --- a/lua/neogit/lib/git/log.lua +++ b/lua/neogit/lib/git/log.lua @@ -205,7 +205,7 @@ local function parse_log(output, colored_graph) table.insert(commits, commit) elseif level then - if graph ~= commits[#commits].graph then + if graph ~= commits[#commits].graph and graph ~= "|" then table.insert(commits, { graph = graph }) end end @@ -292,4 +292,8 @@ function M.update_ref(from, to) cli["update-ref"].message(string.format("reset: moving to %s", to)).args(from, to).call() end +function M.message(commit) + return cli.log.format("%s").args(commit).call():trim().stdout[1] +end + return M diff --git a/lua/neogit/lib/git/revert.lua b/lua/neogit/lib/git/revert.lua index 14007952e..4a573dfe7 100644 --- a/lua/neogit/lib/git/revert.lua +++ b/lua/neogit/lib/git/revert.lua @@ -1,19 +1,22 @@ local cli = require("neogit.lib.git.cli") -local client = require("neogit.client") +local util = require("neogit.lib.util") local M = {} --- TODO: Add proper support for multiple commits. Gotta do something with the sequencer function M.commits(commits, args) - client.wrap(cli.revert.args(table.concat(commits, " ")).arg_list(args), { - autocmd = "NeogitRevertComplete", - refresh = "do_revert", - msg = { - setup = "Reverting...", - success = "Reverted!", - fail = "Couldn't revert", - }, - }) + return cli.revert.no_commit.arg_list(util.merge(args, commits)).call().code == 0 +end + +function M.continue() + cli.revert.continue.call_sync() +end + +function M.skip() + cli.revert.skip.call_sync() +end + +function M.abort() + cli.revert.abort.call_sync() end return M diff --git a/lua/neogit/lib/git/sequencer.lua b/lua/neogit/lib/git/sequencer.lua index c8885b970..620277f24 100644 --- a/lua/neogit/lib/git/sequencer.lua +++ b/lua/neogit/lib/git/sequencer.lua @@ -20,26 +20,35 @@ function M.pick_or_revert_in_progress() end function M.update_sequencer_status(state) - state.sequencer = { items = {}, head = nil } + state.sequencer = { items = {}, head = nil, head_oid = nil } local revert_head = state.git_path("REVERT_HEAD") local cherry_head = state.git_path("CHERRY_PICK_HEAD") if cherry_head:exists() then state.sequencer.head = "CHERRY_PICK_HEAD" + state.sequencer.head_oid = state.git_path("CHERRY_PICK_HEAD"):read() state.sequencer.cherry_pick = true elseif revert_head:exists() then state.sequencer.head = "REVERT_HEAD" + state.sequencer.head_oid = state.git_path("REVERT_HEAD"):read() state.sequencer.revert = true end local todo = state.git_path("sequencer/todo") + local orig = state.git_path("ORIG_HEAD") if todo:exists() then for line in todo:iter() do if not line:match("^#") then table.insert(state.sequencer.items, { name = line }) end end + elseif state.sequencer.head_oid and orig:exists() then + local head = state.sequencer.head_oid:sub(1, 7) + orig = orig:read():sub(1, 7) + local git = require("neogit.lib.git") + table.insert(state.sequencer.items, { name = string.format("work %s %s", orig, git.log.message(orig)) }) + table.insert(state.sequencer.items, { name = string.format("onto %s %s", head, git.log.message(head)) }) end end diff --git a/lua/neogit/lib/hl.lua b/lua/neogit/lib/hl.lua index 13cb4ef18..9a77de18c 100644 --- a/lua/neogit/lib/hl.lua +++ b/lua/neogit/lib/hl.lua @@ -174,14 +174,17 @@ function M.setup() NeogitChangeCopied = { fg = palette.bg_cyan, bold = true, italic = true }, NeogitChangeBothModified = { fg = palette.bg_yellow, bold = true, italic = true }, NeogitChangeNewFile = { fg = palette.bg_green, bold = true, italic = true }, - NeogitUntrackedfiles = { fg = palette.bg_purple, bold = true }, - NeogitUnstagedchanges = { fg = palette.bg_purple, bold = true }, - NeogitUnmergedchanges = { fg = palette.bg_purple, bold = true }, - NeogitUnpulledchanges = { fg = palette.bg_purple, bold = true }, - NeogitRecentcommits = { fg = palette.bg_purple, bold = true }, - NeogitStagedchanges = { fg = palette.bg_purple, bold = true }, - NeogitStashes = { fg = palette.bg_purple, bold = true }, - NeogitRebasing = { fg = palette.bg_purple, bold = true }, + NeogitSectionHeader = { fg = palette.bg_purple, bold = true }, + NeogitUntrackedfiles = { link = "NeogitSectionHeader" }, + NeogitUnstagedchanges = { link = "NeogitSectionHeader" }, + NeogitUnmergedchanges = { link = "NeogitSectionHeader" }, + NeogitUnpulledchanges = { link = "NeogitSectionHeader" }, + NeogitRecentcommits = { link = "NeogitSectionHeader" }, + NeogitStagedchanges = { link = "NeogitSectionHeader" }, + NeogitStashes = { link = "NeogitSectionHeader" }, + NeogitRebasing = { link = "NeogitSectionHeader" }, + NeogitPicking = { link = "NeogitSectionHeader" }, + NeogitReverting = { link = "NeogitSectionHeader" }, } -- stylua: ignore end diff --git a/lua/neogit/lib/ui/init.lua b/lua/neogit/lib/ui/init.lua index 79ee62af4..e31746a23 100644 --- a/lua/neogit/lib/ui/init.lua +++ b/lua/neogit/lib/ui/init.lua @@ -153,6 +153,22 @@ function Ui:get_component_stack_on_line(line) end) end +function Ui:get_commits_in_selection() + local commits = util.filter_map(self:get_component_stack_in_linewise_selection(), function(c) + if c.options.oid then + return c.options.oid + end + end) + + -- Reversed so that the oldest commit is the first in the list + return util.reverse(commits) +end + +function Ui:get_commit_under_cursor() + local stack = self:get_component_stack_under_cursor() + return stack[#stack].options.oid +end + function Ui.visualize_component(c, options) Ui._print_component(0, c, options or {}) if c.tag == "col" or c.tag == "row" then diff --git a/lua/neogit/popups/cherry_pick/actions.lua b/lua/neogit/popups/cherry_pick/actions.lua index 9539fcc9f..d47f46cd8 100644 --- a/lua/neogit/popups/cherry_pick/actions.lua +++ b/lua/neogit/popups/cherry_pick/actions.lua @@ -23,9 +23,7 @@ function M.pick(popup) return end - a.util.scheduler() git.cherry_pick.pick(commits, popup:get_arguments()) - a.util.scheduler() require("neogit.status").refresh(true, "cherry_pick_pick") end diff --git a/lua/neogit/popups/cherry_pick/init.lua b/lua/neogit/popups/cherry_pick/init.lua index 283a8ece8..b9cc1e173 100644 --- a/lua/neogit/popups/cherry_pick/init.lua +++ b/lua/neogit/popups/cherry_pick/init.lua @@ -17,7 +17,7 @@ function M.create(env) local p = popup .builder() :name("NeogitCherryPickPopup") - :switch("F", "ff", "Attempt fast-forward", { enabled = true }) + :switch_if(not in_progress, "F", "ff", "Attempt fast-forward", { enabled = true }) :group_heading_if(not in_progress, "Apply here") :action_if(not in_progress, "A", "Pick", actions.pick) :action_if(not in_progress, "a", "Apply", actions.apply) diff --git a/lua/neogit/popups/revert/actions.lua b/lua/neogit/popups/revert/actions.lua index 7a4f575ad..f16b4b3fe 100644 --- a/lua/neogit/popups/revert/actions.lua +++ b/lua/neogit/popups/revert/actions.lua @@ -2,6 +2,8 @@ local M = {} local a = require("plenary.async") local git = require("neogit.lib.git") +local client = require("neogit.client") +local notif = require("neogit.lib.notification") local CommitSelectViewBuffer = require("neogit.buffers.commit_select_view") ---@param popup any @@ -17,16 +19,78 @@ local function get_commits(popup) return commits or {} end --- TODO: support multiple commits +local function build_commit_message(commits) + local message = {} + table.insert(message, string.format("Revert %d commits\n", #commits)) + + for _, commit in ipairs(commits) do + table.insert(message, string.format("%s '%s'", commit:sub(1, 7), git.log.message(commit))) + end + + return table.concat(message, "\n") .. "\04" +end + function M.commits(popup) local commits = get_commits(popup) if not commits[1] then return end - git.revert.commits(commits, popup:get_arguments()) + local args = popup:get_arguments() + local success = git.revert.commits(commits, args) + if not success then + notif.create("Revert failed. Resolve conflicts before continuing", vim.log.levels.ERROR) + return + end + + local commit_cmd = git.cli.commit.no_verify.with_message(build_commit_message(commits)) + if vim.tbl_contains(args, "--edit") then + commit_cmd = commit_cmd.edit + else + commit_cmd = commit_cmd.no_edit + end + + client.wrap(commit_cmd, { + autocmd = "NeogitRevertComplete", + refresh = "do_revert", + msg = { + setup = "Reverting...", + success = "Reverted!", + fail = "Couldn't revert", + }, + }) + a.util.scheduler() require("neogit.status").refresh(true, "revert_commits") end +function M.changes(popup) + local commits = get_commits(popup) + if not commits[1] then + return + end + + git.revert.commits(commits, popup:get_arguments()) + a.util.scheduler() + require("neogit.status").refresh(true, "revert_changes") +end + +function M.continue() + git.revert.continue() + a.util.scheduler() + require("neogit.status").refresh(true, "revert_continue") +end + +function M.skip() + git.revert.skip() + a.util.scheduler() + require("neogit.status").refresh(true, "revert_skip") +end + +function M.abort() + git.revert.abort() + a.util.scheduler() + require("neogit.status").refresh(true, "revert_abort") +end + return M diff --git a/lua/neogit/popups/revert/init.lua b/lua/neogit/popups/revert/init.lua index 65831fd85..b328ef238 100644 --- a/lua/neogit/popups/revert/init.lua +++ b/lua/neogit/popups/revert/init.lua @@ -4,6 +4,7 @@ local popup = require("neogit.lib.popup") local M = {} function M.create(env) + local in_progress = require("neogit.lib.git.sequencer").pick_or_revert_in_progress() -- TODO: enabled = true needs to check if incompatible switch is toggled in internal state, and not apply. -- if you enable 'no edit', and revert, next time you load the popup both will be enabled -- @@ -11,14 +12,19 @@ function M.create(env) -- :switch("s", "signoff", "Add Signed-off-by lines") -- :option("S", "gpg-sign", "", "Sign using gpg") + -- stylua: ignore local p = popup .builder() :name("NeogitRevertPopup") - :option("m", "mainline", "", "Replay merge relative to parent") - :switch("e", "edit", "Edit commit messages", { enabled = true, incompatible = { "no-edit" } }) - :switch("E", "no-edit", "Don't edit commit messages", { incompatible = { "edit" } }) - :action("v", "Revert commit", actions.commits) -- TODO: Support multiple commits - :action("V", "Revert changes") + :option_if(not in_progress, "m", "mainline", "", "Replay merge relative to parent") + :switch_if(not in_progress, "e", "edit", "Edit commit messages", { enabled = true, incompatible = { "no-edit" } }) + :switch_if(not in_progress, "E", "no-edit", "Don't edit commit messages", { incompatible = { "edit" } }) + :group_heading("Revert") + :action_if(not in_progress, "v", "Commit(s)", actions.commits) + :action_if(not in_progress, "V", "Changes", actions.changes) + :action_if(in_progress, "v", "continue", actions.continue) + :action_if(in_progress, "s", "skip", actions.skip) + :action_if(in_progress, "a", "abort", actions.abort) :env({ commits = env.commits or {} }) :build() diff --git a/lua/neogit/status.lua b/lua/neogit/status.lua index f1f980a0e..92a9457b6 100644 --- a/lua/neogit/status.lua +++ b/lua/neogit/status.lua @@ -310,6 +310,10 @@ local function draw_buffer() if git.repo.rebase.head then render_section("Rebasing: " .. git.repo.rebase.head, "rebase") + elseif git.repo.sequencer.head == "REVERT_HEAD" then + render_section("Reverting", "sequencer") + elseif git.repo.sequencer.head == "CHERRY_PICK_HEAD" then + render_section("Picking", "sequencer") end render_section("Untracked files", "untracked") diff --git a/syntax/NeogitStatus.vim b/syntax/NeogitStatus.vim index e6f590f9d..d460c8ccd 100644 --- a/syntax/NeogitStatus.vim +++ b/syntax/NeogitStatus.vim @@ -5,6 +5,10 @@ endif " Support the rebase todo highlights source $VIMRUNTIME/syntax/gitrebase.vim +" Added for Reverting section when sequencer/todo doesn't exist +syn match gitrebasePick "\v^work=>" nextgroup=gitrebaseCommit skipwhite +syn match gitrebaseBreak "\v^onto=>" nextgroup=gitrebaseCommit skipwhite + syn match NeogitCommitMessage /.*/ contained syn match NeogitBranch /\S\+/ contained nextgroup=NeogitCommitMessage syn match NeogitRemote /\S\+/ contained nextgroup=NeogitCommitMessage @@ -16,7 +20,7 @@ syn match NeogitUnpulledFrom /Unpulled from/ contained syn match NeogitStash /stash@{[0-9]*}\ze/ syn match NeogitObjectId /^[a-z0-9]\{7,}\>\s/ -let b:sections = ["Untracked files", "Unstaged changes", "Unmerged changes", "Unpulled changes", "Recent commits", "Staged changes", "Stashes", "Rebasing"] +let b:sections = ["Untracked files", "Unstaged changes", "Unmerged changes", "Unpulled changes", "Recent commits", "Staged changes", "Stashes", "Rebasing", "Reverting", "Picking"] for section in b:sections let id = join(split(section, " "), "")