{"id":16717409,"url":"https://github.com/panglesd/ocaml-diffutils","last_synced_at":"2025-04-10T06:43:14.433Z","repository":{"id":113654244,"uuid":"542787834","full_name":"panglesd/ocaml-diffutils","owner":"panglesd","description":"An ocaml library for manipulating diffs.","archived":false,"fork":false,"pushed_at":"2024-02-12T16:54:05.000Z","size":78,"stargazers_count":19,"open_issues_count":0,"forks_count":0,"subscribers_count":4,"default_branch":"main","last_synced_at":"2025-03-24T07:49:50.902Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"OCaml","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/panglesd.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-09-28T20:49:56.000Z","updated_at":"2025-01-10T13:53:57.000Z","dependencies_parsed_at":null,"dependency_job_id":"67919575-8a22-4a84-9f21-ff0a2b6251ca","html_url":"https://github.com/panglesd/ocaml-diffutils","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/panglesd%2Focaml-diffutils","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/panglesd%2Focaml-diffutils/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/panglesd%2Focaml-diffutils/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/panglesd%2Focaml-diffutils/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/panglesd","download_url":"https://codeload.github.com/panglesd/ocaml-diffutils/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248173434,"owners_count":21059595,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-12T21:31:52.568Z","updated_at":"2025-04-10T06:43:14.409Z","avatar_url":"https://github.com/panglesd.png","language":"OCaml","readme":"# ocaml-diffutils\n\nAn OCaml library to manipulate diffs, patches, diff3 and merges!\n\n```ocaml\n# open Diffutils.DiffString ;;\n(** A \"Longest-common-subsequence\" diff on sequence of lines *)\n# let orig = [ \"a\" ; \"b\" ; \"c\" ; \"d\"] and new_ = [ \"b\" ; \"x\" ; \"c\" ; \"z\"] ;;\n# let diff = Diff.diff ~orig ~new_ ;;\nval diff : Diff.t =\n  [Diff.Diff {Diff.orig = [\"a\"]; new_ = []};\n   Diff.Same \"b\";\n   Diff.Diff {Diff.orig = []; new_ = [\"x\"]};\n   Diff.Same \"c\";\n   Diff.Diff {Diff.orig = [\"d\"]; new_ = [\"z\"]}]\n# Fmt.pr \"%a\" (Diff.pp Diff.git_printer) diff ;;\n-a\n b\n+x\n c\n-d\n+z\n- : unit = ()\n# let base = [\"a\" ; \"b\" ; \"c\"] and me = [\"a\" ; \"y\" ; \"b\" ; \"c\"] and you = [\"a\" ; \"b\" ; \"z\" ; \"c\" ] ;;\n# let diff = Diff.diff3 ~base ~me ~you ;;\n# Fmt.pr \"%a\" (Diff.pp_unresolved_merge Diff.git_merge_printer) diff;;\na\n\u003e\u003e\u003e\ne\n|||\nb\n===\nz\n\u003c\u003c\u003c\nc\n# let unresolved = Merge.merge ~resolver:Merge.no_resolver ~base ~you ~me ();;\nval unresolved : Merge.t =\n  [Merge.Resolved \"a\";\n   Merge.Unresolved\n    {Conflict.base = [];\n               you = [];\n                me = [Patch.Add \"y\"]};\n   Merge.Resolved \"b\";\n   Merge.Unresolved\n    {Conflict.base = [];\n               you = [Patch.Add \"z\"];\n                me = []};\n   Merge.Resolved \"c\"]\n# let resolved = Merge.apply_resolver Merge.git_resolver unresolved ;;\nval resolved : Merge.t =\n  [Merge.Resolved \"a\";\n   Merge.Resolved \"y\";\n   Merge.Resolved \"b\";\n   Merge.Resolved \"z\";\n   Merge.Resolved \"c\"]\n```\n\nThis is a work in progress. It is usable but the API might change.\n\nFirst, a bit of terminology:\n\n- Usually, by a `diff` or `patch` we refer to a sequence of edits to go from one\n  sequence (for instance of lines) to another sequence. There are multiple way\n  to define what is an edit, usually corresponding to an [edit\n  distance](https://en.wikipedia.org/wiki/Edit_distance):\n  - `LCS` (for longest common subsequence) where the allowed operations are\n    addition and deletion\n  - the Levenhstein distance for addition, deletion and substitution\n  - [block diffs](http://www.daemonology.net/bsdiff/), where copying a whole\n    block from the input correspond to one operation. I don’t think the optimal\n    distance/diff can be found efficiently.\n- There are mainly two usages of those diff/patch:\n  - Visualize more easily the changes that occurred from one file to another.\n    Very useful! I will refer to diff/patch objects meant to be used like this\n    as \"diff\". Note that I only know use of LCS diffs.\n  - Retrieve the modified file from the original one and the diff/patch. Very\n    useful! I will refer to diff/patch objects meant to be used like this as\n    \"patches\". Block diffs seems the most suitable for this. It is mostly used\n    to save bandwidth when updating files remotely, see for instance\n    [courgette](https://www.chromium.org/developers/design-documents/software-updates-courgette/).\n\n## What is this library about?\n\nThis library is about LCS diff and patch, as well as patch3, diff3 and merge\nthat can be defined from these LCS diff/patch. The goal of this library is not\nto efficiently implement an efficient diff algorithm, but to provide tools to\nparse, print and manipulate diffs and patches. It does include an LCS diff\nalgorithm though: the Myers algorithm (not a variant) with time complexity\n`O(nd)` and space complexity `O(n²)`, see\n[here](http://www.xmailserver.org/diff2.pdf) and\n[there](https://blog.jcoglan.com/2017/02/12/the-myers-diff-algorithm-part-1/).\n\nSome things you can do with the library:\n\n- Get a patch of two input sequences `a` and `b`. The patch contains the minimal\n  information to recover `b` from `a`.\n- Apply a patch to an input sequence.\n- Get a diff of two input sequences `a` and `b`. The diff is self-contained and\n  ready to be printed in various format.\n- Print diffs and patches in various format (such as an html visualization!)\n- (TODO) Parse patches/diff written in standard format.\n- Merge two lists given a common ancestor, with conflicts\n- Resolve, maybe partially, some of these conflicts.\n\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpanglesd%2Focaml-diffutils","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpanglesd%2Focaml-diffutils","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpanglesd%2Focaml-diffutils/lists"}