Skip to content

Commit dc168ab

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 92d1dc3 commit dc168ab

1 file changed

Lines changed: 25 additions & 2 deletions

File tree

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

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,29 @@ 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+
return vim.trim(vim.fn.system({ "cygpath", "--absolute", "--windows", path }))
187+
end
188+
189+
return path
190+
end
191+
169192
---Get the git toplevel directory from a path to file or directory
170193
---@param path string
171194
---@return string?
@@ -177,7 +200,7 @@ local function get_toplevel(path)
177200
if code ~= 0 then
178201
return nil
179202
end
180-
return out[1] and vim.trim(out[1])
203+
return normalize_cygwin_path(out[1] and vim.trim(out[1]))
181204
end
182205

183206
---Try to find the top-level of a working tree by using the given indicative
@@ -279,7 +302,7 @@ function GitAdapter:get_dir(path)
279302
if code ~= 0 then
280303
return nil
281304
end
282-
return out[1] and vim.trim(out[1])
305+
return normalize_cygwin_path(out[1] and vim.trim(out[1]))
283306
end
284307

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

0 commit comments

Comments
 (0)