Spellcheck and simple language editing: `why_pijul.md`

yin
Apr 15, 2023, 1:34 AM
LD2OZ7CID2SF7HSK5FT5OKSPWICRCR6JYBKNEUNWOU6USPNO7EBQC

Dependencies

  • [2] LISTQZXT Change one of the “changes” to “patches”
  • [3] VG2C5MWE https -> http for Darcs.net
  • [4] SCSV2FNS Reboot
  • [5] OE4TXB5W commute -> applied in any order
  • [6] 4NAVGRWW Which A (in Git merge)

Change contents

  • edit in src/why_pijul.md at line 4
    [3.221]
    [4.2537]
    Pijul has a number of features that allow it to scale to very large repositories and fast-paced workflows. In particular, **change commutation** means that changes written independently can be applied in any order, without changing the result. This property simplifies workflows, allowing Pijul to:
  • replacement in src/why_pijul.md at line 7
    [4.2538][4.2538:2948]()
    Pijul has a number of features that allow it to scale to very large repositories and fast-paced workflows. In particular, **change commutation** means that changes written independently can be applied in any order, without changing the result. This property simplifies workflows, allowing Pijul to **clone sub-parts of repositories**, to **solve conflicts reliably**, to **easily combine different versions**.
    [4.2538]
    [4.2948]
    - **clone sub-parts of repositories**
    - **solve conflicts reliably**
    - **easily combine different versions**.
  • replacement in src/why_pijul.md at line 15
    [4.3130][4.3130:3425]()
    - **[Use case: early stage of a project]** Change commutation makes Pijul a
    highly forgiving system, as you can "unapply" (or "unrecord")
    changes made in the past, without having to change the identity of
    new changes. A reader familiar with Git will understand "rebasing", in git terms).
    [4.3130]
    [4.3425]
    - **[Use case: In the early stage of a project]** Change commutation
    makes Pijul a highly forgiving system, as you can "unapply"
    (or "unrecord") changes made in the past, without having to change
    the identity of new changes. A reader familiar with Git will
    understand "rebasing".
  • replacement in src/why_pijul.md at line 21
    [4.3426][4.3426:3496]()
    This tends to happen pretty often in the early stages of a project,
    [4.3426]
    [4.3496]
    This tends to happen pretty often in the early stages of a project
  • replacement in src/why_pijul.md at line 25
    [4.3630][4.3630:3705]()
    - **[Use case: the project becomes stable]** As your project grows, change
    [4.3630]
    [4.3705]
    - **[Use case: In a mature project]** As your project grows, change
  • replacement in src/why_pijul.md at line 27
    [4.3773][4.3773:3916]()
    branches, a stable one containing only the original product, and
    bugfixes, and an unstable one, where new features are constantly
    added.
    [4.3773]
    [4.3916]
    branches, a stable one accepting only bugfixes, and an unstable
    one, where changes happen constantly.
  • replacement in src/why_pijul.md at line 34
    [4.4103][4.4103:4242]()
    changes they are interested in. Those changes *do not* change when
    imported, which means that pulling new changes in will work just as
    [4.4103]
    [4.4242]
    changes they are interested in. Pulled changes *do not* change when
    imported, which means that pulling new changes it will work just as
  • replacement in src/why_pijul.md at line 41
    [4.4275][4.4275:4471]()
    In Pijul, change application is an *associative* operation, meaning
    that applying some change A, and then a set of changes (BC) at once,
    yields the same result as applying (AB) first, and then C.
    [4.4275]
    [4.4471]
    In Pijul, change application is an associative operation, meaning
    that applying some change A and then a set of changes (BC) at once
    yields the same result as applying (AB) first and then C.
  • replacement in src/why_pijul.md at line 52
    [4.4684][4.4684:4867]()
    The second scenario would look like the following, with Bob creating
    commit A, and then pulling B. At that moment, Bob has both A and B on
    his branch, and wants to pull C from Alice.
    [4.4684]
    [4.4867]
    The second scenario would look like the following: Bob creating
    commit A and then pulling B. At that moment, Bob has both A and B on
    his branch and wants to pull C from Alice.
  • replacement in src/why_pijul.md at line 61
    [4.4943][4.4943:5013]()
    Note that this is different from change reordering: here, we apply A,
    [4.4943]
    [4.5013]
    Note that this differs from change reordering: here, we apply A,
  • replacement in src/why_pijul.md at line 65
    [4.5138][4.5138:5273]()
    sound like nitpicking, because intuition suggests that it should
    always be the case. However, **Git doesn't guarantee that property**,
    [4.5138]
    [4.5273]
    sound like nitpicking because intuition suggests it should always be
    true. However, **Git doesn't guarantee associative change property**,
  • replacement in src/why_pijul.md at line 68
    [4.5310][4.5310:5721]()
    Concretely, this means that Git (and relatives) can **sometimes shuffle lines around**, because these systems *only* track versions, rather than the changes that happen between the versions. And even though one can reconstruct one from the other, the following example (taken from [here](https://tahoe-lafs.org/~zooko/badmerge/simple.html)) shows that tracking versions only does not yield the expected result.
    [4.5310]
    [4.5721]
    Specifically, Git (and relatives) can **sometimes shuffle lines around**,
    because these systems *only* track versions rather than the changes that
    happen between the versions. And even though one can reconstruct one from
    the other, the following example
    (taken from [here](https://tahoe-lafs.org/~zooko/badmerge/simple.html))
    shows that tracking versions only does not yield the expected result.
  • replacement in src/why_pijul.md at line 88
    [4.6023][4.6023:6277]()
    In this diagram, Alice and Bob start from a common file with the lines A and B. Alice adds G above everything, and then another instance of A and B above that (her new lines are shown in green). Meanwhile, Bob adds a line X between the original A and B.
    [4.6023]
    [4.6277]
    In this diagram, Alice and Bob start from an identical file with lines A and B.
    Alice adds G above everything and then another instance of A and B above that
    (her new lines show green). Meanwhile, Bob adds a line X between the original A
    and B.
  • replacement in src/why_pijul.md at line 93
    [4.6278][4.6278:6697]()
    This example will be merged by Git, SVN, Mercurial… into the file shown on the left, with the relative positions of G and X swapped, where as Pijul (and Darcs) yield the file on the right, preserving the order between the lines. Note that this example **has nothing to do with a conflict**, since the edits happen in different parts of the file. And in fact neither Git nor Pijul will report a conflict in this case.
    [4.6278]
    [4.6697]
    Git, SVN, and Mercurial will merge this example… into the file shown on the
    left, with the relative positions of G and X swapped, whereas Pijul
    (and Darcs) yield the file on the right, preserving the order between the
    lines. Note that this example **has nothing to do with a conflict** since the
    edits happen in different file parts. Furthermore, neither Git nor Pijul will
    report a conflict in this case.
  • replacement in src/why_pijul.md at line 100
    [4.6698][4.6698:7204]()
    The reason for the counter-intuitive behaviour in Git is that Git runs a heuristic algorithm called *three-way merge* or *diff3*, which extends *diff* to two "new" versions instead of one. Note, however, that *diff* has multiple optimal solutions, and the same change can be described equivalently by different diffs. While this is fine for *diff* (since the patch resulting from *diff* has a unique interpretation), it is ambiguous in the case of *diff3* and might lead to arbitrary reshuffling of files.
    [4.6698]
    [4.7204]
    The reason for the counter-intuitive behavior in Git is that Git runs
    a heuristic algorithm called three-way merge or diff3. Diff3 extends diff to
    two "new" versions instead of one. Note, however, that diff has multiple
    optimal solutions, and a single change can be described equivalently by
    different diffs. While this is fine for diff (since the patch resulting from
    diff has aunique interpretation), it is ambiguous in the case of diff3 and
    might lead to an arbitrary reshuffling of files.
  • replacement in src/why_pijul.md at line 109
    [4.7206][4.7206:7470]()
    Obviously, this **does not mean that the merge will have the intended semantics**: code should be still reviewed and tests should still be run. But at least a **review of the change will not be made useless** by a reshuffling of lines by the version control tool.
    [4.7206]
    [4.7470]
    It is prudent to note that change associativity
    **does guarantee the result will have intended semantics**, because languages
    have context-specific rules. Every change should be tested and go through code
    review. However, **the code review won't be made pointless** by reshuffling
    lines by the version control tool.
  • replacement in src/why_pijul.md at line 115
    [4.7471][4.7471:7494]()
    ## Modelling conflicts
    [4.7471]
    [4.7494]
    ## Modeling conflicts
  • replacement in src/why_pijul.md at line 117
    [4.7495][4.7495:7679]()
    Conflicts are a normal thing in the internal representation of a Pijul
    repository. Actually, after applying new changes, we even have to do extra work to find where the conflicts are.
    [4.7495]
    [4.7679]
    Conflicts are a regular thing in the internal representation of a Pijul
    repository. After applying new changes, we have to do extra work to find where
    the conflicts are.
  • replacement in src/why_pijul.md at line 121
    [4.7680][4.7680:7830]()
    In particular, changes editing sides of a conflict can be applied
    without resolving the conflict. This guarantees that no information
    ever gets lost.
    [4.7680]
    [4.7830]
    In particular, edits from both sides of a conflict get applied without
    resolving the conflict. This guarantees no information ever gets lost.
  • replacement in src/why_pijul.md at line 126
    [4.7875][4.7875:8070]()
    - In Git, conflicts are not really handled after they are output to
    files. For instance, if one commits just after a conflict occurs,
    git will commit the entire conflict (including markers).
    [4.7875]
    [4.8070]
    - Git writes conflicts into the working directory and refuses to
    commit any changes to the repository until conflicts get manually
    resolved.
  • replacement in src/why_pijul.md at line 130
    [4.8071][4.8071:8128]()
    - In Darcs, conflicts can lead to the [exponential merge
    [4.8071]
    [4.8128]
    - In Darcs, conflicts can trigger the [exponential merge
  • replacement in src/why_pijul.md at line 141
    [4.8461][2.0:67](),[2.67][4.8528:8558](),[4.8528][4.8528:8558]()
    that Pijul deals with changes (or patches), whereas Git deals only
    with snapshots (or versions).
    [4.8461]
    [4.8558]
    that Pijul stores changes (or patches), whereas Git deals only with
    snapshots (or versions).
  • replacement in src/why_pijul.md at line 146
    [4.8689][4.8689:8961]()
    according to formal axioms that guarantee correctness in 100% of
    cases, whereas commits have to be /stitched together based on their
    contents, rather than on the edits that took place/. This is why in
    these systems, conflicts are often painful, as there is no real way to
    [4.8689]
    [4.8961]
    according to formal axioms that guarantee correctness in 100% of cases.
    In contrast, commits have to be /stitched together based on their
    contents rather than on the edits that took place/. This is why
    conflicts are often painful in these systems, as there is no natural way to
  • replacement in src/why_pijul.md at line 156
    [4.9107][4.9107:9236]()
    Pijul is mostly a formally correct version of Darcs' theory of
    changes, as well as a new algorithm for merging changes. Its main
    [4.9107]
    [4.9236]
    Pijul is a mostly formally-correct version of Darcs' theory of
    changes and a new algorithm for merging changes. Its main
  • replacement in src/why_pijul.md at line 164
    [4.9536][4.9536:9578]()
    afterwards, by looking at the pristine.
    [4.9536]
    [4.9578]
    afterward by looking at the pristine.
  • replacement in src/why_pijul.md at line 166
    [4.9579][4.9579:9654]()
    - Conflicting changes always commute in Pijul, and never commute in Darcs.
    [4.9579]
    [4.9654]
    - Conflicting changes always commute in Pijul and never commute in
    Darcs.
  • replacement in src/why_pijul.md at line 169
    [4.9655][4.9655:9850]()
    - Fast algorithms: Pijul's pristine can be seen as a "cache" of
    applied changes, to which new changes can be applied directly,
    without having to compute anything on the repository's history.
    [4.9655]
    [4.9850]
    - Fast algorithms: Pijul's pristine can be seen as a "cache" of applied
    changes to which new changes can be applied directly without having
    to compute anything on the repository's history.
  • replacement in src/why_pijul.md at line 174
    [4.9852][4.9852:10046]()
    However, Pijul's pristine format was designed to comply with axioms on
    a specific set of operations only. As a result, some of darcs'
    features, such as `darcs replace`, are not (yet) available.
    [4.9852]
    However, Pijul's pristine format is designed to only comply with axioms on
    a specific set of operations. As a result, some of the Darcs'
    features, such as `darcs replace`, have yet to be made available.