aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLudovic Courtès <ludo@gnu.org>2019-12-27 13:15:00 +0100
committerLudovic Courtès <ludo@gnu.org>2019-12-27 13:52:49 +0100
commit785af04a7574867dc940c791daa938a2432d0450 (patch)
tree79e76abd4a1d168a0a8fb0b331061d99ced6d1d7
parent1e43ab2c032834e43a43eb4c27d6a50bf66b86ba (diff)
downloadguix-785af04a7574867dc940c791daa938a2432d0450.tar.gz
guix-785af04a7574867dc940c791daa938a2432d0450.zip
git: 'commit-difference' takes a list of excluded commits.
* guix/git.scm (commit-closure): Add 'visited' optional parameter. (commit-difference): Add 'excluded' optional parameter; pass second argument to 'commit-closure'. * tests/git.scm ("commit-difference, excluded commits"): New test.
-rw-r--r--guix/git.scm14
-rw-r--r--tests/git.scm26
2 files changed, 34 insertions, 6 deletions
diff --git a/guix/git.scm b/guix/git.scm
index d7dddde3a7..83af596ef5 100644
--- a/guix/git.scm
+++ b/guix/git.scm
@@ -347,10 +347,11 @@ Log progress and checkout info to LOG-PORT."
;;; Commit difference.
;;;
-(define (commit-closure commit)
- "Return the closure of COMMIT as a set."
+(define* (commit-closure commit #:optional (visited (setq)))
+ "Return the closure of COMMIT as a set. Skip commits contained in VISITED,
+a set, and adjoin VISITED to the result."
(let loop ((commits (list commit))
- (visited (setq)))
+ (visited visited))
(match commits
(()
visited)
@@ -360,15 +361,16 @@ Log progress and checkout info to LOG-PORT."
(loop (append (commit-parents head) tail)
(set-insert head visited)))))))
-(define (commit-difference new old)
+(define* (commit-difference new old #:optional (excluded '()))
"Return the list of commits between NEW and OLD, where OLD is assumed to be
-an ancestor of NEW.
+an ancestor of NEW. Exclude all the commits listed in EXCLUDED along with
+their ancestors.
Essentially, this computes the set difference between the closure of NEW and
that of OLD."
(let loop ((commits (list new))
(result '())
- (visited (commit-closure old)))
+ (visited (commit-closure old (list->setq excluded))))
(match commits
(()
(reverse result))
diff --git a/tests/git.scm b/tests/git.scm
index 8ba10ece51..052f8a79c4 100644
--- a/tests/git.scm
+++ b/tests/git.scm
@@ -96,4 +96,30 @@
(lset= eq? (commit-difference master4 master2)
(list master4 merge master3 devel1 devel2)))))))
+(unless (which (git-command)) (test-skip 1))
+(test-assert "commit-difference, excluded commits"
+ (with-temporary-git-repository directory
+ '((add "a.txt" "A")
+ (commit "first commit")
+ (add "b.txt" "B")
+ (commit "second commit")
+ (add "c.txt" "C")
+ (commit "third commit")
+ (add "d.txt" "D")
+ (commit "fourth commit")
+ (add "e.txt" "E")
+ (commit "fifth commit"))
+ (with-repository directory repository
+ (let ((commit1 (find-commit repository "first"))
+ (commit2 (find-commit repository "second"))
+ (commit3 (find-commit repository "third"))
+ (commit4 (find-commit repository "fourth"))
+ (commit5 (find-commit repository "fifth")))
+ (and (lset= eq? (commit-difference commit4 commit1 (list commit2))
+ (list commit3 commit4))
+ (lset= eq? (commit-difference commit4 commit1 (list commit3))
+ (list commit4))
+ (lset= eq? (commit-difference commit4 commit1 (list commit5))
+ (list commit2 commit3 commit4)))))))
+
(test-end "git")