Skip to content

Add auto-fetch feature #1761

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions lua/neogit/autocmds.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,21 @@ function M.setup()
local status_buffer = require("neogit.buffers.status")
local git = require("neogit.lib.git")
local group = require("neogit").autocmd_group
local config = require("neogit.config")

if config.values.auto_fetch_enabled and config.values.auto_fetch_on_startup then
api.nvim_create_autocmd("VimEnter", {
callback = function()
if git.cli.is_inside_worktree(".") then
local repo = require("neogit.lib.git.repository").instance(".")
vim.schedule(function()
repo:_fetch()
end)
end
end,
group = group,
})
end

api.nvim_create_autocmd({ "ColorScheme" }, {
callback = function()
Expand Down
9 changes: 9 additions & 0 deletions lua/neogit/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,9 @@ end
---@field disable_signs? boolean Special signs to draw for sections etc. in Neogit
---@field prompt_force_push? boolean Offer to force push when branches diverge
---@field git_services? table Templartes to use when opening a pull request for a branch
---@field auto_fetch_enabled? boolean Enable/disable automatic fetching
---@field auto_fetch_interval? integer The interval (in milliseconds) for automatic fetching
---@field auto_fetch_on_startup? boolean Perform an initial fetch when Neogit starts
---@field fetch_after_checkout? boolean Perform a fetch if the newly checked out branch has an upstream or pushRemote set
---@field telescope_sorter? function The sorter telescope will use
---@field process_spinner? boolean Hide/Show the process spinner
Expand Down Expand Up @@ -399,6 +402,9 @@ function M.get_default_values()
disable_insert_on_commit = "auto",
use_per_project_settings = true,
remember_settings = true,
auto_fetch_enabled = false,
auto_fetch_interval = 300000, -- 5 minutes in milliseconds
auto_fetch_on_startup = false,
fetch_after_checkout = false,
sort_branches = "-committerdate",
kind = "tab",
Expand Down Expand Up @@ -1132,6 +1138,9 @@ function M.validate_config()
end

if validate_type(config, "base config", "table") then
validate_type(config.auto_fetch_enabled, "auto_fetch_enabled", "boolean")
validate_type(config.auto_fetch_interval, "auto_fetch_interval", "number")
validate_type(config.auto_fetch_on_startup, "auto_fetch_on_startup", "boolean")
validate_type(config.disable_hint, "disable_hint", "boolean")
validate_type(config.disable_context_highlighting, "disable_context_highlighting", "boolean")
validate_type(config.disable_signs, "disable_signs", "boolean")
Expand Down
13 changes: 9 additions & 4 deletions lua/neogit/lib/git/fetch.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,16 @@ function M.fetch_interactive(remote, branch, args)
return git.cli.fetch.args(remote or "", branch or "").arg_list(args).call { pty = true }
end

---@param remote string
---@param branch string
---@return ProcessResult
---@param remote string | nil
---@param branch string | nil
function M.fetch(remote, branch)
return git.cli.fetch.args(remote, branch).call { ignore_error = true }
local result = git.cli.fetch.args(remote, branch).call { ignore_error = true }

if result and result.code == 0 then
return true, result
else
return false, result
end
end

return M
82 changes: 82 additions & 0 deletions lua/neogit/lib/git/repository.lua
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ local Path = require("plenary.path")
local git = require("neogit.lib.git")
local ItemFilter = require("neogit.lib.item_filter")
local util = require("neogit.lib.util")
local notification = require("neogit.lib.notification")
local event = require("neogit.lib.event")

local modules = {
"status",
Expand Down Expand Up @@ -169,6 +171,10 @@ local function empty_state()
}
end

---@class NeogitRepoAutoFetch
---@field timer uv_timer_t
---@field interval integer

---@class NeogitRepo
---@field lib table
---@field state NeogitRepoState
Expand All @@ -179,6 +185,7 @@ end
---@field interrupt table
---@field tmp_state table
---@field refresh_callbacks function[]
---@field auto_fetch NeogitRepoAutoFetch|nil
local Repo = {}
Repo.__index = Repo

Expand Down Expand Up @@ -219,6 +226,7 @@ function Repo.new(dir)
running = util.weak_table(),
interrupt = util.weak_table(),
tmp_state = util.weak_table("v"),
auto_fetch = nil,
}

instance.state.worktree_root = instance.worktree_root
Expand All @@ -231,6 +239,10 @@ function Repo.new(dir)
require("neogit.lib.git." .. m).register(instance.lib)
end

if instance.worktree_root ~= "" then
instance:_setup_auto_fetch()
end

return instance
end

Expand Down Expand Up @@ -344,4 +356,74 @@ Repo.dispatch_refresh = a.void(function(self, opts)
self:refresh(opts)
end)

function Repo:_setup_auto_fetch()
local config = require("neogit.config")

if config.values.auto_fetch_enabled then
logger.debug("[REPO]: Setting up auto-fetch for " .. self.worktree_root)

self.auto_fetch = {
timer = vim.uv.new_timer(),
interval = config.values.auto_fetch_interval,
}

self:_start_auto_fetch()
end
end

function Repo:_start_auto_fetch()
if not self.auto_fetch then
return
end

logger.debug("[REPO]: Starting auto-fetch timer")

self.auto_fetch.timer:start(
self.auto_fetch.interval,
self.auto_fetch.interval,
vim.schedule_wrap(function()
self:_fetch()
end)
)
end

function Repo:_fetch()
notification.info("Auto-fetching...")
a.void(function()
local success, result = git.fetch.fetch("--all")

if success then
notification.info("Auto-fetch complete.")
else
local error_message = "Auto-fetch failed: "
if result then
if result.stderr and #result.stderr > 0 then
if type(result.stderr) == "table" then
error_message = error_message .. table.concat(result.stderr, "\n")
elseif type(result.stderr) == "string" then
error_message = error_message .. result.stderr
else
error_message = error_message .. "Unknown stderr format."
end
elseif result.stdout and #result.stdout > 0 then
if type(result.stdout) == "table" then
error_message = error_message .. table.concat(result.stdout, "\n")
elseif type(result.stdout) == "string" then
error_message = error_message .. result.stdout
else
error_message = error_message .. "Unknown stdout format."
end
else
error_message = error_message
.. string.format("Command failed with exit code %d", result.code or -1)
end
else
error_message = error_message .. "No result returned from git command."
end
notification.error(error_message)
end
event.send("FetchComplete")
end)()
end

return Repo
Loading