The sound distributed version control system

#663 enhancement: patterns and matches like Darcs

Opened by joyously on April 4, 2022
joyously on April 4, 2022

I was reading about Darcs, and every command takes patterns and matches. These sound really useful. Would it be possible to have something similar?

The page describes these as

Patterns

Selecting Patches:

The –patches option yields patches with names matching an extended regular expression. See regex(7) for details. The –matches option yields patches that match a logical (Boolean) expression: one or more primitive expressions combined by grouping (parentheses) and the complement (not), conjunction (and) and disjunction (or) operators. The C notation for logic operators (!, && and ||) can also be used.

  • –patches=regex is a synonym for –matches=‘name regex’
  • –hash=HASH is a synonym for –matches=‘hash HASH’
  • –from-patch and –to-patch are synonyms for –from-match=’name… and –to-match=’name…
  • –from-patch and –to-match can be unproblematically combined: darcs log --from-patch='html.*documentation' --to-match='date 20040212'

The following primitive Boolean expressions are supported:

  • exact - check a literal string against the patch name.
  • name - check a regular expression against the patch name.
  • author - check a regular expression against the author name.
  • hunk - check a regular expression against the contents of a hunk patch.
  • comment - check a regular expression against the log message.
  • hash - match a full hash or a prefix for a patch.
  • date - match the patch date.
  • touch - match file paths for a patch. Here are some examples:
darcs log --match 'exact "Resolve issue17: use dynamic memory allocation."'
darcs log --match 'name issue17'
darcs log --match 'name "^[Rr]esolve issue17\>"'
darcs log --match 'author "David Roundy"'
darcs log --match 'author droundy'
darcs log --match 'author droundy@darcs.net'
darcs log --match 'hunk "foo = 2"'
darcs log --match 'hunk "^instance .* Foo where$"'
darcs log --match 'comment "prevent deadlocks"'
darcs log --match 'hash c719567e92c3b0ab9eddd5290b705712b8b918ef'
darcs log --match 'hash c7195'
darcs log --match 'date "2006-04-02 22:41"'
darcs log --match 'date "tea time yesterday"'
darcs log --match 'touch src/foo.c'
darcs log --match 'touch src/'
darcs log --match 'touch "src/*.(c|h)"'
joyously on February 21, 2024

I don’t understand Haskell, but this doesn’t look very complicated: https://hub.darcs.net/darcs/darcs-2.16/browse/src/Darcs/Patch/Match.hs#20

-- | /First matcher, Second matcher and Nonrange matcher/
--
-- When we match for patches, we have a PatchSet, of which we want a
-- subset. This subset is formed by the patches in a given interval
-- which match a given criterion. If we represent time going left to
-- right, then we have (up to) three 'Matcher's:
--
-- * the 'firstMatcher' is the left bound of the interval,
--
-- * the 'secondMatcher' is the right bound, and
--
-- * the 'nonrangeMatcher' is the criterion we use to select among
--   patches in the interval.
---
-- Each of these matchers can be present or not according to the
-- options. The patches we want would then be the ones that all
-- present matchers have in common.
--
-- Alternatively, match flags can also be understood as a 'patchSetMatch'.
-- This (ab-)uses match flags that normally denote a 'nonrangeMatcher',
-- (additionally including the 'OneIndex' flag --index=n), to denote
-- selection of a full 'PatchSet' up to the latest matching patch. This
-- works similar to 'secondMatcher' except for tag matches, which in this
-- case mean to select only the tag and all its dependencies. In other
-- words, the tag will be clean in the resulting 'PatchSet'.

It is interesting that these patterns can be used on most Darcs commands, and they all resolve to logical sets of patches, without using any state ID. This is especially needed for Pijul. I think it’s possible in Darcs because of the patch order (and the command to reorder it).