diff options
| author | Kristoffer Balintona <krisbalintona@gmail.com> | 2026-04-27 16:50:36 -0500 |
|---|---|---|
| committer | Kristoffer Balintona <krisbalintona@gmail.com> | 2026-04-27 17:03:33 -0500 |
| commit | 03ab3ba867905fa2cf565209ac70e6df8e70c967 (patch) | |
| tree | 6a75c526a93adfe98892d3efc4e0ee1de575e0b1 | |
| parent | 1407704c50b27f99f4a44a6622e96e79850deca8 (diff) | |
fix: Address edge case in file rename tracking in vc-dir buffersexternals/vc-jj
Also add a new test case for it.
| -rw-r--r-- | vc-jj-tests.el | 23 | ||||
| -rw-r--r-- | vc-jj.el | 28 |
2 files changed, 39 insertions, 12 deletions
diff --git a/vc-jj-tests.el b/vc-jj-tests.el index 1155ecf..389635b 100644 --- a/vc-jj-tests.el +++ b/vc-jj-tests.el @@ -291,7 +291,7 @@ When a file is renamed, its old file path should have a VC state of When a directory is renamed, the files contained within it are reported along the same lines." - ;; Rename file + ;; Rename root-level file (vc-jj-test--with-repo repo ;; 2026-04-26: It seems like Jujutsu's rename detection requires ;; file content to identify a single-file rename: without content, @@ -311,7 +311,26 @@ along the same lines." ("after rename.txt" added ( :rename-state added :rename-other-filename "before rename.txt")))))) - ;; Rename subdirectory + ;; Rename file in subdirectory + (vc-jj-test--with-repo repo + (make-directory "subdir") + (write-region "foo bar" nil "subdir/before rename.txt") + (shell-command "jj new") + (shell-command "mv 'subdir/before rename.txt' 'subdir/after rename.txt'") + + (should (eq (vc-jj-state "subdir/before rename.txt") 'removed)) + (should (eq (vc-jj-state "subdir/after rename.txt") 'added)) + (should (seq-set-equal-p + (vc-jj-dir-status-files repo nil + #'vc-jj-test--dir-status-files-update-function) + '(("subdir/before rename.txt" removed + ( :rename-state removed + :rename-other-filename "subdir/after rename.txt")) + ("subdir/after rename.txt" added + ( :rename-state added + :rename-other-filename "subdir/before rename.txt")))))) + + ;; Rename entire subdirectory (vc-jj-test--with-repo repo (make-directory "dir before rename/subdir" t) ;; 2026-04-26: It seems that, unlike single-file renames, @@ -465,19 +465,27 @@ path prepended with a two-character type string indicating the before and after types of the file." (let ((table (make-hash-table :test #'equal))) (mapc (lambda (line) - (if (string-match (rx "{" (group (1+ anychar)) " => " (group (1+ anychar)) "}" - (opt "/" (group (1+ anychar)))) + (if (string-match (rx (group-n 1 (* anychar)) + "{" + (group-n 2 (1+ (not (any "}")))) + " => " + (group-n 3 (1+ (not (any "}")))) + "}" + (group-n 4 (* anychar))) line) ;; For renamed files, create separate entries for the - ;; before-rename and after-rename files - (let ((before (match-string 1 line)) - (after (match-string 2 line)) - (subdir-file (match-string 3 line))) - (when subdir-file ; When a directory was renamed - (setq before (file-name-concat before subdir-file) - after (file-name-concat after subdir-file))) + ;; before-rename and after-rename files. The rename + ;; block {before => after} may appear mid-path, so we + ;; reconstruct full paths using the surrounding + ;; context. + (let* ((prefix (substring (match-string 1 line) 3)) + (before-part (match-string 2 line)) + (after-part (match-string 3 line)) + (suffix (match-string 4 line)) + (before (concat prefix before-part suffix)) + (after (concat prefix after-part suffix))) (puthash before "F-" table) ; Removed state - (puthash after "-F" table) ; Added state + (puthash after "-F" table) ; Added state (when extra-table ;; Populate EXTRA-TABLE with rename information (puthash before (list :rename-state 'removed :rename-other-filename after) |
