|
1 |
| -What The Patch!? |
2 |
| -================ |
3 |
| - |
4 |
| -.. image:: https://travis-ci.org/cscorley/whatthepatch.svg?style=flat |
5 |
| - :target: https://travis-ci.org/cscorley/whatthepatch |
6 |
| - |
7 |
| -What The Patch!? is a library for both parsing and applying patch files. |
8 |
| - |
9 |
| -Features |
10 |
| ---------- |
11 |
| - |
12 |
| -- Parsing of almost all ``diff`` formats (except forwarded ed): |
13 |
| - |
14 |
| - - normal (default, --normal) |
15 |
| - - copied context (-c, --context) |
16 |
| - - unified context (-u, --unified) |
17 |
| - - ed script (-e, --ed) |
18 |
| - - rcs ed script (-n, --rcs) |
19 |
| - |
20 |
| -- Parsing of several SCM patches: |
21 |
| - |
22 |
| - - CVS |
23 |
| - - SVN |
24 |
| - - Git |
25 |
| - |
26 |
| -Installation |
27 |
| ------------- |
28 |
| - |
29 |
| -To install What The Patch!?, simply: |
30 |
| - |
31 |
| -.. code-block:: bash |
32 |
| -
|
33 |
| - $ pip install whatthepatch |
34 |
| -
|
35 |
| -Usage |
36 |
| -===== |
37 |
| - |
38 |
| -Let us say we have a patch file containing some changes, aptly named |
39 |
| -'somechanges.patch': |
40 |
| - |
41 |
| -.. code-block:: diff |
42 |
| -
|
43 |
| - --- lao 2012-12-26 23:16:54.000000000 -0600 |
44 |
| - +++ tzu 2012-12-26 23:16:50.000000000 -0600 |
45 |
| - @@ -1,7 +1,6 @@ |
46 |
| - -The Way that can be told of is not the eternal Way; |
47 |
| - -The name that can be named is not the eternal name. |
48 |
| - The Nameless is the origin of Heaven and Earth; |
49 |
| - -The Named is the mother of all things. |
50 |
| - +The named is the mother of all things. |
51 |
| - + |
52 |
| - Therefore let there always be non-being, |
53 |
| - so we may see their subtlety, |
54 |
| - And let there always be being, |
55 |
| - @@ -9,3 +8,6 @@ |
56 |
| - The two are the same, |
57 |
| - But after they are produced, |
58 |
| - they have different names. |
59 |
| - +They both may be called deep and profound. |
60 |
| - +Deeper and more profound, |
61 |
| - +The door of all subtleties! |
62 |
| -
|
63 |
| -
|
64 |
| -Parsing |
65 |
| -------- |
66 |
| - |
67 |
| -Here is how we would use What The Patch!? in Python to get the changeset for |
68 |
| -each diff in the patch: |
69 |
| - |
70 |
| -.. code-block:: python |
71 |
| -
|
72 |
| - >>> import whatthepatch |
73 |
| - >>> import pprint |
74 |
| - >>> with open('tests/casefiles/diff-unified.diff') as f: |
75 |
| - ... text = f.read() |
76 |
| - ... |
77 |
| - >>> for diff in whatthepatch.parse_patch(text): |
78 |
| - ... print(diff) # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE |
79 |
| - ... |
80 |
| - diff(header=header(index_path=None, |
81 |
| - old_path='lao', |
82 |
| - old_version='2013-01-05 16:56:19.000000000 -0600', |
83 |
| - new_path='tzu', |
84 |
| - new_version='2013-01-05 16:56:35.000000000 -0600'), |
85 |
| - changes=[Change(old=1, new=None, line='The Way that can be told of is not the eternal Way;', hunk=1), |
86 |
| - Change(old=2, new=None, line='The name that can be named is not the eternal name.', hunk=1), |
87 |
| - Change(old=3, new=1, line='The Nameless is the origin of Heaven and Earth;', hunk=1), |
88 |
| - Change(old=4, new=None, line='The Named is the mother of all things.', hunk=1), |
89 |
| - Change(old=None, new=2, line='The named is the mother of all things.', hunk=1), |
90 |
| - Change(old=None, new=3, line='', hunk=1), |
91 |
| - Change(old=5, new=4, line='Therefore let there always be non-being,', hunk=1), |
92 |
| - Change(old=6, new=5, line=' so we may see their subtlety,', hunk=1), |
93 |
| - Change(old=7, new=6, line='And let there always be being,', hunk=1), |
94 |
| - Change(old=9, new=8, line='The two are the same,', hunk=2), |
95 |
| - Change(old=10, new=9, line='But after they are produced,', hunk=2), |
96 |
| - Change(old=11, new=10, line=' they have different names.', hunk=2), |
97 |
| - Change(old=None, new=11, line='They both may be called deep and profound.', hunk=2), |
98 |
| - Change(old=None, new=12, line='Deeper and more profound,', hunk=2), |
99 |
| - Change(old=None, new=13, line='The door of all subtleties!', hunk=2)], |
100 |
| - text='...') |
101 |
| -
|
102 |
| -The changes are listed as they are in the patch, but instead of the +/- syntax |
103 |
| -of the patch, we get a tuple of two numbers and the text of the line. |
104 |
| -What these numbers indicate are as follows: |
105 |
| - |
106 |
| -#. ``( old=1, new=None, ... )`` indicates line 1 of the file lao was **removed**. |
107 |
| -#. ``( old=None, new=2, ... )`` indicates line 2 of the file tzu was **inserted**. |
108 |
| -#. ``( old=5, new=4, ... )`` indicates that line 5 of lao and line 4 of tzu are **equal**. |
109 |
| - |
110 |
| -Please note that not all patch formats provide the actual lines modified, so some |
111 |
| -results will have the text portion of the tuple set to ``None``. |
112 |
| - |
113 |
| -Applying |
114 |
| --------- |
115 |
| - |
116 |
| -To apply a diff to some lines of text, first read the patch and parse it. |
117 |
| - |
118 |
| -.. code-block:: python |
119 |
| -
|
120 |
| - >>> import whatthepatch |
121 |
| - >>> with open('tests/casefiles/diff-default.diff') as f: |
122 |
| - ... text = f.read() |
123 |
| - ... |
124 |
| - >>> with open('tests/casefiles/lao') as f: |
125 |
| - ... lao = f.read() |
126 |
| - ... |
127 |
| - >>> diff = [x for x in whatthepatch.parse_patch(text)] |
128 |
| - >>> diff = diff[0] |
129 |
| - >>> tzu = whatthepatch.apply_diff(diff, lao) |
130 |
| - >>> tzu # doctest: +NORMALIZE_WHITESPACE |
131 |
| - ['The Nameless is the origin of Heaven and Earth;', |
132 |
| - 'The named is the mother of all things.', |
133 |
| - '', |
134 |
| - 'Therefore let there always be non-being,', |
135 |
| - ' so we may see their subtlety,', |
136 |
| - 'And let there always be being,', |
137 |
| - ' so we may see their outcome.', |
138 |
| - 'The two are the same,', |
139 |
| - 'But after they are produced,', |
140 |
| - ' they have different names.', |
141 |
| - 'They both may be called deep and profound.', |
142 |
| - 'Deeper and more profound,', |
143 |
| - 'The door of all subtleties!'] |
144 |
| -
|
145 |
| -
|
146 |
| -Contribute |
147 |
| -========== |
148 |
| - |
149 |
| -#. Fork this repository |
150 |
| -#. Create a new branch to work on |
151 |
| -#. Commit your tests and/or changes |
152 |
| -#. Push and create a pull request here! |
153 |
| - |
| 1 | +What The Patch!? |
| 2 | +================ |
| 3 | + |
| 4 | +.. image:: https://travis-ci.org/cscorley/whatthepatch.svg?style=flat |
| 5 | + :target: https://travis-ci.org/cscorley/whatthepatch |
| 6 | + |
| 7 | +What The Patch!? is a library for both parsing and applying patch files. |
| 8 | + |
| 9 | +Features |
| 10 | +--------- |
| 11 | + |
| 12 | +- Parsing of almost all ``diff`` formats (except forwarded ed): |
| 13 | + |
| 14 | + - normal (default, --normal) |
| 15 | + - copied context (-c, --context) |
| 16 | + - unified context (-u, --unified) |
| 17 | + - ed script (-e, --ed) |
| 18 | + - rcs ed script (-n, --rcs) |
| 19 | + |
| 20 | +- Parsing of several SCM patches: |
| 21 | + |
| 22 | + - CVS |
| 23 | + - SVN |
| 24 | + - Git |
| 25 | + |
| 26 | +Installation |
| 27 | +------------ |
| 28 | + |
| 29 | +To install What The Patch!?, simply: |
| 30 | + |
| 31 | +.. code-block:: bash |
| 32 | +
|
| 33 | + $ pip install whatthepatch |
| 34 | +
|
| 35 | +Usage |
| 36 | +===== |
| 37 | + |
| 38 | +Let us say we have a patch file containing some changes, aptly named |
| 39 | +'somechanges.patch': |
| 40 | + |
| 41 | +.. code-block:: diff |
| 42 | +
|
| 43 | + --- lao 2012-12-26 23:16:54.000000000 -0600 |
| 44 | + +++ tzu 2012-12-26 23:16:50.000000000 -0600 |
| 45 | + @@ -1,7 +1,6 @@ |
| 46 | + -The Way that can be told of is not the eternal Way; |
| 47 | + -The name that can be named is not the eternal name. |
| 48 | + The Nameless is the origin of Heaven and Earth; |
| 49 | + -The Named is the mother of all things. |
| 50 | + +The named is the mother of all things. |
| 51 | + + |
| 52 | + Therefore let there always be non-being, |
| 53 | + so we may see their subtlety, |
| 54 | + And let there always be being, |
| 55 | + @@ -9,3 +8,6 @@ |
| 56 | + The two are the same, |
| 57 | + But after they are produced, |
| 58 | + they have different names. |
| 59 | + +They both may be called deep and profound. |
| 60 | + +Deeper and more profound, |
| 61 | + +The door of all subtleties! |
| 62 | +
|
| 63 | +
|
| 64 | +Parsing |
| 65 | +------- |
| 66 | + |
| 67 | +Here is how we would use What The Patch!? in Python to get the changeset for |
| 68 | +each diff in the patch: |
| 69 | + |
| 70 | +.. code-block:: python |
| 71 | +
|
| 72 | + >>> import whatthepatch |
| 73 | + >>> import pprint |
| 74 | + >>> with open('tests/casefiles/diff-unified.diff') as f: |
| 75 | + ... text = f.read() |
| 76 | + ... |
| 77 | + >>> for diff in whatthepatch.parse_patch(text): |
| 78 | + ... print(diff) # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE |
| 79 | + ... |
| 80 | + diff(header=header(index_path=None, |
| 81 | + old_path='lao', |
| 82 | + old_version='2013-01-05 16:56:19.000000000 -0600', |
| 83 | + new_path='tzu', |
| 84 | + new_version='2013-01-05 16:56:35.000000000 -0600'), |
| 85 | + changes=[Change(old=1, new=None, line='The Way that can be told of is not the eternal Way;', hunk=1), |
| 86 | + Change(old=2, new=None, line='The name that can be named is not the eternal name.', hunk=1), |
| 87 | + Change(old=3, new=1, line='The Nameless is the origin of Heaven and Earth;', hunk=1), |
| 88 | + Change(old=4, new=None, line='The Named is the mother of all things.', hunk=1), |
| 89 | + Change(old=None, new=2, line='The named is the mother of all things.', hunk=1), |
| 90 | + Change(old=None, new=3, line='', hunk=1), |
| 91 | + Change(old=5, new=4, line='Therefore let there always be non-being,', hunk=1), |
| 92 | + Change(old=6, new=5, line=' so we may see their subtlety,', hunk=1), |
| 93 | + Change(old=7, new=6, line='And let there always be being,', hunk=1), |
| 94 | + Change(old=9, new=8, line='The two are the same,', hunk=2), |
| 95 | + Change(old=10, new=9, line='But after they are produced,', hunk=2), |
| 96 | + Change(old=11, new=10, line=' they have different names.', hunk=2), |
| 97 | + Change(old=None, new=11, line='They both may be called deep and profound.', hunk=2), |
| 98 | + Change(old=None, new=12, line='Deeper and more profound,', hunk=2), |
| 99 | + Change(old=None, new=13, line='The door of all subtleties!', hunk=2)], |
| 100 | + text='...') |
| 101 | +
|
| 102 | +The changes are listed as they are in the patch, but instead of the +/- syntax |
| 103 | +of the patch, we get a tuple of two numbers and the text of the line. |
| 104 | +What these numbers indicate are as follows: |
| 105 | + |
| 106 | +#. ``( old=1, new=None, ... )`` indicates line 1 of the file lao was **removed**. |
| 107 | +#. ``( old=None, new=2, ... )`` indicates line 2 of the file tzu was **inserted**. |
| 108 | +#. ``( old=5, new=4, ... )`` indicates that line 5 of lao and line 4 of tzu are **equal**. |
| 109 | + |
| 110 | +Please note that not all patch formats provide the actual lines modified, so some |
| 111 | +results will have the text portion of the tuple set to ``None``. |
| 112 | + |
| 113 | +Applying |
| 114 | +-------- |
| 115 | + |
| 116 | +To apply a diff to some lines of text, first read the patch and parse it. |
| 117 | + |
| 118 | +.. code-block:: python |
| 119 | +
|
| 120 | + >>> import whatthepatch |
| 121 | + >>> with open('tests/casefiles/diff-default.diff') as f: |
| 122 | + ... text = f.read() |
| 123 | + ... |
| 124 | + >>> with open('tests/casefiles/lao') as f: |
| 125 | + ... lao = f.read() |
| 126 | + ... |
| 127 | + >>> diff = [x for x in whatthepatch.parse_patch(text)] |
| 128 | + >>> diff = diff[0] |
| 129 | + >>> tzu = whatthepatch.apply_diff(diff, lao) |
| 130 | + >>> tzu # doctest: +NORMALIZE_WHITESPACE |
| 131 | + ['The Nameless is the origin of Heaven and Earth;', |
| 132 | + 'The named is the mother of all things.', |
| 133 | + '', |
| 134 | + 'Therefore let there always be non-being,', |
| 135 | + ' so we may see their subtlety,', |
| 136 | + 'And let there always be being,', |
| 137 | + ' so we may see their outcome.', |
| 138 | + 'The two are the same,', |
| 139 | + 'But after they are produced,', |
| 140 | + ' they have different names.', |
| 141 | + 'They both may be called deep and profound.', |
| 142 | + 'Deeper and more profound,', |
| 143 | + 'The door of all subtleties!'] |
| 144 | +
|
| 145 | +If apply does not satisfy your needs and you are on a system that has `patch` |
| 146 | +in `PATH`, you can also call `apply_diff(diff, lao, use_patch=True)`. The |
| 147 | +default is False, and patch is not necessary to apply diffs to text. |
| 148 | + |
| 149 | +Contribute |
| 150 | +========== |
| 151 | + |
| 152 | +#. Fork this repository |
| 153 | +#. Create a new branch to work on |
| 154 | +#. Commit your tests and/or changes |
| 155 | +#. Push and create a pull request here! |
| 156 | + |
0 commit comments