datagit-sdk 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,76 @@
1
+ Metadata-Version: 2.4
2
+ Name: datagit-sdk
3
+ Version: 0.1.0
4
+ Summary: DataGit's Python SDK: Git-style version control for rows in your own database
5
+ License: Apache-2.0
6
+ Project-URL: Homepage, https://github.com/Glyph-Software/datagit
7
+ Project-URL: Documentation, https://github.com/Glyph-Software/datagit/tree/main/sdk
8
+ Project-URL: Source, https://github.com/Glyph-Software/datagit
9
+ Requires-Python: >=3.9
10
+ Description-Content-Type: text/markdown
11
+ Requires-Dist: grpcio>=1.60
12
+ Requires-Dist: protobuf>=4.25
13
+ Provides-Extra: dev
14
+ Requires-Dist: pytest; extra == "dev"
15
+ Requires-Dist: grpcio-tools; extra == "dev"
16
+
17
+ # datagit-sdk
18
+
19
+ Python SDK for [DataGit](https://github.com/Glyph-Software/datagit) — Git-style
20
+ version control for rows in your own PostgreSQL or MySQL database.
21
+
22
+ ```bash
23
+ pip install datagit-sdk
24
+ ```
25
+
26
+ Installed as `datagit-sdk`, imported as `datagit` — the distribution name and the
27
+ import package are separate in Python, and the import keeps the shorter name.
28
+
29
+ ```python
30
+ from decimal import Decimal
31
+ from datagit import Client, col
32
+
33
+ with Client("datagit.internal:443", api_key=KEY) as c:
34
+ items = c.repo("catalog").table("products")
35
+
36
+ # Reading a BRANCH. Reads on main need no DataGit at all — query the table.
37
+ for row in items.read(branch="q4-pricing", where=col(3) == "outdoor"):
38
+ print(row)
39
+
40
+ # One commit, however many rows.
41
+ with items.transaction(branch="q4-pricing", message="Q4 pricing") as tx:
42
+ tx.update(pk, {1: "TENT-4P", 4: Decimal("268.92")})
43
+ ```
44
+
45
+ ## Three things this SDK will not let you do
46
+
47
+ **Set a commit author.** It comes from the credential. An audit trail whose author
48
+ is client-supplied is decoration, so there is no field to pass.
49
+
50
+ **Send a decimal as a `float`.** Values are hashed into history, so a rounding
51
+ difference would change a commit id for data nobody edited. Exact numbers travel
52
+ as `decimal.Decimal` and go on the wire as strings.
53
+
54
+ **Build a filter from a string.** Filters are typed expression trees with no SQL
55
+ text form, so there is nothing to inject into. A hostile string passed as a filter
56
+ value stays a value.
57
+
58
+ ## Rows are keyed by column id
59
+
60
+ Not by name. A rename is metadata-only in DataGit, and keying by name would let a
61
+ rename silently change what a row means on the wire.
62
+
63
+ ## Batch your writes
64
+
65
+ A commit takes the branch's ref lock, so throughput is commits per second
66
+ regardless of how many rows each carries. One commit of a thousand rows costs
67
+ roughly what one commit of one row costs, and a loop of single-row commits is the
68
+ slowest possible way to write.
69
+
70
+ ## Versioning
71
+
72
+ This package and the npm `@glyphsoftware/datagit-sdk` package are the same contract
73
+ twice and release on one version number. A change to the canonical
74
+ encoding is always a major, even when this SDK's own API is untouched.
75
+
76
+ Apache 2.0.
@@ -0,0 +1,60 @@
1
+ # datagit-sdk
2
+
3
+ Python SDK for [DataGit](https://github.com/Glyph-Software/datagit) — Git-style
4
+ version control for rows in your own PostgreSQL or MySQL database.
5
+
6
+ ```bash
7
+ pip install datagit-sdk
8
+ ```
9
+
10
+ Installed as `datagit-sdk`, imported as `datagit` — the distribution name and the
11
+ import package are separate in Python, and the import keeps the shorter name.
12
+
13
+ ```python
14
+ from decimal import Decimal
15
+ from datagit import Client, col
16
+
17
+ with Client("datagit.internal:443", api_key=KEY) as c:
18
+ items = c.repo("catalog").table("products")
19
+
20
+ # Reading a BRANCH. Reads on main need no DataGit at all — query the table.
21
+ for row in items.read(branch="q4-pricing", where=col(3) == "outdoor"):
22
+ print(row)
23
+
24
+ # One commit, however many rows.
25
+ with items.transaction(branch="q4-pricing", message="Q4 pricing") as tx:
26
+ tx.update(pk, {1: "TENT-4P", 4: Decimal("268.92")})
27
+ ```
28
+
29
+ ## Three things this SDK will not let you do
30
+
31
+ **Set a commit author.** It comes from the credential. An audit trail whose author
32
+ is client-supplied is decoration, so there is no field to pass.
33
+
34
+ **Send a decimal as a `float`.** Values are hashed into history, so a rounding
35
+ difference would change a commit id for data nobody edited. Exact numbers travel
36
+ as `decimal.Decimal` and go on the wire as strings.
37
+
38
+ **Build a filter from a string.** Filters are typed expression trees with no SQL
39
+ text form, so there is nothing to inject into. A hostile string passed as a filter
40
+ value stays a value.
41
+
42
+ ## Rows are keyed by column id
43
+
44
+ Not by name. A rename is metadata-only in DataGit, and keying by name would let a
45
+ rename silently change what a row means on the wire.
46
+
47
+ ## Batch your writes
48
+
49
+ A commit takes the branch's ref lock, so throughput is commits per second
50
+ regardless of how many rows each carries. One commit of a thousand rows costs
51
+ roughly what one commit of one row costs, and a loop of single-row commits is the
52
+ slowest possible way to write.
53
+
54
+ ## Versioning
55
+
56
+ This package and the npm `@glyphsoftware/datagit-sdk` package are the same contract
57
+ twice and release on one version number. A change to the canonical
58
+ encoding is always a major, even when this SDK's own API is untouched.
59
+
60
+ Apache 2.0.
@@ -0,0 +1,44 @@
1
+ """DataGit's Python SDK.
2
+
3
+ The generated gRPC stubs are complete and unpleasant. This layer exists to make
4
+ the common paths short without hiding what the service actually does.
5
+
6
+ Three things it does NOT do, deliberately:
7
+
8
+ It does not let you set a commit author. The author comes from the credential
9
+ (DESIGN.md §15.2); an audit trail whose author is client-supplied is decoration.
10
+ There is no field to pass.
11
+
12
+ It does not carry decimals as floats. A value is hashed into history, and a
13
+ rounding difference would change the commit id, so exact numerics travel as
14
+ `decimal.Decimal` and are put on the wire as strings.
15
+
16
+ It does not build predicates from strings. Filters are typed expressions with no
17
+ SQL text form, so there is nothing to inject into (§15.4).
18
+ """
19
+
20
+ __version__ = "0.1.0"
21
+
22
+ from .client import (
23
+ Client,
24
+ Repo,
25
+ Table,
26
+ Transaction,
27
+ Conflict,
28
+ DataGitError,
29
+ ConflictError,
30
+ NeedsMigrationError,
31
+ col,
32
+ )
33
+
34
+ __all__ = [
35
+ "Client",
36
+ "Repo",
37
+ "Table",
38
+ "Transaction",
39
+ "Conflict",
40
+ "DataGitError",
41
+ "ConflictError",
42
+ "NeedsMigrationError",
43
+ "col",
44
+ ]
@@ -0,0 +1,271 @@
1
+ """The ergonomic client."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import contextlib
6
+ from dataclasses import dataclass, field
7
+ from typing import Any, Iterator, Mapping, Sequence
8
+
9
+ import grpc
10
+
11
+ from .v1 import datagit_pb2 as pb
12
+ from .v1 import datagit_pb2_grpc as rpc
13
+ from .values import from_wire, to_wire
14
+
15
+
16
+ class DataGitError(Exception):
17
+ """A refusal from the service, carrying the reason it gave.
18
+
19
+ DataGit's refusals are deliberate and explain themselves -- a table with no
20
+ primary key, a merge over the atomic apply limit, a protected branch with no
21
+ approvals. The message is the useful part, so it is preserved rather than
22
+ replaced with a status name.
23
+ """
24
+
25
+ def __init__(self, err: grpc.RpcError):
26
+ self.code = err.code()
27
+ super().__init__(err.details() or str(err))
28
+
29
+
30
+ class ConflictError(DataGitError):
31
+ """A merge that did not apply because cells disagree.
32
+
33
+ Not an error in the sense of something going wrong: DataGit surfaces
34
+ conflicts rather than guessing, and nothing was applied. The conflicts are on
35
+ `.conflicts`.
36
+ """
37
+
38
+ def __init__(self, conflicts: Sequence["Conflict"]):
39
+ self.conflicts = list(conflicts)
40
+ Exception.__init__(
41
+ self,
42
+ f"{len(self.conflicts)} conflict(s); nothing was applied. "
43
+ f"Resolve them and merge again",
44
+ )
45
+
46
+
47
+ class NeedsMigrationError(Exception):
48
+ """A merge whose data applied but whose SHAPE change is waiting.
49
+
50
+ Not a failure. The data half is committed; the schema change is a migration
51
+ plan to be applied deliberately, because applications read the live table
52
+ directly and a column that appears or vanishes mid-query has no rollout
53
+ window (§10.4).
54
+ """
55
+
56
+ def __init__(self, plan_id: int, ops: Sequence[str]):
57
+ self.plan_id = plan_id
58
+ self.ops = list(ops)
59
+ super().__init__(
60
+ f"data merged; migration plan {plan_id} is pending with "
61
+ f"{len(self.ops)} operation(s). Apply it when readers can tolerate it"
62
+ )
63
+
64
+
65
+ @dataclass(frozen=True)
66
+ class Conflict:
67
+ pk: bytes
68
+ column: str
69
+ kind: str
70
+ base: Any
71
+ ours: Any
72
+ theirs: Any
73
+
74
+
75
+ @dataclass(frozen=True)
76
+ class Column:
77
+ """A column reference, for building typed filters."""
78
+
79
+ id: int
80
+
81
+ def __eq__(self, other: Any) -> pb.Expr: # type: ignore[override]
82
+ return _cmp(self.id, pb.COMPARE_OP_EQ, other)
83
+
84
+ def __ne__(self, other: Any) -> pb.Expr: # type: ignore[override]
85
+ return _cmp(self.id, pb.COMPARE_OP_NE, other)
86
+
87
+ def __lt__(self, other: Any) -> pb.Expr:
88
+ return _cmp(self.id, pb.COMPARE_OP_LT, other)
89
+
90
+ def __le__(self, other: Any) -> pb.Expr:
91
+ return _cmp(self.id, pb.COMPARE_OP_LE, other)
92
+
93
+ def __gt__(self, other: Any) -> pb.Expr:
94
+ return _cmp(self.id, pb.COMPARE_OP_GT, other)
95
+
96
+ def __ge__(self, other: Any) -> pb.Expr:
97
+ return _cmp(self.id, pb.COMPARE_OP_GE, other)
98
+
99
+
100
+ def col(column_id: int) -> Column:
101
+ """Reference a column by its STABLE id, so a rename does not break a filter.
102
+
103
+ Filters build a typed expression tree. There is no string form and therefore
104
+ nothing to inject into (§15.4).
105
+ """
106
+ return Column(column_id)
107
+
108
+
109
+ def _cmp(column_id: int, op: int, value: Any) -> pb.Expr:
110
+ return pb.Expr(
111
+ compare=pb.Compare(col=column_id, op=op, value=to_wire(value))
112
+ )
113
+
114
+
115
+ def and_(*terms: pb.Expr) -> pb.Expr:
116
+ return pb.Expr(and_=pb.And(terms=list(terms)))
117
+
118
+
119
+ def or_(*terms: pb.Expr) -> pb.Expr:
120
+ return pb.Expr(or_=pb.Or(terms=list(terms)))
121
+
122
+
123
+ class Client:
124
+ """A connection to a DataGit service.
125
+
126
+ The API key identifies the principal, and the principal is what commits are
127
+ attributed to. There is no way to commit as someone else, by design.
128
+ """
129
+
130
+ def __init__(self, target: str, api_key: str, *, secure: bool = True):
131
+ creds = grpc.ssl_channel_credentials() if secure else None
132
+ if secure:
133
+ self._channel = grpc.secure_channel(target, creds)
134
+ else:
135
+ # Plaintext is for local development. Over a network it sends the API
136
+ # key in the clear.
137
+ self._channel = grpc.insecure_channel(target)
138
+ self._meta = (("authorization", f"Bearer {api_key}"),)
139
+ self.repository = rpc.RepositoryStub(self._channel)
140
+ self.data = rpc.DataStub(self._channel)
141
+ self.version = rpc.VersionStub(self._channel)
142
+ self.branching = rpc.BranchingStub(self._channel)
143
+ self.proposals = rpc.ProposalsStub(self._channel)
144
+ self.admin = rpc.AdminStub(self._channel)
145
+
146
+ def close(self) -> None:
147
+ self._channel.close()
148
+
149
+ def __enter__(self) -> "Client":
150
+ return self
151
+
152
+ def __exit__(self, *exc: Any) -> None:
153
+ self.close()
154
+
155
+ def repo(self, name: str) -> "Repo":
156
+ return Repo(self, name)
157
+
158
+
159
+ @dataclass
160
+ class Repo:
161
+ client: Client
162
+ name: str
163
+
164
+ def table(self, physical: str) -> "Table":
165
+ return Table(self.client, self.name, physical)
166
+
167
+ def create_branch(self, name: str, *, frm: str = "main") -> None:
168
+ _call(
169
+ self.client.branching.CreateBranch,
170
+ pb.CreateBranchRequest(repo=self.name, name=name, **{"from": frm}),
171
+ self.client,
172
+ )
173
+
174
+
175
+ @dataclass
176
+ class Table:
177
+ client: Client
178
+ repo: str
179
+ physical: str
180
+
181
+ def read(
182
+ self,
183
+ *,
184
+ branch: str = "main",
185
+ where: pb.Expr | None = None,
186
+ limit: int = 0,
187
+ ) -> Iterator[Mapping[int, Any]]:
188
+ """Stream rows from a branch.
189
+
190
+ Reads on `main` do not need DataGit at all -- query the table directly.
191
+ This exists for reading a BRANCH, or a point in history.
192
+ """
193
+ req = pb.ScanRequest(
194
+ repo=self.repo, table=self.physical, branch=branch, limit=limit
195
+ )
196
+ if where is not None:
197
+ req.filter.CopyFrom(where)
198
+ try:
199
+ for row in self.client.data.Scan(req, metadata=self.client._meta):
200
+ yield {k: from_wire(v) for k, v in row.cells.items()}
201
+ except grpc.RpcError as e:
202
+ raise DataGitError(e) from None
203
+
204
+ @contextlib.contextmanager
205
+ def transaction(self, *, branch: str = "main", message: str) -> Iterator["Transaction"]:
206
+ """Buffer changes and commit them as ONE commit on exit.
207
+
208
+ Buffering is not just ergonomics: a commit takes the branch's ref lock,
209
+ so throughput is commits per second regardless of how many rows each one
210
+ carries (§11.3). One commit of a thousand rows costs what one commit of
211
+ one row costs.
212
+
213
+ An exception inside the block abandons the buffer without committing.
214
+ """
215
+ tx = Transaction(self, branch, message)
216
+ yield tx
217
+ tx.commit()
218
+
219
+
220
+ @dataclass
221
+ class Transaction:
222
+ table: Table
223
+ branch: str
224
+ message: str
225
+ _changes: list[pb.Change] = field(default_factory=list)
226
+
227
+ def insert(self, pk: bytes, row: Mapping[int, Any]) -> None:
228
+ self._changes.append(
229
+ pb.Change(pk=pk, op=pb.OP_INSERT, row=_row(row))
230
+ )
231
+
232
+ def update(self, pk: bytes, row: Mapping[int, Any]) -> None:
233
+ self._changes.append(
234
+ pb.Change(pk=pk, op=pb.OP_UPDATE, row=_row(row))
235
+ )
236
+
237
+ def delete(self, pk: bytes) -> None:
238
+ self._changes.append(pb.Change(pk=pk, op=pb.OP_DELETE))
239
+
240
+ def commit(self) -> bytes:
241
+ """Write the buffer as one commit and return its id.
242
+
243
+ There is no author argument, and there never will be: the author comes
244
+ from the credential this client authenticated with (§15.2).
245
+ """
246
+ if not self._changes:
247
+ return b""
248
+ res = _call(
249
+ self.table.client.version.Commit,
250
+ pb.CommitRequest(
251
+ repo=self.table.repo,
252
+ table=self.table.physical,
253
+ branch=self.branch,
254
+ message=self.message,
255
+ changes=self._changes,
256
+ ),
257
+ self.table.client,
258
+ )
259
+ self._changes.clear()
260
+ return res.commit_id
261
+
262
+
263
+ def _row(cells: Mapping[int, Any]) -> pb.Row:
264
+ return pb.Row(cells={k: to_wire(v) for k, v in cells.items()})
265
+
266
+
267
+ def _call(stub_method: Any, req: Any, client: Client) -> Any:
268
+ try:
269
+ return stub_method(req, metadata=client._meta)
270
+ except grpc.RpcError as e:
271
+ raise DataGitError(e) from None
File without changes
@@ -0,0 +1,180 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Generated by the protocol buffer compiler. DO NOT EDIT!
3
+ # NO CHECKED-IN PROTOBUF GENCODE
4
+ # source: datagit/v1/datagit.proto
5
+ # Protobuf Python Version: 7.35.1
6
+ """Generated protocol buffer code."""
7
+ from google.protobuf import descriptor as _descriptor
8
+ from google.protobuf import descriptor_pool as _descriptor_pool
9
+ from google.protobuf import runtime_version as _runtime_version
10
+ from google.protobuf import symbol_database as _symbol_database
11
+ from google.protobuf.internal import builder as _builder
12
+ _runtime_version.ValidateProtobufRuntimeVersion(
13
+ _runtime_version.Domain.PUBLIC,
14
+ 7,
15
+ 35,
16
+ 1,
17
+ '',
18
+ 'datagit/v1/datagit.proto'
19
+ )
20
+ # @@protoc_insertion_point(imports)
21
+
22
+ _sym_db = _symbol_database.Default()
23
+
24
+
25
+ from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2
26
+
27
+
28
+ DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x18\x64\x61tagit/v1/datagit.proto\x12\ndatagit.v1\x1a\x1fgoogle/protobuf/timestamp.proto\"\xdc\x01\n\x05Value\x12\x11\n\x07is_null\x18\x01 \x01(\x08H\x00\x12\x14\n\nbool_value\x18\x02 \x01(\x08H\x00\x12\x13\n\tint_value\x18\x03 \x01(\x03H\x00\x12\x15\n\x0b\x66loat_value\x18\x04 \x01(\x01H\x00\x12\x17\n\rnumeric_value\x18\x05 \x01(\tH\x00\x12\x14\n\ntext_value\x18\x06 \x01(\tH\x00\x12\x15\n\x0b\x62ytes_value\x18\x07 \x01(\x0cH\x00\x12\x30\n\ntime_value\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.TimestampH\x00\x42\x06\n\x04kind\"q\n\x03Row\x12)\n\x05\x63\x65lls\x18\x01 \x03(\x0b\x32\x1a.datagit.v1.Row.CellsEntry\x1a?\n\nCellsEntry\x12\x0b\n\x03key\x18\x01 \x01(\r\x12 \n\x05value\x18\x02 \x01(\x0b\x32\x11.datagit.v1.Value:\x02\x38\x01\"\xe5\x01\n\x04\x45xpr\x12&\n\x07\x63ompare\x18\x01 \x01(\x0b\x32\x13.datagit.v1.CompareH\x00\x12\x1c\n\x02in\x18\x02 \x01(\x0b\x32\x0e.datagit.v1.InH\x00\x12%\n\x07is_null\x18\x03 \x01(\x0b\x32\x12.datagit.v1.IsNullH\x00\x12#\n\x03\x61nd\x18\x04 \x01(\x0b\x32\x14.datagit.v1.JunctionH\x00\x12\"\n\x02or\x18\x05 \x01(\x0b\x32\x14.datagit.v1.JunctionH\x00\x12\x1f\n\x03not\x18\x06 \x01(\x0b\x32\x10.datagit.v1.ExprH\x00\x42\x06\n\x04node\"[\n\x07\x43ompare\x12\x0b\n\x03\x63ol\x18\x01 \x01(\r\x12!\n\x02op\x18\x02 \x01(\x0e\x32\x15.datagit.v1.CompareOp\x12 \n\x05value\x18\x03 \x01(\x0b\x32\x11.datagit.v1.Value\"4\n\x02In\x12\x0b\n\x03\x63ol\x18\x01 \x01(\r\x12!\n\x06values\x18\x02 \x03(\x0b\x32\x11.datagit.v1.Value\"\x15\n\x06IsNull\x12\x0b\n\x03\x63ol\x18\x01 \x01(\r\"+\n\x08Junction\x12\x1f\n\x05terms\x18\x01 \x03(\x0b\x32\x10.datagit.v1.Expr\"N\n\x06\x43hange\x12\n\n\x02pk\x18\x01 \x01(\x0c\x12\x1a\n\x02op\x18\x02 \x01(\x0e\x32\x0e.datagit.v1.Op\x12\x1c\n\x03row\x18\x03 \x01(\x0b\x32\x0f.datagit.v1.Row\"\xb2\x01\n\nCommitInfo\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x0b\n\x03seq\x18\x02 \x01(\x03\x12\x0f\n\x07parents\x18\x03 \x03(\x0c\x12\x0e\n\x06\x61uthor\x18\x04 \x01(\t\x12\x30\n\x0c\x63ommitted_at\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x0f\n\x07message\x18\x06 \x01(\t\x12\x14\n\x0c\x65xternal_ref\x18\x07 \x01(\t\x12\x11\n\tintegrity\x18\x08 \x01(\t\"\x07\n\x05\x45mpty\"!\n\x11\x43reateRepoRequest\x12\x0c\n\x04name\x18\x01 \x01(\t\"<\n\x08RepoInfo\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x16\n\x0e\x64\x65\x66\x61ult_branch\x18\x03 \x01(\t\">\n\x11TrackTableRequest\x12\x0c\n\x04repo\x18\x01 \x01(\t\x12\r\n\x05table\x18\x02 \x01(\t\x12\x0c\n\x04mode\x18\x03 \x01(\t\"_\n\nColumnInfo\x12\n\n\x02id\x18\x01 \x01(\r\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x10\n\x08sql_type\x18\x03 \x01(\t\x12\x10\n\x08nullable\x18\x04 \x01(\x08\x12\x13\n\x0bprimary_key\x18\x05 \x01(\x08\"k\n\tTableInfo\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0c\n\x04mode\x18\x03 \x01(\t\x12\r\n\x05state\x18\x04 \x01(\t\x12\'\n\x07\x63olumns\x18\x05 \x03(\x0b\x32\x16.datagit.v1.ColumnInfo\"2\n\x13UntrackTableRequest\x12\x0c\n\x04repo\x18\x01 \x01(\t\x12\r\n\x05table\x18\x02 \x01(\t\" \n\x10GetStatusRequest\x12\x0c\n\x04repo\x18\x01 \x01(\t\"z\n\nRepoStatus\x12\"\n\x04repo\x18\x01 \x01(\x0b\x32\x14.datagit.v1.RepoInfo\x12%\n\x06tables\x18\x02 \x03(\x0b\x32\x15.datagit.v1.TableInfo\x12!\n\x04refs\x18\x03 \x03(\x0b\x32\x13.datagit.v1.RefInfo\"\x83\x01\n\nGetRequest\x12\x0c\n\x04repo\x18\x01 \x01(\t\x12\r\n\x05table\x18\x02 \x01(\t\x12\x0e\n\x06\x62ranch\x18\x03 \x01(\t\x12\n\n\x02pk\x18\x04 \x01(\x0c\x12\x11\n\tat_commit\x18\x05 \x01(\x0c\x12)\n\x05\x61s_of\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"\xb8\x01\n\x0bScanRequest\x12\x0c\n\x04repo\x18\x01 \x01(\t\x12\r\n\x05table\x18\x02 \x01(\t\x12\x0e\n\x06\x62ranch\x18\x03 \x01(\t\x12 \n\x06\x66ilter\x18\x04 \x01(\x0b\x32\x10.datagit.v1.Expr\x12\r\n\x05limit\x18\x05 \x01(\x05\x12\r\n\x05\x61\x66ter\x18\x06 \x01(\x0c\x12\x11\n\tat_commit\x18\x07 \x01(\x0c\x12)\n\x05\x61s_of\x18\x08 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"\xb8\x01\n\rCommitRequest\x12\x0c\n\x04repo\x18\x01 \x01(\t\x12\r\n\x05table\x18\x02 \x01(\t\x12\x0e\n\x06\x62ranch\x18\x03 \x01(\t\x12#\n\x07\x63hanges\x18\x04 \x03(\x0b\x32\x12.datagit.v1.Change\x12\x0f\n\x07message\x18\x05 \x01(\t\x12\x14\n\x0c\x65xternal_ref\x18\x06 \x01(\t\x12\x15\n\rexpected_head\x18\x07 \x01(\x0c\x12\x17\n\x0fidempotency_key\x18\x08 \x01(\t\"?\n\x0e\x43ommitResponse\x12\n\n\x02id\x18\x01 \x01(\x0c\x12\x0b\n\x03seq\x18\x02 \x01(\x03\x12\x14\n\x0crows_changed\x18\x03 \x01(\x05\"9\n\nLogRequest\x12\x0c\n\x04repo\x18\x01 \x01(\t\x12\x0e\n\x06\x62ranch\x18\x02 \x01(\t\x12\r\n\x05limit\x18\x03 \x01(\x05\"\\\n\x0b\x44iffRequest\x12\x0c\n\x04repo\x18\x01 \x01(\t\x12\r\n\x05table\x18\x02 \x01(\t\x12\x0e\n\x06\x62ranch\x18\x03 \x01(\t\x12\x10\n\x08\x66rom_seq\x18\x04 \x01(\x03\x12\x0e\n\x06to_seq\x18\x05 \x01(\x03\"\x90\x01\n\x0c\x43hangeDetail\x12\n\n\x02pk\x18\x01 \x01(\x0c\x12\x1a\n\x02op\x18\x02 \x01(\x0e\x32\x0e.datagit.v1.Op\x12\x1f\n\x06\x62\x65\x66ore\x18\x03 \x01(\x0b\x32\x0f.datagit.v1.Row\x12\x1e\n\x05\x61\x66ter\x18\x04 \x01(\x0b\x32\x0f.datagit.v1.Row\x12\x17\n\x0f\x63hanged_columns\x18\x05 \x03(\r\"X\n\x0c\x42lameRequest\x12\x0c\n\x04repo\x18\x01 \x01(\t\x12\r\n\x05table\x18\x02 \x01(\t\x12\x0e\n\x06\x62ranch\x18\x03 \x01(\t\x12\n\n\x02pk\x18\x04 \x01(\x0c\x12\x0f\n\x07\x63olumns\x18\x05 \x03(\r\"\x96\x01\n\tCellBlame\x12\x0b\n\x03\x63ol\x18\x01 \x01(\r\x12 \n\x05value\x18\x02 \x01(\x0b\x32\x11.datagit.v1.Value\x12\x11\n\tcommit_id\x18\x03 \x01(\x0c\x12\x0e\n\x06\x61uthor\x18\x04 \x01(\t\x12&\n\x02\x61t\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x0f\n\x07message\x18\x06 \x01(\t\"I\n\x0eHistoryRequest\x12\x0c\n\x04repo\x18\x01 \x01(\t\x12\r\n\x05table\x18\x02 \x01(\t\x12\x0e\n\x06\x62ranch\x18\x03 \x01(\t\x12\n\n\x02pk\x18\x04 \x01(\x0c\"\xc4\x01\n\nRowVersion\x12\x10\n\x08seq_from\x18\x01 \x01(\x03\x12\x0e\n\x06seq_to\x18\x02 \x01(\x03\x12\x1a\n\x02op\x18\x03 \x01(\x0e\x32\x0e.datagit.v1.Op\x12\x11\n\tcommit_id\x18\x04 \x01(\x0c\x12\x1c\n\x03row\x18\x05 \x01(\x0b\x32\x0f.datagit.v1.Row\x12\x0e\n\x06\x61uthor\x18\x06 \x01(\t\x12&\n\x02\x61t\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x0f\n\x07message\x18\x08 \x01(\t\"o\n\rRevertRequest\x12\x0c\n\x04repo\x18\x01 \x01(\t\x12\r\n\x05table\x18\x02 \x01(\t\x12\x0e\n\x06\x62ranch\x18\x03 \x01(\t\x12\x11\n\tcommit_id\x18\x04 \x01(\x0c\x12\x0f\n\x07message\x18\x05 \x01(\t\x12\r\n\x05\x66orce\x18\x06 \x01(\x08\"?\n\x13\x43reateBranchRequest\x12\x0c\n\x04repo\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0c\n\x04\x66rom\x18\x03 \x01(\t\"\xbb\x01\n\x07RefInfo\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04kind\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x0c\n\x04head\x18\x04 \x01(\x0c\x12\x10\n\x08head_seq\x18\x05 \x01(\x03\x12\x0e\n\x06parent\x18\x06 \x01(\t\x12\x13\n\x0b\x63hain_depth\x18\x07 \x01(\x05\x12\x11\n\tprotected\x18\x08 \x01(\x08\x12\x15\n\rmin_approvals\x18\t \x01(\x05\x12\x19\n\x11merge_in_progress\x18\n \x01(\x08\"1\n\x13\x44\x65leteBranchRequest\x12\x0c\n\x04repo\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\"\x1f\n\x0fListRefsRequest\x12\x0c\n\x04repo\x18\x01 \x01(\t\"A\n\x10\x43reateTagRequest\x12\x0c\n\x04repo\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x11\n\tat_commit\x18\x03 \x01(\x0c\"F\n\x17UpdateFromParentRequest\x12\x0c\n\x04repo\x18\x01 \x01(\t\x12\r\n\x05table\x18\x02 \x01(\t\x12\x0e\n\x06\x62ranch\x18\x03 \x01(\t\"G\n\x12MaterializeRequest\x12\x0c\n\x04repo\x18\x01 \x01(\t\x12\x0e\n\x06\x62ranch\x18\x02 \x01(\t\x12\x13\n\x0binto_schema\x18\x03 \x01(\t\"X\n\x0eProtectRequest\x12\x0c\n\x04repo\x18\x01 \x01(\t\x12\x0e\n\x06\x62ranch\x18\x02 \x01(\t\x12\x11\n\tprotected\x18\x03 \x01(\x08\x12\x15\n\rmin_approvals\x18\x04 \x01(\x05\"2\n\x12OpenSessionRequest\x12\x0c\n\x04repo\x18\x01 \x01(\t\x12\x0e\n\x06\x62ranch\x18\x02 \x01(\t\"o\n\x0bSessionInfo\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0e\n\x06\x62ranch\x18\x02 \x01(\t\x12\x13\n\x0b\x62\x61se_commit\x18\x03 \x01(\x0c\x12/\n\x0blease_until\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"k\n\x13SessionWriteRequest\x12\x0c\n\x04repo\x18\x01 \x01(\t\x12\r\n\x05table\x18\x02 \x01(\t\x12\x12\n\nsession_id\x18\x03 \x01(\t\x12#\n\x07\x63hanges\x18\x04 \x03(\x0b\x32\x12.datagit.v1.Change\"X\n\x14\x43ommitSessionRequest\x12\x0c\n\x04repo\x18\x01 \x01(\t\x12\r\n\x05table\x18\x02 \x01(\t\x12\x12\n\nsession_id\x18\x03 \x01(\t\x12\x0f\n\x07message\x18\x04 \x01(\t\"H\n\x15\x41\x62\x61ndonSessionRequest\x12\x0c\n\x04repo\x18\x01 \x01(\t\x12\r\n\x05table\x18\x02 \x01(\t\x12\x12\n\nsession_id\x18\x03 \x01(\t\"e\n\x15\x43reateProposalRequest\x12\x0c\n\x04repo\x18\x01 \x01(\t\x12\x0c\n\x04\x66rom\x18\x02 \x01(\t\x12\x0c\n\x04into\x18\x03 \x01(\t\x12\r\n\x05title\x18\x04 \x01(\t\x12\x13\n\x0b\x64\x65scription\x18\x05 \x01(\t\"\x98\x01\n\x0cProposalInfo\x12\n\n\x02id\x18\x01 \x01(\x03\x12\x0c\n\x04\x66rom\x18\x02 \x01(\t\x12\x0c\n\x04into\x18\x03 \x01(\t\x12\r\n\x05title\x18\x04 \x01(\t\x12\r\n\x05state\x18\x05 \x01(\t\x12\x12\n\ncreated_by\x18\x06 \x01(\t\x12.\n\ncreated_at\x18\x07 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"N\n\rReviewRequest\x12\x0c\n\x04repo\x18\x01 \x01(\t\x12\x13\n\x0bproposal_id\x18\x02 \x01(\x03\x12\x0c\n\x04kind\x18\x03 \x01(\t\x12\x0c\n\x04\x62ody\x18\x04 \x01(\t\"H\n\x14ListConflictsRequest\x12\x0c\n\x04repo\x18\x01 \x01(\t\x12\r\n\x05table\x18\x02 \x01(\t\x12\x13\n\x0bproposal_id\x18\x03 \x01(\x03\"\x82\x01\n\x0c\x43onflictInfo\x12\n\n\x02id\x18\x01 \x01(\x03\x12\n\n\x02pk\x18\x02 \x01(\x0c\x12\x0e\n\x06\x63olumn\x18\x03 \x01(\t\x12\x0c\n\x04kind\x18\x04 \x01(\t\x12\x0c\n\x04\x62\x61se\x18\x05 \x01(\t\x12\x0c\n\x04ours\x18\x06 \x01(\t\x12\x0e\n\x06theirs\x18\x07 \x01(\t\x12\x10\n\x08resolved\x18\x08 \x01(\x08\"^\n\x16ResolveConflictRequest\x12\x0c\n\x04repo\x18\x01 \x01(\t\x12\x13\n\x0b\x63onflict_id\x18\x02 \x01(\x03\x12\x12\n\nresolution\x18\x03 \x01(\t\x12\r\n\x05value\x18\x04 \x01(\t\"_\n\x14MergeProposalRequest\x12\x0c\n\x04repo\x18\x01 \x01(\t\x12\r\n\x05table\x18\x02 \x01(\t\x12\x13\n\x0bproposal_id\x18\x03 \x01(\x03\x12\x15\n\rallow_chunked\x18\x04 \x01(\x08\"t\n\rMergeResponse\x12\r\n\x05\x63lean\x18\x01 \x01(\x08\x12\x11\n\tcommit_id\x18\x02 \x01(\x0c\x12\x14\n\x0crows_applied\x18\x03 \x01(\x05\x12+\n\tconflicts\x18\x04 \x03(\x0b\x32\x18.datagit.v1.ConflictInfo\"T\n\x0cPruneRequest\x12\x0c\n\x04repo\x18\x01 \x01(\t\x12\r\n\x05table\x18\x02 \x01(\t\x12\x11\n\tkeep_days\x18\x03 \x01(\x05\x12\x14\n\x0ckeep_commits\x18\x04 \x01(\x05\"D\n\rPruneResponse\x12\x18\n\x10versions_removed\x18\x01 \x01(\x05\x12\x19\n\x11\x63ommits_protected\x18\x02 \x01(\x05\"\x1c\n\x0cRunGCRequest\x12\x0c\n\x04repo\x18\x01 \x01(\t\">\n\nGCResponse\x12\x17\n\x0forphan_versions\x18\x01 \x01(\x05\x12\x17\n\x0fsessions_reaped\x18\x02 \x01(\x05\"G\n\x0cPurgeRequest\x12\x0c\n\x04repo\x18\x01 \x01(\t\x12\r\n\x05table\x18\x02 \x01(\t\x12\n\n\x02pk\x18\x03 \x01(\x0c\x12\x0e\n\x06reason\x18\x04 \x01(\t\"h\n\x0cPurgeReceipt\x12\x18\n\x10versions_removed\x18\x01 \x01(\x05\x12\x16\n\x0e\x63ommits_marked\x18\x02 \x01(\x05\x12&\n\x02\x61t\x18\x03 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\"b\n\rVerifyRequest\x12\x0c\n\x04repo\x18\x01 \x01(\t\x12\x0e\n\x06\x62ranch\x18\x02 \x01(\t\x12\r\n\x05\x64rift\x18\x03 \x01(\x08\x12\x11\n\tintegrity\x18\x04 \x01(\x08\x12\x11\n\tintervals\x18\x05 \x01(\x08\"I\n\rVerifyFinding\x12\r\n\x05\x63heck\x18\x01 \x01(\t\x12\r\n\x05table\x18\x02 \x01(\t\x12\n\n\x02ok\x18\x03 \x01(\x08\x12\x0e\n\x06\x64\x65tail\x18\x04 \x01(\t\"<\n\rExportRequest\x12\x0c\n\x04repo\x18\x01 \x01(\t\x12\r\n\x05table\x18\x02 \x01(\t\x12\x0e\n\x06\x62ranch\x18\x03 \x01(\t\"\x1c\n\x0b\x45xportChunk\x12\r\n\x05jsonl\x18\x01 \x01(\x0c*\xae\x01\n\tCompareOp\x12\x1a\n\x16\x43OMPARE_OP_UNSPECIFIED\x10\x00\x12\x11\n\rCOMPARE_OP_EQ\x10\x01\x12\x11\n\rCOMPARE_OP_NE\x10\x02\x12\x11\n\rCOMPARE_OP_LT\x10\x03\x12\x11\n\rCOMPARE_OP_LE\x10\x04\x12\x11\n\rCOMPARE_OP_GT\x10\x05\x12\x11\n\rCOMPARE_OP_GE\x10\x06\x12\x13\n\x0f\x43OMPARE_OP_LIKE\x10\x07*E\n\x02Op\x12\x12\n\x0eOP_UNSPECIFIED\x10\x00\x12\r\n\tOP_INSERT\x10\x01\x12\r\n\tOP_UPDATE\x10\x02\x12\r\n\tOP_DELETE\x10\x03\x32\x9a\x02\n\nRepository\x12\x41\n\nCreateRepo\x12\x1d.datagit.v1.CreateRepoRequest\x1a\x14.datagit.v1.RepoInfo\x12\x42\n\nTrackTable\x12\x1d.datagit.v1.TrackTableRequest\x1a\x15.datagit.v1.TableInfo\x12\x42\n\x0cUntrackTable\x12\x1f.datagit.v1.UntrackTableRequest\x1a\x11.datagit.v1.Empty\x12\x41\n\tGetStatus\x12\x1c.datagit.v1.GetStatusRequest\x1a\x16.datagit.v1.RepoStatus2j\n\x04\x44\x61ta\x12.\n\x03Get\x12\x16.datagit.v1.GetRequest\x1a\x0f.datagit.v1.Row\x12\x32\n\x04Scan\x12\x17.datagit.v1.ScanRequest\x1a\x0f.datagit.v1.Row0\x01\x32\xfe\x02\n\x07Version\x12?\n\x06\x43ommit\x12\x19.datagit.v1.CommitRequest\x1a\x1a.datagit.v1.CommitResponse\x12\x37\n\x03Log\x12\x16.datagit.v1.LogRequest\x1a\x16.datagit.v1.CommitInfo0\x01\x12;\n\x04\x44iff\x12\x17.datagit.v1.DiffRequest\x1a\x18.datagit.v1.ChangeDetail0\x01\x12:\n\x05\x42lame\x12\x18.datagit.v1.BlameRequest\x1a\x15.datagit.v1.CellBlame0\x01\x12?\n\x07History\x12\x1a.datagit.v1.HistoryRequest\x1a\x16.datagit.v1.RowVersion0\x01\x12?\n\x06Revert\x12\x19.datagit.v1.RevertRequest\x1a\x1a.datagit.v1.CommitResponse2\xe7\x03\n\tBranching\x12\x44\n\x0c\x43reateBranch\x12\x1f.datagit.v1.CreateBranchRequest\x1a\x13.datagit.v1.RefInfo\x12\x42\n\x0c\x44\x65leteBranch\x12\x1f.datagit.v1.DeleteBranchRequest\x1a\x11.datagit.v1.Empty\x12>\n\x08ListRefs\x12\x1b.datagit.v1.ListRefsRequest\x1a\x13.datagit.v1.RefInfo0\x01\x12>\n\tCreateTag\x12\x1c.datagit.v1.CreateTagRequest\x1a\x13.datagit.v1.RefInfo\x12R\n\x10UpdateFromParent\x12#.datagit.v1.UpdateFromParentRequest\x1a\x19.datagit.v1.MergeResponse\x12@\n\x0bMaterialize\x12\x1e.datagit.v1.MaterializeRequest\x1a\x11.datagit.v1.Empty\x12:\n\x07Protect\x12\x1a.datagit.v1.ProtectRequest\x1a\x13.datagit.v1.RefInfo2\xad\x02\n\x08Sessions\x12\x46\n\x0bOpenSession\x12\x1e.datagit.v1.OpenSessionRequest\x1a\x17.datagit.v1.SessionInfo\x12\x42\n\x0cSessionWrite\x12\x1f.datagit.v1.SessionWriteRequest\x1a\x11.datagit.v1.Empty\x12M\n\rCommitSession\x12 .datagit.v1.CommitSessionRequest\x1a\x1a.datagit.v1.CommitResponse\x12\x46\n\x0e\x41\x62\x61ndonSession\x12!.datagit.v1.AbandonSessionRequest\x1a\x11.datagit.v1.Empty2\xf9\x02\n\tProposals\x12M\n\x0e\x43reateProposal\x12!.datagit.v1.CreateProposalRequest\x1a\x18.datagit.v1.ProposalInfo\x12\x36\n\x06Review\x12\x19.datagit.v1.ReviewRequest\x1a\x11.datagit.v1.Empty\x12M\n\rListConflicts\x12 .datagit.v1.ListConflictsRequest\x1a\x18.datagit.v1.ConflictInfo0\x01\x12H\n\x0fResolveConflict\x12\".datagit.v1.ResolveConflictRequest\x1a\x11.datagit.v1.Empty\x12L\n\rMergeProposal\x12 .datagit.v1.MergeProposalRequest\x1a\x19.datagit.v1.MergeResponse2\xbf\x02\n\x05\x41\x64min\x12<\n\x05Prune\x12\x18.datagit.v1.PruneRequest\x1a\x19.datagit.v1.PruneResponse\x12\x39\n\x05RunGC\x12\x18.datagit.v1.RunGCRequest\x1a\x16.datagit.v1.GCResponse\x12;\n\x05Purge\x12\x18.datagit.v1.PurgeRequest\x1a\x18.datagit.v1.PurgeReceipt\x12@\n\x06Verify\x12\x19.datagit.v1.VerifyRequest\x1a\x19.datagit.v1.VerifyFinding0\x01\x12>\n\x06\x45xport\x12\x19.datagit.v1.ExportRequest\x1a\x17.datagit.v1.ExportChunk0\x01\x42<Z:github.com/Glyph-Software/datagit/gen/datagit/v1;datagitv1b\x06proto3')
29
+
30
+ _globals = globals()
31
+ _builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, _globals)
32
+ _builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'datagit.v1.datagit_pb2', _globals)
33
+ if not _descriptor._USE_C_DESCRIPTORS:
34
+ _globals['DESCRIPTOR']._loaded_options = None
35
+ _globals['DESCRIPTOR']._serialized_options = b'Z:github.com/Glyph-Software/datagit/gen/datagit/v1;datagitv1'
36
+ _globals['_ROW_CELLSENTRY']._loaded_options = None
37
+ _globals['_ROW_CELLSENTRY']._serialized_options = b'8\001'
38
+ _globals['_COMPAREOP']._serialized_start=5840
39
+ _globals['_COMPAREOP']._serialized_end=6014
40
+ _globals['_OP']._serialized_start=6016
41
+ _globals['_OP']._serialized_end=6085
42
+ _globals['_VALUE']._serialized_start=74
43
+ _globals['_VALUE']._serialized_end=294
44
+ _globals['_ROW']._serialized_start=296
45
+ _globals['_ROW']._serialized_end=409
46
+ _globals['_ROW_CELLSENTRY']._serialized_start=346
47
+ _globals['_ROW_CELLSENTRY']._serialized_end=409
48
+ _globals['_EXPR']._serialized_start=412
49
+ _globals['_EXPR']._serialized_end=641
50
+ _globals['_COMPARE']._serialized_start=643
51
+ _globals['_COMPARE']._serialized_end=734
52
+ _globals['_IN']._serialized_start=736
53
+ _globals['_IN']._serialized_end=788
54
+ _globals['_ISNULL']._serialized_start=790
55
+ _globals['_ISNULL']._serialized_end=811
56
+ _globals['_JUNCTION']._serialized_start=813
57
+ _globals['_JUNCTION']._serialized_end=856
58
+ _globals['_CHANGE']._serialized_start=858
59
+ _globals['_CHANGE']._serialized_end=936
60
+ _globals['_COMMITINFO']._serialized_start=939
61
+ _globals['_COMMITINFO']._serialized_end=1117
62
+ _globals['_EMPTY']._serialized_start=1119
63
+ _globals['_EMPTY']._serialized_end=1126
64
+ _globals['_CREATEREPOREQUEST']._serialized_start=1128
65
+ _globals['_CREATEREPOREQUEST']._serialized_end=1161
66
+ _globals['_REPOINFO']._serialized_start=1163
67
+ _globals['_REPOINFO']._serialized_end=1223
68
+ _globals['_TRACKTABLEREQUEST']._serialized_start=1225
69
+ _globals['_TRACKTABLEREQUEST']._serialized_end=1287
70
+ _globals['_COLUMNINFO']._serialized_start=1289
71
+ _globals['_COLUMNINFO']._serialized_end=1384
72
+ _globals['_TABLEINFO']._serialized_start=1386
73
+ _globals['_TABLEINFO']._serialized_end=1493
74
+ _globals['_UNTRACKTABLEREQUEST']._serialized_start=1495
75
+ _globals['_UNTRACKTABLEREQUEST']._serialized_end=1545
76
+ _globals['_GETSTATUSREQUEST']._serialized_start=1547
77
+ _globals['_GETSTATUSREQUEST']._serialized_end=1579
78
+ _globals['_REPOSTATUS']._serialized_start=1581
79
+ _globals['_REPOSTATUS']._serialized_end=1703
80
+ _globals['_GETREQUEST']._serialized_start=1706
81
+ _globals['_GETREQUEST']._serialized_end=1837
82
+ _globals['_SCANREQUEST']._serialized_start=1840
83
+ _globals['_SCANREQUEST']._serialized_end=2024
84
+ _globals['_COMMITREQUEST']._serialized_start=2027
85
+ _globals['_COMMITREQUEST']._serialized_end=2211
86
+ _globals['_COMMITRESPONSE']._serialized_start=2213
87
+ _globals['_COMMITRESPONSE']._serialized_end=2276
88
+ _globals['_LOGREQUEST']._serialized_start=2278
89
+ _globals['_LOGREQUEST']._serialized_end=2335
90
+ _globals['_DIFFREQUEST']._serialized_start=2337
91
+ _globals['_DIFFREQUEST']._serialized_end=2429
92
+ _globals['_CHANGEDETAIL']._serialized_start=2432
93
+ _globals['_CHANGEDETAIL']._serialized_end=2576
94
+ _globals['_BLAMEREQUEST']._serialized_start=2578
95
+ _globals['_BLAMEREQUEST']._serialized_end=2666
96
+ _globals['_CELLBLAME']._serialized_start=2669
97
+ _globals['_CELLBLAME']._serialized_end=2819
98
+ _globals['_HISTORYREQUEST']._serialized_start=2821
99
+ _globals['_HISTORYREQUEST']._serialized_end=2894
100
+ _globals['_ROWVERSION']._serialized_start=2897
101
+ _globals['_ROWVERSION']._serialized_end=3093
102
+ _globals['_REVERTREQUEST']._serialized_start=3095
103
+ _globals['_REVERTREQUEST']._serialized_end=3206
104
+ _globals['_CREATEBRANCHREQUEST']._serialized_start=3208
105
+ _globals['_CREATEBRANCHREQUEST']._serialized_end=3271
106
+ _globals['_REFINFO']._serialized_start=3274
107
+ _globals['_REFINFO']._serialized_end=3461
108
+ _globals['_DELETEBRANCHREQUEST']._serialized_start=3463
109
+ _globals['_DELETEBRANCHREQUEST']._serialized_end=3512
110
+ _globals['_LISTREFSREQUEST']._serialized_start=3514
111
+ _globals['_LISTREFSREQUEST']._serialized_end=3545
112
+ _globals['_CREATETAGREQUEST']._serialized_start=3547
113
+ _globals['_CREATETAGREQUEST']._serialized_end=3612
114
+ _globals['_UPDATEFROMPARENTREQUEST']._serialized_start=3614
115
+ _globals['_UPDATEFROMPARENTREQUEST']._serialized_end=3684
116
+ _globals['_MATERIALIZEREQUEST']._serialized_start=3686
117
+ _globals['_MATERIALIZEREQUEST']._serialized_end=3757
118
+ _globals['_PROTECTREQUEST']._serialized_start=3759
119
+ _globals['_PROTECTREQUEST']._serialized_end=3847
120
+ _globals['_OPENSESSIONREQUEST']._serialized_start=3849
121
+ _globals['_OPENSESSIONREQUEST']._serialized_end=3899
122
+ _globals['_SESSIONINFO']._serialized_start=3901
123
+ _globals['_SESSIONINFO']._serialized_end=4012
124
+ _globals['_SESSIONWRITEREQUEST']._serialized_start=4014
125
+ _globals['_SESSIONWRITEREQUEST']._serialized_end=4121
126
+ _globals['_COMMITSESSIONREQUEST']._serialized_start=4123
127
+ _globals['_COMMITSESSIONREQUEST']._serialized_end=4211
128
+ _globals['_ABANDONSESSIONREQUEST']._serialized_start=4213
129
+ _globals['_ABANDONSESSIONREQUEST']._serialized_end=4285
130
+ _globals['_CREATEPROPOSALREQUEST']._serialized_start=4287
131
+ _globals['_CREATEPROPOSALREQUEST']._serialized_end=4388
132
+ _globals['_PROPOSALINFO']._serialized_start=4391
133
+ _globals['_PROPOSALINFO']._serialized_end=4543
134
+ _globals['_REVIEWREQUEST']._serialized_start=4545
135
+ _globals['_REVIEWREQUEST']._serialized_end=4623
136
+ _globals['_LISTCONFLICTSREQUEST']._serialized_start=4625
137
+ _globals['_LISTCONFLICTSREQUEST']._serialized_end=4697
138
+ _globals['_CONFLICTINFO']._serialized_start=4700
139
+ _globals['_CONFLICTINFO']._serialized_end=4830
140
+ _globals['_RESOLVECONFLICTREQUEST']._serialized_start=4832
141
+ _globals['_RESOLVECONFLICTREQUEST']._serialized_end=4926
142
+ _globals['_MERGEPROPOSALREQUEST']._serialized_start=4928
143
+ _globals['_MERGEPROPOSALREQUEST']._serialized_end=5023
144
+ _globals['_MERGERESPONSE']._serialized_start=5025
145
+ _globals['_MERGERESPONSE']._serialized_end=5141
146
+ _globals['_PRUNEREQUEST']._serialized_start=5143
147
+ _globals['_PRUNEREQUEST']._serialized_end=5227
148
+ _globals['_PRUNERESPONSE']._serialized_start=5229
149
+ _globals['_PRUNERESPONSE']._serialized_end=5297
150
+ _globals['_RUNGCREQUEST']._serialized_start=5299
151
+ _globals['_RUNGCREQUEST']._serialized_end=5327
152
+ _globals['_GCRESPONSE']._serialized_start=5329
153
+ _globals['_GCRESPONSE']._serialized_end=5391
154
+ _globals['_PURGEREQUEST']._serialized_start=5393
155
+ _globals['_PURGEREQUEST']._serialized_end=5464
156
+ _globals['_PURGERECEIPT']._serialized_start=5466
157
+ _globals['_PURGERECEIPT']._serialized_end=5570
158
+ _globals['_VERIFYREQUEST']._serialized_start=5572
159
+ _globals['_VERIFYREQUEST']._serialized_end=5670
160
+ _globals['_VERIFYFINDING']._serialized_start=5672
161
+ _globals['_VERIFYFINDING']._serialized_end=5745
162
+ _globals['_EXPORTREQUEST']._serialized_start=5747
163
+ _globals['_EXPORTREQUEST']._serialized_end=5807
164
+ _globals['_EXPORTCHUNK']._serialized_start=5809
165
+ _globals['_EXPORTCHUNK']._serialized_end=5837
166
+ _globals['_REPOSITORY']._serialized_start=6088
167
+ _globals['_REPOSITORY']._serialized_end=6370
168
+ _globals['_DATA']._serialized_start=6372
169
+ _globals['_DATA']._serialized_end=6478
170
+ _globals['_VERSION']._serialized_start=6481
171
+ _globals['_VERSION']._serialized_end=6863
172
+ _globals['_BRANCHING']._serialized_start=6866
173
+ _globals['_BRANCHING']._serialized_end=7353
174
+ _globals['_SESSIONS']._serialized_start=7356
175
+ _globals['_SESSIONS']._serialized_end=7657
176
+ _globals['_PROPOSALS']._serialized_start=7660
177
+ _globals['_PROPOSALS']._serialized_end=8037
178
+ _globals['_ADMIN']._serialized_start=8040
179
+ _globals['_ADMIN']._serialized_end=8359
180
+ # @@protoc_insertion_point(module_scope)