|
79 | 79 | { |
80 | 80 | "cell_type": "code", |
81 | 81 | "execution_count": null, |
82 | | - "id": "f53b610f", |
| 82 | + "id": "a8981115", |
83 | 83 | "metadata": {}, |
84 | 84 | "outputs": [], |
85 | 85 | "source": [ |
86 | 86 | "#| export\n", |
87 | 87 | "def read_nb_from_git(\n", |
88 | 88 | " g:Git, # The git object\n", |
89 | | - " ref, # The git ref to read from (e.g. HEAD)\n", |
90 | | - " path # The path to the notebook in git\n", |
| 89 | + " path, # The path to the notebook (absolute or relative to git root)\n", |
| 90 | + " ref=None # The git ref to read from (e.g. HEAD); None for working dir\n", |
91 | 91 | ")->AttrDict: # The notebook\n", |
92 | | - " \"Read notebook from git ref (e.g. HEAD) at path\"\n", |
| 92 | + " \"Read notebook from git ref (e.g. HEAD) at path, or working dir if ref is None\"\n", |
| 93 | + " path = Path(path)\n", |
| 94 | + " if path.is_absolute(): path = path.relative_to(g.top())\n", |
| 95 | + " if ref is None: return read_nb(g.top()/path)\n", |
93 | 96 | " raw = g.show(f'{ref}:{path}', split=False)\n", |
94 | 97 | " return dict2nb(json.loads(raw))" |
95 | 98 | ] |
96 | 99 | }, |
97 | 100 | { |
98 | 101 | "cell_type": "code", |
99 | 102 | "execution_count": null, |
100 | | - "id": "89ebfaa2", |
| 103 | + "id": "f0fdf8e5", |
101 | 104 | "metadata": {}, |
102 | 105 | "outputs": [ |
103 | 106 | { |
|
125 | 128 | } |
126 | 129 | ], |
127 | 130 | "source": [ |
128 | | - "read_nb_from_git(g, 'HEAD', 'test.ipynb').cells" |
| 131 | + "read_nb_from_git(g, 'test.ipynb', 'HEAD').cells" |
129 | 132 | ] |
130 | 133 | }, |
131 | 134 | { |
132 | 135 | "cell_type": "code", |
133 | 136 | "execution_count": null, |
134 | | - "id": "e7032b25", |
| 137 | + "id": "3ac25702", |
135 | 138 | "metadata": {}, |
136 | 139 | "outputs": [], |
137 | 140 | "source": [ |
138 | 141 | "#| export\n", |
139 | | - "def nbs_pair(\n", |
140 | | - " nb_path, # Path to the notebook\n", |
141 | | - " ref_a='HEAD', # First git ref (None for working dir)\n", |
142 | | - " ref_b=None # Second git ref (None for working dir)\n", |
143 | | - "): # Tuple of two notebooks\n", |
144 | | - " \"NBs at two refs; None means working dir. By default provides HEAD and working dir\"\n", |
145 | | - " nb_path = Path(nb_path).resolve()\n", |
146 | | - " g = Git(nb_path.parent)\n", |
147 | | - " rel = nb_path.relative_to(g.top())\n", |
148 | | - " nb_a = read_nb_from_git(g, ref_a, str(rel)) if ref_a else read_nb(nb_path)\n", |
149 | | - " nb_b = read_nb_from_git(g, ref_b, str(rel)) if ref_b else read_nb(nb_path)\n", |
150 | | - " return nb_a, nb_b" |
| 142 | + "def _nb_srcdict(g:Git, nb_path, ref=None, f=noop):\n", |
| 143 | + " \"Dict of id->source\"\n", |
| 144 | + " nb = read_nb_from_git(g, nb_path, ref)\n", |
| 145 | + " return {c['id']: f(c) for c in nb.cells}" |
151 | 146 | ] |
152 | 147 | }, |
153 | 148 | { |
154 | 149 | "cell_type": "code", |
155 | 150 | "execution_count": null, |
156 | | - "id": "154c92ed", |
| 151 | + "id": "27ff9a7b", |
157 | 152 | "metadata": {}, |
158 | 153 | "outputs": [], |
159 | 154 | "source": [ |
160 | | - "a,b = nbs_pair(nb_path)" |
| 155 | + "#| export\n", |
| 156 | + "def nbs_pair(\n", |
| 157 | + " nb_path, # Path to the notebook\n", |
| 158 | + " ref_a='HEAD', # First git ref (None for working dir)\n", |
| 159 | + " ref_b=None, # Second git ref (None for working dir)\n", |
| 160 | + " f=noop # Function to call on contents\n", |
| 161 | + "): # Tuple of two notebooks\n", |
| 162 | + " \"NBs at two refs; None means working dir. By default provides HEAD and working dir\"\n", |
| 163 | + " nb_path = Path(nb_path).resolve()\n", |
| 164 | + " g = Git(nb_path.parent)\n", |
| 165 | + " return _nb_srcdict(g, nb_path, ref_a, f), _nb_srcdict(g, nb_path, ref_b, f)" |
161 | 166 | ] |
162 | 167 | }, |
163 | 168 | { |
164 | 169 | "cell_type": "code", |
165 | 170 | "execution_count": null, |
166 | | - "id": "dddea7bc", |
| 171 | + "id": "154c92ed", |
167 | 172 | "metadata": {}, |
168 | 173 | "outputs": [ |
169 | 174 | { |
170 | 175 | "data": { |
171 | 176 | "text/plain": [ |
172 | | - "({'cell_type': 'code',\n", |
| 177 | + "{'390c8c7d': {'cell_type': 'code',\n", |
173 | 178 | " 'execution_count': 0,\n", |
174 | 179 | " 'id': '390c8c7d',\n", |
175 | 180 | " 'metadata': {},\n", |
176 | 181 | " 'outputs': [],\n", |
177 | 182 | " 'source': 'x=1',\n", |
178 | 183 | " 'idx_': 0},\n", |
179 | | - " {'cell_type': 'code',\n", |
| 184 | + " '7247342c': {'cell_type': 'code',\n", |
180 | 185 | " 'execution_count': 0,\n", |
181 | | - " 'id': '390c8c7d',\n", |
| 186 | + " 'id': '7247342c',\n", |
182 | 187 | " 'metadata': {},\n", |
183 | 188 | " 'outputs': [],\n", |
184 | | - " 'source': 'x = 100',\n", |
185 | | - " 'idx_': 0})" |
| 189 | + " 'source': 'y=2',\n", |
| 190 | + " 'idx_': 1}}" |
186 | 191 | ] |
187 | 192 | }, |
188 | 193 | "execution_count": null, |
|
191 | 196 | } |
192 | 197 | ], |
193 | 198 | "source": [ |
194 | | - "a.cells[0], b.cells[0]" |
| 199 | + "a,b = nbs_pair(nb_path)\n", |
| 200 | + "a" |
195 | 201 | ] |
196 | 202 | }, |
197 | 203 | { |
|
214 | 220 | " outputs=False # Consider cell outputs when comparing\n", |
215 | 221 | "): # Dict of results\n", |
216 | 222 | " \"Apply fn(cell_id, old_content, new_content) to changed cells between two refs\"\n", |
217 | | - " nb_a, nb_b = nbs_pair(nb_path, ref_a, ref_b)\n", |
218 | 223 | " def cell_content(c):\n", |
219 | 224 | " res = c.get('source', '')\n", |
220 | 225 | " if metadata: res += '\\n# metadata: ' + json.dumps(c.get('metadata', {}), sort_keys=True)\n", |
221 | 226 | " if outputs: res += '\\n# outputs: ' + json.dumps(c.get('outputs', []), sort_keys=True)\n", |
222 | 227 | " return res\n", |
223 | | - " old = {c['id']: cell_content(c) for c in nb_a.cells}\n", |
224 | | - " new = {c['id']: cell_content(c) for c in nb_b.cells}\n", |
| 228 | + " old,new = nbs_pair(nb_path, ref_a, ref_b, f=cell_content)\n", |
225 | 229 | " res = {}\n", |
226 | 230 | " if adds: res |= {cid: fn(cid, '', new[cid]) for cid in new if cid not in old}\n", |
227 | 231 | " if changes: res |= {cid: fn(cid, old[cid], new[cid]) for cid in new if cid in old and new[cid] != old[cid]}\n", |
|
0 commit comments