Skip to content

Commit 4e660b9

Browse files
zdmdlyongemallo
authored andcommitted
feat(git): add MSYS2/Cygwin path normalization
When running native Windows Neovim with Cygwin-based git, commands like `rev-parse --show-toplevel` return Unix-style paths (e.g. `/c/Users/...`) that Neovim cannot use. Detect this case and convert via `cygpath --absolute --windows`. Only fires when `has('win32')` is true and the path starts with `/`, so Linux/macOS users are unaffected. Based on softvisio/diffview.nvim (commits a67c42d, 06232a8) and upstream PR sindrets#574, with modifications: use `vim.trim()` instead of manual newline stripping, add type annotations, use double quotes.
1 parent ffc58f6 commit 4e660b9

File tree

1 file changed

+29
-2
lines changed

1 file changed

+29
-2
lines changed

lua/diffview/vcs/adapters/git/init.lua

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,33 @@ function GitAdapter.get_repo_paths(path_args, cpath)
166166
return paths, top_indicators
167167
end
168168

169+
---Convert MSYS2/Cygwin Unix-style paths to Windows paths when running on
170+
---native Windows with a Cygwin-based git. Without this, paths like
171+
---`/c/Users/...` returned by Cygwin git are unusable by Neovim.
172+
---See: https://www.msys2.org/docs/git/
173+
---@param path string?
174+
---@return string?
175+
local has_cygpath ---@type boolean?
176+
local function normalize_cygwin_path(path)
177+
if not path or vim.fn.has("win32") ~= 1 or path:sub(1, 1) ~= "/" then
178+
return path
179+
end
180+
181+
if has_cygpath == nil then
182+
has_cygpath = vim.fn.executable("cygpath") == 1
183+
end
184+
185+
if has_cygpath then
186+
local result = vim.trim(vim.fn.system({ "cygpath", "--absolute", "--windows", path }))
187+
if vim.v.shell_error ~= 0 or result == "" then
188+
return path
189+
end
190+
return result
191+
end
192+
193+
return path
194+
end
195+
169196
---Get the git toplevel directory from a path to file or directory
170197
---@param path string
171198
---@return string?
@@ -177,7 +204,7 @@ local function get_toplevel(path)
177204
if code ~= 0 then
178205
return nil
179206
end
180-
return out[1] and vim.trim(out[1])
207+
return normalize_cygwin_path(out[1] and vim.trim(out[1]))
181208
end
182209

183210
---Try to find the top-level of a working tree by using the given indicative
@@ -279,7 +306,7 @@ function GitAdapter:get_dir(path)
279306
if code ~= 0 then
280307
return nil
281308
end
282-
return out[1] and vim.trim(out[1])
309+
return normalize_cygwin_path(out[1] and vim.trim(out[1]))
283310
end
284311

285312
---Verify that a given git rev is valid.

0 commit comments

Comments
 (0)