Skip to content

Commit f7c7a93

Browse files
committed
feat: show ahead and behind commits in winbar
1 parent d67484f commit f7c7a93

5 files changed

Lines changed: 64 additions & 44 deletions

File tree

lua/gitlab/actions/discussions/init.lua

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ end
5555
---Makes API call to get the discussion data, stores it in the state, and calls the callback
5656
---@param callback function|nil
5757
M.load_discussions = function(callback)
58+
local git = require("gitlab.git")
59+
local ahead, behind = git.get_ahead_behind(git.get_current_branch(), git.get_remote_branch())
60+
state.ahead_behind = { ahead, behind }
5861
state.discussion_tree.last_updated = nil
5962
state.load_new_state("discussion_data", function(data)
6063
if not state.DISCUSSION_DATA then

lua/gitlab/actions/discussions/winbar.lua

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,8 @@ local function content()
9494
resolved_notes = resolved_notes,
9595
non_resolvable_notes = non_resolvable_notes,
9696
help_keymap = state.settings.keymaps.help,
97+
ahead = state.ahead_behind[1],
98+
behind = state.ahead_behind[2],
9799
updated = updated,
98100
}
99101

@@ -158,7 +160,7 @@ end
158160
M.make_winbar = function(t)
159161
local discussions_focused = M.current_view_type == "discussions"
160162
local discussion_text = add_drafts_and_resolvable(
161-
"Inline Comments:",
163+
"Comments:",
162164
t.resolvable_discussions,
163165
t.resolved_discussions,
164166
t.inline_draft_notes,
@@ -190,15 +192,18 @@ M.make_winbar = function(t)
190192
local separator = "%#Comment#|"
191193
local end_section = "%="
192194
local updated = "%#Text#" .. t.updated
195+
local ahead_behind = M.get_ahead_behind(t.ahead, t.behind)
193196
local help = "%#Comment#Help: " .. (t.help_keymap and t.help_keymap:gsub(" ", "<space>") .. " " or "unmapped")
194197
return string.format(
195-
" %s %s %s %s %s %s %s %s %s %s %s",
198+
" %s %s %s %s %s %s %s %s %s %s %s %s %s",
196199
discussion_text,
197200
separator,
198201
notes_text,
199202
end_section,
200203
updated,
201204
separator,
205+
ahead_behind,
206+
separator,
202207
sort_method,
203208
separator,
204209
mode,
@@ -254,6 +259,16 @@ M.get_mode = function()
254259
end
255260
end
256261

262+
---@param ahead number|nil
263+
---@param behind number|nil
264+
M.get_ahead_behind = function(ahead, behind)
265+
local a = ahead == nil and "?" or tostring(ahead)
266+
local b = behind == nil and "?" or tostring(behind)
267+
a = ((a == "?" or a == "0") and "%#Comment#" or "%#WarningMsg#") .. a
268+
b = ((b == "?" or b == "0") and "%#Comment#" or "%#WarningMsg#") .. b
269+
return a .. "" .. b .. ""
270+
end
271+
257272
---Toggles the current view type (or sets it to `override`) and then updates the view.
258273
---@param override "discussions"|"notes" Defines the view type to select.
259274
M.switch_view_type = function(override)

lua/gitlab/annotations.lua

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@
9292
---@field resolved_notes number
9393
---@field non_resolvable_notes number
9494
---@field help_keymap string
95+
---@field ahead number|nil -- Number of commits local is ahead of remote
96+
---@field behind number|nil -- Number of commits local is behind remote
9597
---@field updated string
9698
---
9799
---@class SignTable

lua/gitlab/git.lua

Lines changed: 37 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -74,54 +74,34 @@ M.fetch_remote_branch = function(remote_branch)
7474
return true
7575
end
7676

77-
---Determines whether the tracking branch is ahead of or behind the current branch, and warns the user if so
78-
---@param current_branch string
79-
---@param remote_branch string
80-
---@param log_level number
81-
---@return boolean
82-
M.get_ahead_behind = function(current_branch, remote_branch, log_level)
77+
---Determines whether the tracking branch is ahead of or behind the current branch and returns the
78+
---number of ahead and behind commits or nil values in case of errors.
79+
---@param current_branch string|nil
80+
---@param remote_branch string|nil
81+
---@return integer|nil ahead, integer|nil behind
82+
M.get_ahead_behind = function(current_branch, remote_branch)
83+
if current_branch == nil or remote_branch == nil then
84+
return nil, nil
85+
end
8386
if not M.fetch_remote_branch(remote_branch) then
84-
return false
87+
return nil, nil
8588
end
8689

8790
local u = require("gitlab.utils")
8891
local result, err =
8992
run_system({ "git", "rev-list", "--left-right", "--count", current_branch .. "..." .. remote_branch })
9093
if err ~= nil or result == nil then
9194
u.notify("Could not determine if branch is up-to-date: " .. err, vim.log.levels.ERROR)
92-
return false
95+
return nil, nil
9396
end
9497

9598
local ahead, behind = result:match("(%d+)%s+(%d+)")
9699
if ahead == nil or behind == nil then
97-
u.notify("Error parsing ahead/behind information.", vim.log.levels.ERROR)
98-
return false
99-
end
100-
101-
ahead = tonumber(ahead)
102-
behind = tonumber(behind)
103-
104-
if ahead > 0 and behind == 0 then
105-
u.notify(string.format("There are local changes that haven't been pushed to %s yet", remote_branch), log_level)
106-
return false
107-
end
108-
if behind > 0 and ahead == 0 then
109-
u.notify(string.format("There are remote changes on %s that haven't been pulled yet", remote_branch), log_level)
110-
return false
111-
end
112-
113-
if ahead > 0 and behind > 0 then
114-
u.notify(
115-
string.format(
116-
"Your branch and the remote %s have diverged. You need to pull, possibly rebase, and then push.",
117-
remote_branch
118-
),
119-
log_level
120-
)
121-
return false
100+
u.notify("Error parsing ahead/behind information", vim.log.levels.ERROR)
101+
return nil, nil
122102
end
123103

124-
return true -- Checks passed, branch is up-to-date
104+
return tonumber(ahead), tonumber(behind)
125105
end
126106

127107
---Return the name of the current branch or nil if it can't be retrieved
@@ -184,16 +164,35 @@ end
184164
---@return boolean
185165
M.check_current_branch_up_to_date_on_remote = function(log_level)
186166
local current_branch = M.get_current_branch()
187-
if current_branch == nil then
167+
local remote_branch = M.get_remote_branch()
168+
local ahead, behind = M.get_ahead_behind(current_branch, remote_branch)
169+
if ahead == nil or behind == nil then
188170
return false
189171
end
190172

191-
local remote_branch = M.get_remote_branch()
192-
if remote_branch == nil then
173+
local u = require("gitlab.utils")
174+
175+
if ahead > 0 and behind == 0 then
176+
u.notify(string.format("There are local changes that haven't been pushed to %s yet", remote_branch), log_level)
177+
return false
178+
end
179+
if behind > 0 and ahead == 0 then
180+
u.notify(string.format("There are remote changes on %s that haven't been pulled yet", remote_branch), log_level)
193181
return false
194182
end
195183

196-
return M.get_ahead_behind(current_branch, remote_branch, log_level)
184+
if ahead > 0 and behind > 0 then
185+
u.notify(
186+
string.format(
187+
"Your branch and the remote %s have diverged. You need to pull, possibly rebase, and then push.",
188+
remote_branch
189+
),
190+
log_level
191+
)
192+
return false
193+
end
194+
195+
return true -- Checks passed, branch is up-to-date
197196
end
198197

199198
---Warns user if the current MR is in a bad state (closed, has conflicts, merged)

lua/gitlab/state.lua

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,16 +3,17 @@
33
-- This module is also responsible for ensuring that the state of the plugin
44
-- is valid via dependencies
55

6-
local git = require("gitlab.git")
76
local u = require("gitlab.utils")
87
local List = require("gitlab.utils.list")
9-
local M = {}
10-
11-
M.emoji_map = nil
8+
local M = {
9+
emoji_map = nil,
10+
ahead_behind = { nil, nil },
11+
}
1212

1313
---Returns a gitlab token, and a gitlab URL. Used to connect to gitlab.
1414
---@return string|nil, string|nil, string|nil
1515
M.default_auth_provider = function()
16+
local git = require("gitlab.git")
1617
local base_path, err = M.settings.config_path, nil
1718
if base_path == nil then
1819
base_path, err = git.base_dir()

0 commit comments

Comments
 (0)