From c171f0e6bd036677027c358cf80f390f06364072 Mon Sep 17 00:00:00 2001 From: Harrison Cramer Date: Fri, 11 Oct 2024 12:41:58 -0400 Subject: [PATCH 1/9] Updated function --- lua/gitlab/git.lua | 89 +++++++++++++++++++++++++++++++--------------- 1 file changed, 61 insertions(+), 28 deletions(-) diff --git a/lua/gitlab/git.lua b/lua/gitlab/git.lua index cced16ad..d83fb853 100644 --- a/lua/gitlab/git.lua +++ b/lua/gitlab/git.lua @@ -43,6 +43,56 @@ M.switch_branch = function(branch) return run_system({ "git", "checkout", "-q", branch }) end +---Fetches the name of the remote tracking branch for the current branch +---@return string|nil, string|nil +M.get_remote_branch = function() + return run_system({ "git", "rev-parse", "--abbrev-ref", "symbolic-full-name", "@{u}" }) +end + +---Determines whether there are unpushed commits from local to remote +---@param current_branch string +---@param remote_branch string +---@return boolean +M.get_ahead_behind = function(current_branch, remote_branch, log_level) + local result, err = + run_system({ "git", "rev-list", "--left-right", "--count", current_branch .. "..." .. remote_branch }) + if err ~= nil or result == nil then + u.notify("Could not determine if branch is up-to-date: " .. err, vim.log.levels.ERROR) + return false + end + + local ahead, behind = result:match("(%d+)%s+(%d+)") + if ahead == nil or behind == nil then + u.notify("Error parsing ahead/behind information.", vim.log.levels.ERROR) + return false + end + + ahead = tonumber(ahead) + behind = tonumber(behind) + + if ahead > 0 and behind == 0 then + u.notify( + string.format("You have local commits that are not on %s. Have you forgotten to push?", remote_branch), + log_level + ) + return false + end + if behind > 0 and ahead == 0 then + u.notify(string.format("There are remote changes on %s that haven't been pulled yet", remote_branch), log_level) + return false + end + + if ahead > 0 and behind > 0 then + u.notify( + string.format("Your branch and the remote %s have diverged. You need to pull and then push.", remote_branch), + log_level + ) + return false + end + + return true -- Checks passed, branch is up-to-date +end + ---Return the name of the current branch ---@return string|nil, string|nil M.get_current_branch = function() @@ -93,39 +143,22 @@ M.contains_branch = function(current_branch) return run_system({ "git", "branch", "-r", "--contains", current_branch }) end ----Returns true if `branch` is up-to-date on remote, false otherwise. +---Returns true if `branch` is up-to-date on remote ---@param log_level integer ----@return boolean|nil +---@return boolean M.current_branch_up_to_date_on_remote = function(log_level) - local state = require("gitlab.state") - local current_branch = M.get_current_branch() - local handle = io.popen("git branch -r --contains " .. current_branch .. " 2>&1") - if not handle then - require("gitlab.utils").notify("Error running 'git branch' command.", vim.log.levels.ERROR) - return nil + -- Get current branch + local current_branch, err = M.get_current_branch() + if not current_branch or err ~= nil then + return false end - local remote_branches_with_current_head = {} - for line in handle:lines() do - table.insert(remote_branches_with_current_head, line) + -- Get remote tracking branch + local remote_branch, err = M.get_current_branch() + if not remote_branch or err ~= nil then + return false end - handle:close() - local current_head_on_remote = List.new(remote_branches_with_current_head):filter(function(line) - return line == string.format(" %s/", state.settings.connection_settings.remote) .. current_branch - end) - local remote_up_to_date = #current_head_on_remote == 1 - - if not remote_up_to_date then - require("gitlab.utils").notify( - string.format( - "You have local commits that are not on %s. Have you forgotten to push?", - state.settings.connection_settings.remote - ), - log_level - ) - end - return remote_up_to_date + return M.get_ahead_behind(current_branch, remote_branch, log_level) end - return M From bcf4fe85e789a66837ea9ec12c4702244304ab22 Mon Sep 17 00:00:00 2001 From: Harrison Cramer Date: Fri, 11 Oct 2024 13:04:03 -0400 Subject: [PATCH 2/9] Updated condition check + remote branch check --- lua/gitlab/actions/summary.lua | 1 + lua/gitlab/git.lua | 39 ++++++++++++++++++++++++++++------ lua/gitlab/reviewer/init.lua | 13 +----------- 3 files changed, 35 insertions(+), 18 deletions(-) diff --git a/lua/gitlab/actions/summary.lua b/lua/gitlab/actions/summary.lua index 613b4df7..d5e2a1d7 100644 --- a/lua/gitlab/actions/summary.lua +++ b/lua/gitlab/actions/summary.lua @@ -83,6 +83,7 @@ M.summary = function() end) git.current_branch_up_to_date_on_remote(vim.log.levels.WARN) + git.check_mr_in_good_condition() end -- Builds a lua list of strings that contain metadata about the current MR. Only builds the diff --git a/lua/gitlab/git.lua b/lua/gitlab/git.lua index d83fb853..24cbd89b 100644 --- a/lua/gitlab/git.lua +++ b/lua/gitlab/git.lua @@ -46,7 +46,7 @@ end ---Fetches the name of the remote tracking branch for the current branch ---@return string|nil, string|nil M.get_remote_branch = function() - return run_system({ "git", "rev-parse", "--abbrev-ref", "symbolic-full-name", "@{u}" }) + return run_system({ "git", "rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{u}" }) end ---Determines whether there are unpushed commits from local to remote @@ -54,6 +54,7 @@ end ---@param remote_branch string ---@return boolean M.get_ahead_behind = function(current_branch, remote_branch, log_level) + local u = require("gitlab.utils") local result, err = run_system({ "git", "rev-list", "--left-right", "--count", current_branch .. "..." .. remote_branch }) if err ~= nil or result == nil then @@ -84,7 +85,10 @@ M.get_ahead_behind = function(current_branch, remote_branch, log_level) if ahead > 0 and behind > 0 then u.notify( - string.format("Your branch and the remote %s have diverged. You need to pull and then push.", remote_branch), + string.format( + "Your branch and the remote %s have diverged. You need to pull, possibly rebase, and then push.", + remote_branch + ), log_level ) return false @@ -143,22 +147,45 @@ M.contains_branch = function(current_branch) return run_system({ "git", "branch", "-r", "--contains", current_branch }) end ----Returns true if `branch` is up-to-date on remote +---Returns true if `branch` is up-to-date on remote, otherwise false and warns user ---@param log_level integer ---@return boolean M.current_branch_up_to_date_on_remote = function(log_level) + local u = require("gitlab.utils") + -- Get current branch local current_branch, err = M.get_current_branch() - if not current_branch or err ~= nil then + if err or not current_branch then + u.notify("Could not get current branch", vim.log.levels.ERROR) return false end -- Get remote tracking branch - local remote_branch, err = M.get_current_branch() - if not remote_branch or err ~= nil then + local remote_branch, err = M.get_remote_branch() + if err or not remote_branch then + u.notify("Could not get remote branch", vim.log.levels.ERROR) return false end return M.get_ahead_behind(current_branch, remote_branch, log_level) end + +---Warns user if the current MR is in a bad state (closed, has conflicts, merged) +M.check_mr_in_good_condition = function() + local state = require("gitlab.state") + local u = require("gitlab.utils") + + if state.INFO.has_conflicts then + u.notify("This merge request has conflicts!", vim.log.levels.WARN) + end + + if state.INFO.state == "closed" then + u.notify(string.format("This MR was closed %s", u.time_since(state.INFO.closed_at)), vim.log.levels.WARN) + end + + if state.INFO.state == "merged" then + u.notify(string.format("This MR was merged %s", u.time_since(state.INFO.merged_at)), vim.log.levels.WARN) + end +end + return M diff --git a/lua/gitlab/reviewer/init.lua b/lua/gitlab/reviewer/init.lua index 185c01bc..6d5c8dec 100644 --- a/lua/gitlab/reviewer/init.lua +++ b/lua/gitlab/reviewer/init.lua @@ -62,18 +62,6 @@ M.open = function() ) end - if state.INFO.has_conflicts then - u.notify("This merge request has conflicts!", vim.log.levels.WARN) - end - - if state.INFO.state == "closed" then - u.notify(string.format("This MR was closed %s", u.time_since(state.INFO.closed_at)), vim.log.levels.WARN) - end - - if state.INFO.state == "merged" then - u.notify(string.format("This MR was merged %s", u.time_since(state.INFO.merged_at)), vim.log.levels.WARN) - end - if state.settings.discussion_diagnostic ~= nil or state.settings.discussion_sign ~= nil then u.notify( "Diagnostics are now configured as settings.discussion_signs, see :h gitlab.nvim.signs-and-diagnostics", @@ -99,6 +87,7 @@ M.open = function() end git.current_branch_up_to_date_on_remote(vim.log.levels.WARN) + git.check_mr_in_good_condition() end -- Closes the reviewer and cleans up From 18ea8ce62b216040a3af7199eb516590553b09fa Mon Sep 17 00:00:00 2001 From: Harrison Cramer Date: Fri, 11 Oct 2024 13:07:20 -0400 Subject: [PATCH 3/9] Updated lua/gitlab/git.lua --- lua/gitlab/git.lua | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lua/gitlab/git.lua b/lua/gitlab/git.lua index 24cbd89b..d2ced1c2 100644 --- a/lua/gitlab/git.lua +++ b/lua/gitlab/git.lua @@ -49,14 +49,14 @@ M.get_remote_branch = function() return run_system({ "git", "rev-parse", "--abbrev-ref", "--symbolic-full-name", "@{u}" }) end ----Determines whether there are unpushed commits from local to remote +---Determines whether the tracking branch is ahead of or behind the current branch, and warns the user if so ---@param current_branch string ---@param remote_branch string ---@return boolean M.get_ahead_behind = function(current_branch, remote_branch, log_level) local u = require("gitlab.utils") local result, err = - run_system({ "git", "rev-list", "--left-right", "--count", current_branch .. "..." .. remote_branch }) + run_system({ "git", "rev-list", "--left-right", "--count", current_branch .. "..." .. remote_branch }) if err ~= nil or result == nil then u.notify("Could not determine if branch is up-to-date: " .. err, vim.log.levels.ERROR) return false @@ -130,14 +130,14 @@ M.get_all_remote_branches = function() local u = require("gitlab.utils") local lines = u.lines_into_table(all_branches) return List.new(lines) - :map(function(line) - -- Trim the remote branch - return line:match(state.settings.connection_settings.remote .. "/(%S+)") - end) - :filter(function(branch) - -- Don't include the HEAD pointer - return not branch:match("^HEAD$") - end) + :map(function(line) + -- Trim the remote branch + return line:match(state.settings.connection_settings.remote .. "/(%S+)") + end) + :filter(function(branch) + -- Don't include the HEAD pointer + return not branch:match("^HEAD$") + end) end ---Return whether something From bec580e503e51d180bf2409567eb8c6e570c2db0 Mon Sep 17 00:00:00 2001 From: Harrison Cramer Date: Fri, 11 Oct 2024 13:07:36 -0400 Subject: [PATCH 4/9] formatting --- lua/gitlab/git.lua | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/lua/gitlab/git.lua b/lua/gitlab/git.lua index d2ced1c2..cda87747 100644 --- a/lua/gitlab/git.lua +++ b/lua/gitlab/git.lua @@ -56,7 +56,7 @@ end M.get_ahead_behind = function(current_branch, remote_branch, log_level) local u = require("gitlab.utils") local result, err = - run_system({ "git", "rev-list", "--left-right", "--count", current_branch .. "..." .. remote_branch }) + run_system({ "git", "rev-list", "--left-right", "--count", current_branch .. "..." .. remote_branch }) if err ~= nil or result == nil then u.notify("Could not determine if branch is up-to-date: " .. err, vim.log.levels.ERROR) return false @@ -130,14 +130,14 @@ M.get_all_remote_branches = function() local u = require("gitlab.utils") local lines = u.lines_into_table(all_branches) return List.new(lines) - :map(function(line) - -- Trim the remote branch - return line:match(state.settings.connection_settings.remote .. "/(%S+)") - end) - :filter(function(branch) - -- Don't include the HEAD pointer - return not branch:match("^HEAD$") - end) + :map(function(line) + -- Trim the remote branch + return line:match(state.settings.connection_settings.remote .. "/(%S+)") + end) + :filter(function(branch) + -- Don't include the HEAD pointer + return not branch:match("^HEAD$") + end) end ---Return whether something From f0bed41b7a56d280339c1d7624e308793e34a13b Mon Sep 17 00:00:00 2001 From: Harrison Cramer Date: Fri, 11 Oct 2024 13:11:34 -0400 Subject: [PATCH 5/9] formatting --- lua/gitlab/git.lua | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lua/gitlab/git.lua b/lua/gitlab/git.lua index cda87747..efacfb21 100644 --- a/lua/gitlab/git.lua +++ b/lua/gitlab/git.lua @@ -154,16 +154,16 @@ M.current_branch_up_to_date_on_remote = function(log_level) local u = require("gitlab.utils") -- Get current branch - local current_branch, err = M.get_current_branch() - if err or not current_branch then - u.notify("Could not get current branch", vim.log.levels.ERROR) + local current_branch, err_current_branch = M.get_current_branch() + if err_current_branch or not current_branch then + u.notify("Could not get current branch: " .. err_current_branch, vim.log.levels.ERROR) return false end -- Get remote tracking branch - local remote_branch, err = M.get_remote_branch() - if err or not remote_branch then - u.notify("Could not get remote branch", vim.log.levels.ERROR) + local remote_branch, err_remote_branch = M.get_remote_branch() + if err_remote_branch or not remote_branch then + u.notify("Could not get remote branch: " .. err_remote_branch, vim.log.levels.ERROR) return false end From 91a6210949e6a9ea69e5f121eebd976e7fa2afd8 Mon Sep 17 00:00:00 2001 From: "Harrison (Harry) Cramer" <32515581+harrisoncramer@users.noreply.github.com> Date: Sat, 12 Oct 2024 10:00:33 -0400 Subject: [PATCH 6/9] Update lua/gitlab/git.lua MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jakub F. Bortlík --- lua/gitlab/git.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/gitlab/git.lua b/lua/gitlab/git.lua index efacfb21..37dd3093 100644 --- a/lua/gitlab/git.lua +++ b/lua/gitlab/git.lua @@ -73,7 +73,7 @@ M.get_ahead_behind = function(current_branch, remote_branch, log_level) if ahead > 0 and behind == 0 then u.notify( - string.format("You have local commits that are not on %s. Have you forgotten to push?", remote_branch), + string.format("There are local changes that haven't been pushed to %s yet", remote_branch), log_level ) return false From b98b385627fa14c77914ee34db16cf8a4515ad87 Mon Sep 17 00:00:00 2001 From: "Harrison (Harry) Cramer" <32515581+harrisoncramer@users.noreply.github.com> Date: Sat, 12 Oct 2024 10:00:54 -0400 Subject: [PATCH 7/9] Update lua/gitlab/git.lua MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jakub F. Bortlík --- lua/gitlab/git.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lua/gitlab/git.lua b/lua/gitlab/git.lua index 37dd3093..31aa3387 100644 --- a/lua/gitlab/git.lua +++ b/lua/gitlab/git.lua @@ -150,7 +150,7 @@ end ---Returns true if `branch` is up-to-date on remote, otherwise false and warns user ---@param log_level integer ---@return boolean -M.current_branch_up_to_date_on_remote = function(log_level) +M.check_current_branch_up_to_date_on_remote = function(log_level) local u = require("gitlab.utils") -- Get current branch From 140257af01ab58451c82dcb29da9875d9ab81c89 Mon Sep 17 00:00:00 2001 From: "Harrison (Harry) Cramer" <32515581+harrisoncramer@users.noreply.github.com> Date: Sat, 12 Oct 2024 10:02:32 -0400 Subject: [PATCH 8/9] Update lua/gitlab/git.lua MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Jakub F. Bortlík --- lua/gitlab/git.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/lua/gitlab/git.lua b/lua/gitlab/git.lua index 31aa3387..f77f7343 100644 --- a/lua/gitlab/git.lua +++ b/lua/gitlab/git.lua @@ -52,6 +52,7 @@ end ---Determines whether the tracking branch is ahead of or behind the current branch, and warns the user if so ---@param current_branch string ---@param remote_branch string +---@param log_level integer ---@return boolean M.get_ahead_behind = function(current_branch, remote_branch, log_level) local u = require("gitlab.utils") From 69ca6215f97fbc55d2c8ba51b4585733008f6245 Mon Sep 17 00:00:00 2001 From: Harrison Cramer Date: Sat, 12 Oct 2024 10:03:10 -0400 Subject: [PATCH 9/9] Updated function name --- lua/gitlab/actions/create_mr.lua | 2 +- lua/gitlab/actions/summary.lua | 2 +- lua/gitlab/git.lua | 7 ++----- lua/gitlab/reviewer/init.lua | 2 +- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/lua/gitlab/actions/create_mr.lua b/lua/gitlab/actions/create_mr.lua index 401162e2..2e366946 100644 --- a/lua/gitlab/actions/create_mr.lua +++ b/lua/gitlab/actions/create_mr.lua @@ -47,7 +47,7 @@ end --- continue working on it. ---@param args? Mr M.start = function(args) - if not git.current_branch_up_to_date_on_remote(vim.log.levels.ERROR) then + if not git.check_current_branch_up_to_date_on_remote(vim.log.levels.ERROR) then return end diff --git a/lua/gitlab/actions/summary.lua b/lua/gitlab/actions/summary.lua index d5e2a1d7..dfde1d73 100644 --- a/lua/gitlab/actions/summary.lua +++ b/lua/gitlab/actions/summary.lua @@ -82,7 +82,7 @@ M.summary = function() vim.api.nvim_set_current_buf(description_popup.bufnr) end) - git.current_branch_up_to_date_on_remote(vim.log.levels.WARN) + git.check_current_branch_up_to_date_on_remote(vim.log.levels.WARN) git.check_mr_in_good_condition() end diff --git a/lua/gitlab/git.lua b/lua/gitlab/git.lua index f77f7343..aa74abc0 100644 --- a/lua/gitlab/git.lua +++ b/lua/gitlab/git.lua @@ -52,7 +52,7 @@ end ---Determines whether the tracking branch is ahead of or behind the current branch, and warns the user if so ---@param current_branch string ---@param remote_branch string ----@param log_level integer +---@param log_level number ---@return boolean M.get_ahead_behind = function(current_branch, remote_branch, log_level) local u = require("gitlab.utils") @@ -73,10 +73,7 @@ M.get_ahead_behind = function(current_branch, remote_branch, log_level) behind = tonumber(behind) if ahead > 0 and behind == 0 then - u.notify( - string.format("There are local changes that haven't been pushed to %s yet", remote_branch), - log_level - ) + u.notify(string.format("There are local changes that haven't been pushed to %s yet", remote_branch), log_level) return false end if behind > 0 and ahead == 0 then diff --git a/lua/gitlab/reviewer/init.lua b/lua/gitlab/reviewer/init.lua index 6d5c8dec..89654c97 100644 --- a/lua/gitlab/reviewer/init.lua +++ b/lua/gitlab/reviewer/init.lua @@ -86,7 +86,7 @@ M.open = function() require("gitlab").toggle_discussions() -- Fetches data and opens discussions end - git.current_branch_up_to_date_on_remote(vim.log.levels.WARN) + git.check_current_branch_up_to_date_on_remote(vim.log.levels.WARN) git.check_mr_in_good_condition() end