21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
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
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
- **Double-check crosslinking of other types** and make sure that we are not missing newly-added features.
- **Stash** support. First requires merge support.
- **Unversioned files** should be trivial to do.
- Maybe pending-moderation support (tickets, ticket comments, wiki edits), depending on how centrally-managed such data need to be (i.e. whether it can be delegated to an app layer).
## Checkin
The SQL code related to checkins has diverged significantly from fossil since libf's checkin support was first implemented (the better part of a decade ago). Though libf's is known to work for the cases supported by its existing feature set, it "really couldn't hurt" to audit the checkin algorithm against fossil's. It's okay if they differ, so long as the results are the same. This will be especially important as merge support is added, since the libf checkin code has never dealt with that. What brings all this up is a corner-case discrepancy discovered in fossil's checkin support regarding merged-and-edited files:
<https://fossil-scm.org/forum/forumpost/03f6b307f89c990b?t=h>
for which Richard proposes a patch to fossil's `checkin.c`:
```
--- src/checkin.c
+++ src/checkin.c
@@ -2572,11 +2572,11 @@
** table. If there were arguments passed to this command, only
** the identified files are inserted (if they have been modified).
*/
db_prepare(&q,
"SELECT id, %Q || pathname, mrid, %s, %s, %s FROM vfile "
- "WHERE chnged IN (1, 7, 9) AND NOT deleted AND is_selected(id)",
+ "WHERE chnged<>0 AND NOT deleted AND is_selected(id)",
g.zLocalRoot,
glob_expr("pathname", db_get("crlf-glob",db_get("crnl-glob",""))),
glob_expr("pathname", db_get("binary-glob","")),
glob_expr("pathname", db_get("encoding-glob",""))
);
@@ -2610,16 +2610,18 @@
blob_str(&fname));
blob_reset(&fname);
}
nrid = content_put(&content);
blob_reset(&content);
- if( rid>0 ){
- content_deltify(rid, &nrid, 1, 0);
+ if( nrid!=rid ){
+ if( rid>0 ){
+ content_deltify(rid, &nrid, 1, 0);
+ }
+ db_multi_exec("UPDATE vfile SET mrid=%d, rid=%d, mhash=NULL WHERE id=%d",
+ nrid,nrid,id);
+ db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nrid);
}
- db_multi_exec("UPDATE vfile SET mrid=%d, rid=%d, mhash=NULL WHERE id=%d",
- nrid,nrid,id);
- db_multi_exec("INSERT OR IGNORE INTO unsent VALUES(%d)", nrid);
}
db_finalize(&q);
if( nConflict && !allowConflict ){
fossil_fatal("abort due to unresolved merge conflicts; "
"use --allow-conflict to override");
```
The corresponding code in libf looks *much* different than that now, and it's not currently (2021-09-17) clear whether or how that change would need to apply to libf's impl
# Security-relevant
But not otherwise SCM-relevant...
- **Port over `db_unprotect()` and `db_protect_pop()`** APIs, which allow a db to effectively be made read-only except for limited windows where specific sections of it needs to be writable. Related: `db.c:db_top_autorizer()`.
|