1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162
//! Tools for finding and manipulating differences between files //! //! ## Overview //! //! This library is intended to be a collection of tools used to find and //! manipulate differences between files inspired by [LibXDiff] and [GNU //! Diffutils]. Version control systems like [Git] and [Mercurial] generally //! communicate differences between two versions of a file using a `diff` or //! `patch`. //! //! The current diff implementation is based on the [Myers' diff algorithm]. //! //! ## Creating a Patch //! //! A [`Patch`] between two texts can be created by doing the following: //! //! ``` //! use diffy::create_patch; //! //! let original = "The Way of Kings\nWords of Radiance\n"; //! let modified = "The Way of Kings\nWords of Radiance\nOathbringer\n"; //! //! let patch = create_patch(original, modified); //! # //! # let expected = "\ //! # --- original //! # +++ modified //! # @@ -1,2 +1,3 @@ //! # The Way of Kings //! # Words of Radiance //! # +Oathbringer //! # "; //! # //! # assert_eq!(patch.to_string(), expected); //! ``` //! //! A [`Patch`] can the be output in the [Unified Format] either by using its //! [`Display`] impl or by using a [`PatchFormatter`] to output the diff with //! color. //! //! ``` //! # use diffy::create_patch; //! # //! # let original = "The Way of Kings\nWords of Radiance\n"; //! # let modified = "The Way of Kings\nWords of Radiance\nOathbringer\n"; //! # //! # let patch = create_patch(original, modified); //! # //! # let expected = "\ //! # --- original //! # +++ modified //! # @@ -1,2 +1,3 @@ //! # The Way of Kings //! # Words of Radiance //! # +Oathbringer //! # "; //! # //! # assert_eq!(patch.to_string(), expected); //! # //! // Without color //! print!("{}", patch); //! //! // With color //! # use diffy::PatchFormatter; //! let f = PatchFormatter::new().with_color(); //! print!("{}", f.fmt_patch(&patch)); //! ``` //! //! ```console //! --- original //! +++ modified //! @@ -1,2 +1,3 @@ //! The Way of Kings //! Words of Radiance //! +Oathbringer //! ``` //! //! ## Performing a Three-way Merge //! //! Two files `A` and `B` can be merged together given a common ancestor or //! original file `O` to produce a file `C` similarly to how [diff3] //! performs a three-way merge. //! //! ```console //! --- A --- //! / \ //! / \ //! O C //! \ / //! \ / //! --- B --- //! ``` //! //! If files `A` and `B` modified different regions of the original file `O` //! (or the same region in the same way) then the files can be merged without //! conflict. //! //! ``` //! use diffy::merge; //! //! let original = "the final empire\nThe Well of Ascension\nThe hero of ages\n"; //! let a = "The Final Empire\nThe Well of Ascension\nThe Hero of Ages\n"; //! let b = "The Final Empire\nThe Well of Ascension\nThe hero of ages\n"; //! let expected = "\ //! The Final Empire //! The Well of Ascension //! The Hero of Ages //! "; //! //! assert_eq!(merge(original, a, b).unwrap(), expected); //! ``` //! //! If both files `A` and `B` modified the same region of the original file //! `O` (and those modifications are different), it would result in a conflict //! as it is not clear which modifications should be used in the merged //! result. //! //! ``` //! use diffy::merge; //! //! let original = "The Final Empire\nThe Well of Ascension\nThe hero of ages\n"; //! let a = "The Final Empire\nThe Well of Ascension\nThe Hero of Ages\nSecret History\n"; //! let b = "The Final Empire\nThe Well of Ascension\nThe hero of ages\nThe Alloy of Law\n"; //! let expected = "\ //! The Final Empire //! The Well of Ascension //! <<<<<<< ours //! The Hero of Ages //! Secret History //! ||||||| original //! The hero of ages //! ======= //! The hero of ages //! The Alloy of Law //! >>>>>>> theirs //! "; //! //! assert_eq!(merge(original, a, b).unwrap_err(), expected); //! ``` //! //! [LibXDiff]: http://www.xmailserver.org/xdiff-lib.html //! [Myers' diff algorithm]: http://www.xmailserver.org/diff2.pdf //! [GNU Diffutils]: https://www.gnu.org/software/diffutils/ //! [Git]: https://git-scm.com/ //! [Mercurial]: https://www.mercurial-scm.org/ //! [Unified Format]: https://en.wikipedia.org/wiki/Diff#Unified_format //! [diff3]: https://en.wikipedia.org/wiki/Diff3 //! //! [`Display`]: https://doc.rust-lang.org/stable/std/fmt/trait.Display.html //! [`Patch`]: struct.Patch.html //! [`PatchFormatter`]: struct.PatchFormatter.html mod apply; mod diff; mod merge; mod patch; mod range; mod utils; pub use diff::{create_patch, DiffOptions}; pub use merge::{merge, ConflictStyle, MergeOptions}; pub use patch::{Hunk, HunkRange, Line, Patch, PatchFormatter};