From f5d11a30984b77ab5a33a3efb4c9cec49fd443ab Mon Sep 17 00:00:00 2001 From: Lars Hansen Date: Wed, 6 May 2026 09:34:26 +0200 Subject: [PATCH] fix(diff): correctly relativize paths for diffing current buffer (#108) --- lua/jj/annotate.lua | 2 +- lua/jj/diff/diffview.lua | 2 +- lua/jj/diff/native.lua | 2 +- lua/jj/file.lua | 6 +++--- lua/jj/utils.lua | 28 +++++++++++++--------------- 5 files changed, 19 insertions(+), 21 deletions(-) diff --git a/lua/jj/annotate.lua b/lua/jj/annotate.lua index 29d1820..06573e7 100644 --- a/lua/jj/annotate.lua +++ b/lua/jj/annotate.lua @@ -29,7 +29,7 @@ local function get_annotate_target() return nil, nil, "Invalid jj:// buffer name" end - local normalized, err = utils.normalize_repo_path(filename) + local normalized, err = utils.normalize_relative_path(filename) if not normalized then return nil, nil, err or "Could not normalize file path" end diff --git a/lua/jj/diff/diffview.lua b/lua/jj/diff/diffview.lua index 6e7ff81..f885a11 100644 --- a/lua/jj/diff/diffview.lua +++ b/lua/jj/diff/diffview.lua @@ -56,7 +56,7 @@ diff.register_backend("diffview", { end local raw_path = opts.path or jj_path or "%" - local path, err = utils.normalize_repo_path(raw_path) + local path, err = utils.normalize_relative_path(raw_path) if not path then utils.notify(err or "Could not resolve file path for Diffview", vim.log.levels.ERROR) return diff --git a/lua/jj/diff/native.lua b/lua/jj/diff/native.lua index bbf085e..665b3f3 100644 --- a/lua/jj/diff/native.lua +++ b/lua/jj/diff/native.lua @@ -21,7 +21,7 @@ local function open_revision(rev, path) end local change_id = ids[1] - local rel_path, err = utils.normalize_repo_path(path) + local rel_path, err = utils.normalize_relative_path(path) if not rel_path then utils.notify(err or "Could not resolve path", vim.log.levels.ERROR) return diff --git a/lua/jj/file.lua b/lua/jj/file.lua index b8a687c..c0f3ae0 100644 --- a/lua/jj/file.lua +++ b/lua/jj/file.lua @@ -18,7 +18,7 @@ local parser = require("jj.core.parser") --- Fetch file content from jj synchronously. --- Returns lines with blank lines preserved; trailing empty line removed. --- @param rev string The revision (change ID or other revset) ---- @param path string Repository-relative path +--- @param path string Cwd-relative path --- @return string[] lines --- @return boolean had_eol Whether the content had a trailing newline --- @return boolean ok Whether the command succeeded @@ -46,7 +46,7 @@ M.get_file_content = get_file_content function M.read_target(opts) local revision = opts and opts.rev or "@" local raw_path = opts and opts.path or "%" - local path, normalize_err = utils.normalize_repo_path(raw_path) + local path, normalize_err = utils.normalize_relative_path(raw_path) if not path then utils.notify(normalize_err or "Could not normalize path", vim.log.levels.ERROR) return @@ -127,7 +127,7 @@ M.write_revision_file = write_revision_file function M.open_target(opts) local revision = opts.rev or "@" local raw_path = opts.path or "%" - local path, normalize_err = utils.normalize_repo_path(raw_path) + local path, normalize_err = utils.normalize_relative_path(raw_path) if not path then utils.notify(normalize_err or "Could not normalize path", vim.log.levels.ERROR) return diff --git a/lua/jj/utils.lua b/lua/jj/utils.lua index 598c017..f0f7d82 100644 --- a/lua/jj/utils.lua +++ b/lua/jj/utils.lua @@ -161,18 +161,17 @@ function M.parse_jj_uri(name) return name:match("^jj://([^/]+)/(.+)$") end ---- Normalize a user-provided file path to a repository-relative path for jj commands. +--- Normalize a user-provided file path to a cwd-relative path for jj commands. --- --- Rules: --- - `%` resolves to the current buffer absolute file path. ---- - Absolute paths are converted to repository-relative paths. ---- - Relative paths are kept relative. +--- - Absolute paths are converted to cwd-relative paths. +--- - Relative paths are kept relative (already cwd-relative). --- --- @param path string|nil Path provided by the user (`%`, absolute, or relative) ---- @param root? string Repository root (defaults to current jj repo root) ---- @return string|nil normalized_path Repository-relative normalized path +--- @return string|nil normalized_path Cwd-relative normalized path --- @return string|nil err Error message when normalization fails -function M.normalize_repo_path(path, root) +function M.normalize_relative_path(path) path = vim.trim(path or "") if path == "" then return nil, "Path is empty" @@ -191,18 +190,16 @@ function M.normalize_repo_path(path, root) path = vim.fs.normalize(path) - root = root or M.get_jj_root() - if not root or root == "" then - return nil, "Not in a jj repository" - end - - root = vim.fs.normalize(root) - local is_absolute = vim.startswith(path, "/") or path:match("^%a:/") ~= nil if is_absolute then - local rel = M.relpath(root, path) + local cwd = vim.uv.cwd() + if not cwd or cwd == "" then + return nil, "Could not determine current working directory" + end + cwd = vim.fs.normalize(cwd) + local rel = M.relpath(cwd, path) if not rel then - return nil, "Path is outside repository root" + return nil, "Path is outside current working directory" end path = rel end @@ -685,6 +682,7 @@ function M.get_describe_text(revset) return text end + --- --- Get the commit id from a given revision. Returns nil and notifies an error if multiple commit_ids are found for a single revset --- @param revset string The revset to extract the commit id from