branch: externals/vc-jj
commit ba94d8b13df37d7ca4d34151247a7d802d2e0109
Author: Rudi Schlatte <[email protected]>
Commit: Rudi Schlatte <[email protected]>
Return full change id from vc-jj-(next|previous)-revision
- Use 'first_parent' or 'ancestors' in vc-jj-previous-revision
- Use 'children' or 'descendants' in vc-jj-next-revision
- Add some tests
See #112
---
vc-jj-tests.el | 49 +++++++++++++++++++++++++++++++++++++++++++++++++
vc-jj.el | 38 +++++++++++++++++++++-----------------
2 files changed, 70 insertions(+), 17 deletions(-)
diff --git a/vc-jj-tests.el b/vc-jj-tests.el
index 4944daf393..d728b775ca 100644
--- a/vc-jj-tests.el
+++ b/vc-jj-tests.el
@@ -278,5 +278,54 @@ See https://codeberg.org/emacs-jj-vc/vc-jj.el/issues/63."
(should (eq (vc-jj-dir-status-files repo nil (lambda (x y) x))
nil)))))
+(ert-deftest vc-jj-previous-revision-in-merge ()
+ "Test vc-previous-revision for a change with multiple parents.
+We expect this function to return the first parent specified."
+ (vc-jj-test-with-repo repo
+ (let ((root "zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz")
+ branch-1 branch-2 branch-merged
+ branch-parent branch-parent-with-file)
+ ;; - construct a diamond graph
+ ;; - add a file to the second parent of the merge commit
+ ;; - check that we find the first parent
+ ;; - check that we find the second parent when looking for a
+ ;; parent with the new file
+ (shell-command (concat "jj new " root))
+ (write-region "Hello!" nil "README")
+ (setq branch-1 (vc-jj-working-revision "README"))
+ (shell-command (concat "jj new " root))
+ (write-region "Hello!" nil "README")
+ (write-region "Hello!" nil "README-onlyhere")
+ (setq branch-2 (vc-jj-working-revision "README"))
+ (shell-command (concat "jj new " branch-1 " " branch-2))
+ (setq branch-merged (vc-jj-working-revision "README"))
+ (setq branch-parent (vc-jj-previous-revision nil branch-merged))
+ (setq branch-parent-with-file (vc-jj-previous-revision "README-onlyhere"
branch-merged))
+ (should (string= branch-parent branch-1))
+ (should (string= branch-parent-with-file branch-2)))))
+
+(ert-deftest vc-jj-next-revision-in-merge ()
+ "Test vc-next-revision for a change with multiple children.
+We check that we get the revision where a given file was added."
+ (vc-jj-test-with-repo repo
+ (let ( branch-root branch-1 branch-2 branch-child branch-child-1
branch-child-2)
+ (write-region "Hello!" nil "README")
+ (setq branch-root (vc-jj-working-revision "README"))
+ (shell-command (concat "jj new " branch-root))
+ (write-region "Hello!" nil "README-onlyhere")
+ (setq branch-1 (vc-jj-working-revision "README-onlyhere"))
+ (shell-command (concat "jj new " branch-root))
+ (write-region "Persisting branch 2" nil "README-branch2")
+ (setq branch-2 (vc-jj-working-revision "README-branch2"))
+ (setq branch-child (vc-jj-next-revision nil branch-root))
+ ;; Slight pun: these files only exist in the child branches
+ (setq branch-child-1 (vc-jj-next-revision "README-onlyhere" branch-root))
+ (setq branch-child-2 (vc-jj-next-revision "README-branch2" branch-root))
+ ;; We don't want to rely on the exact order in which the
+ ;; children are printed
+ (should (or (string= branch-child branch-1) (string= branch-child
branch-2)))
+ (should (string= branch-child-1 branch-1))
+ (should (string= branch-child-2 branch-2)))))
+
(provide 'vc-jj-tests)
;;; vc-jj-tests.el ends here
diff --git a/vc-jj.el b/vc-jj.el
index d14b4c7164..05bd1f4a24 100644
--- a/vc-jj.el
+++ b/vc-jj.el
@@ -605,29 +605,33 @@ If REV is not specified, revert the file as with
`vc-jj-revert'."
(defun vc-jj-previous-revision (file rev)
"JJ-specific version of `vc-previous-revision'."
- ;; TODO: here and in `vc-jj-next-revision', check how (concat
- ;; revision "-") works with merge commits; do we get multiple change
- ;; ids in a multi-line string, and does this break users of these
- ;; functions?
(if file
- (vc-jj--command-parseable "log" "--no-graph" "-n" "1"
- "-r" (concat ".." rev "-")
- "-T" "change_id.shortest()"
+ (vc-jj--command-parseable "log" "--no-graph" "--limit" "1"
+ "-r" (concat "ancestors(" rev ")")
+ "-T" "change_id"
"--" (vc-jj--filename-to-fileset file))
- (vc-jj--command-parseable "log" "--no-graph" "-n" "1"
- "-r" (concat rev "-")
- "-T" "change_id.shortest()"
- )))
+ ;; The jj manual states that "for merges, [first_parent] only
+ ;; returns the first parent instead of returning all parents";
+ ;; given the choice, we do want to return the first parent of a
+ ;; merge change.
+ (vc-jj--command-parseable "log" "--no-graph"
+ "-r" (concat "first_parent(" rev ")")
+ "-T" "change_id")))
(defun vc-jj-next-revision (file rev)
"JJ-specific version of `vc-next-revision'."
(if file
- (vc-jj--command-parseable "log" "--no-graph" "-n" "1"
- "-r" (format "roots(files(\"%s\") ~ ::%s)"
file rev)
- "-T" "change_id.shortest()")
- (vc-jj--command-parseable "log" "--no-graph" "-n" "1"
- "-r" (concat rev "+")
- "-T" "change_id.shortest()")))
+ (vc-jj--command-parseable "log" "--no-graph" "--limit" "1"
+ "-r" (concat "descendants(" rev ")")
+ "-T" "change_id"
+ "--" (vc-jj--filename-to-fileset file))
+ ;; Note: experimentally, jj (as of 0.35.0) prints children in LIFO
+ ;; order (newest child first), but we should not rely on that
+ ;; behavior and since none of the children of a change are
+ ;; special, we return an arbitrary one.
+ (car (vc-jj--process-lines "log" "--no-graph"
+ "-r" (concat "children(" rev ")")
+ "-T" "change_id ++ \"\n\""))))
(defun vc-jj-get-change-comment (_files rev)
(vc-jj--command-parseable "log" "--no-graph" "-n" "1"