Thus said Zakero on Sun, 16 Oct 2016 18:45:41 -0500:
> Ran into an interesting problem yesterday when merging branches:
>
> SQLITE_CONSTRAINT: abort at 41 in [INSERT INTO
> vfile(vid,chnged,deleted,rid,mrid,isexe,islink,pathname) SELECT
> 21178,3,0,rid,mrid,isexe,islink,pathname FROM vfile WHERE id=4735]: UNIQUE
> constraint failed: vfile.pathname, vfile.
> fossil: UNIQUE constraint failed: vfile.pathname, vfile.vid: {INSERT INTO
> vfile(vid,chnged,deleted,rid,mrid,isexe,islink,pathname) SELECT
> 21178,3,0,rid,mrid,isexe,islink,pathname FROM vfile WHERE id=4735}
> Rolling back prior filesystem changes...
I have been working with Zakero on this problem, but so far have been
unable to provide a suitable fix, mostly because I'm not sure which part
of the code is actually the cause of the problem; that and and lack of
familiarity with the merge algorithm (is there one?) and code.
I have finally been able to reproduce this problem with a minimal
test-case. I will include the output below that can trigger the problem.
I've added some additional uncommitted debug code to Fossil to help
understand what's happening; basically just output the fv table after
each modification to it. I believe the problem happens because the same
file is attempted to be added to the vfile table due to failure to
detect that there was a rename.
In the debug, you'll notice that Fossil first adds in renames for fn,
and there are none, so there is no output. Then it adds in renames for
fnp (Pivot) and there are some but none that get added to fv. Then it
adds in renames for fnm (Merge) and finally there is an entry in the fv
table for a change from the name pivot (N) to the merge version (M).
afile is recorded as renamed to Afile due to the merge.
Next, Fossil starts adding in files from the checkout version (V) and
another row is added to the fv table for the rename. Should it have
updated the existing entry in fv? Or should it be handled later on with
the rest of the code that checks for various renames?
Moving on...
After adding files from V, both row 1 and row 2 in fv that represent
changes to Afile. Adding in files from P updates both rows 1 and 2.
Adding in files from M doesn't alter row 1 or 2, but does update row 3
(un unrelated file). No further modifications are made to fv and in the
end, when Fossil begins updating the vfile table, it ends up trying to
insert the same filename twice but for different reasons.
I've tried what I thought would be an appropriate fix, but there were a
handful of failures in merge5, merge_renames and one in merge_exe, so
either it was the wrong fix, or the tests are biased towards incorrect
behavior.
Here is the enhanced merge debug output:
$ /tmp/fossil merge --debug away
N=3 0e060d1e500398f692088acff2981a1ea57b1bde
P=19 ed49365cd035e7eaadf99ba315bf211e75a915b6
M=21 48a07754f9c0bcbe0d4408e9a83c976ae74c8b85
V=19 ed49365cd035e7eaadf99ba315bf211e75a915b6
add_renames for fn
add_renames for fnp
N->M at 14> 4386173c7f: 2[afile] -> 0[]
N->M at 14> 4386173c7f: 2[afile] -> 3[Afile]
N->M summary 2[afile] -> 3[Afile]
add_renames for fnm
1: ridv=0 ridp=0 ridm=0 idv=0 idp=0 idm=0 chnged=0 isexe=0
islinkv=0 islinkm=0
fn = []
fnp = []
fnm = [Afile]
fnn = [afile]
add files found in V
1: ridv=0 ridp=0 ridm=0 idv=0 idp=0 idm=0 chnged=0 isexe=0
islinkv=0 islinkm=0
fn = [afile]
fnp = []
fnm = [Afile]
fnn = [afile]
2: ridv=12 ridp=0 ridm=0 idv=9 idp=0 idm=0 chnged=0 isexe=0
islinkv=0 islinkm=0
fn = [Afile]
fnp = []
fnm = []
fnn = []
3: ridv=18 ridp=0 ridm=0 idv=10 idp=0 idm=0 chnged=0 isexe=0
islinkv=0 islinkm=0
fn = [file]
fnp = []
fnm = []
fnn = []
add files found in P
1: ridv=0 ridp=0 ridm=0 idv=0 idp=0 idm=0 chnged=0 isexe=0
islinkv=0 islinkm=0
fn = [afile]
fnp = [afile]
fnm = [Afile]
fnn = [afile]
2: ridv=12 ridp=0 ridm=0 idv=9 idp=0 idm=0 chnged=0 isexe=0
islinkv=0 islinkm=0
fn = [Afile]
fnp = [Afile]
fnm = []
fnn = []
3: ridv=18 ridp=0 ridm=0 idv=10 idp=0 idm=0 chnged=0 isexe=0
islinkv=0 islinkm=0
fn = [file]
fnp = [file]
fnm = []
fnn = []
add files found in M
1: ridv=0 ridp=0 ridm=0 idv=0 idp=0 idm=0 chnged=0 isexe=0
islinkv=0 islinkm=0
fn = [afile]
fnp = [afile]
fnm = [Afile]
fnn = [afile]
2: ridv=12 ridp=0 ridm=0 idv=9 idp=0 idm=0 chnged=0 isexe=0
islinkv=0 islinkm=0
fn = [Afile]
fnp = [Afile]
fnm = []
fnn = []
3: ridv=18 ridp=0 ridm=0 idv=10 idp=0 idm=0 chnged=0 isexe=0
islinkv=0 islinkm=0
fn = [file]
fnp = [file]
fnm = [file]
fnn = []
compute file version ids for P and M
1: ridv=0 ridp=0 ridm=0 idv=0 idp=0 idm=0 chnged=0 isexe=0
islinkv=0 islinkm=0
fn = [afile]
fnp = [afile]
fnm = [Afile]
fnn = [afile]
2: ridv=12 ridp=12 ridm=0 idv=9 idp=9 idm=0 chnged=0 isexe=0
islinkv=0 islinkm=0
fn = [Afile]
fnp = [Afile]
fnm = []
fnn = []
3: ridv=18 ridp=18 ridm=0 idv=10 idp=10 idm=0 chnged=0 isexe=0
islinkv=0 islinkm=0
fn = [file]
fnp = [file]
fnm = [file]
fnn = []
Final fv table
1: ridv=0 ridp=0 ridm=12 idv=0 idp=0 idm=11 chnged=0 isexe=0
islinkv=0 islinkm=0
fn = [afile]
fnp = [afile]
fnm = [Afile]
fnn = [afile]
2: ridv=12 ridp=12 ridm=0 idv=9 idp=9 idm=0 chnged=0 isexe=0
islinkv=0 islinkm=0
fn = [Afile]
fnp = [Afile]
fnm = []
fnn = []
3: ridv=18 ridp=18 ridm=20 idv=10 idp=10 idm=12 chnged=0 isexe=0
islinkv=0 islinkm=0
fn = [file]
fnp = [file]
fnm = [file]
fnn = []
UPDATE file
DELETE Afile
SQLITE_CONSTRAINT: abort at 41 in [INSERT INTO
vfile(vid,chnged,deleted,rid,mrid,isexe,islink,pathname) SELECT
19,3,0,rid,mrid,isexe,islink,pathname FROM vfile WHERE id=11]: UNIQUE
constraint failed: vfile.pathname, vfile.vid
/tmp/fossil: UNIQUE constraint failed: vfile.pathname, vfile.vid: {INSERT INTO
vfile(vid,chnged,deleted,rid,mrid,isexe,islink,pathname) SELECT
19,3,0,rid,mrid,isexe,islink,pathname FROM vfile WHERE id=11}
Rolling back prior filesystem changes...
UNDO file
NEW Afile
Finally, here is the actual output which generated that Fossil and a
link to a running copy of it:
http://fossil.bradfords.org:8080/
$ fossil new trial.fossil
project-id: 9e366debcee01098f3222ac070f7d1a3405c7ede
server-id: 4f97c2b2117caf2df2b5b74f013c35ce7947643f
admin-user: amb (initial password is "eeffcc")
$ mkdir trial; cd trial; fossil open ../trial.fossil
project-name: <unnamed>
repository: /tmp/trial/../trial.fossil
local-root: /tmp/trial/
config-db: /home/amb/.fossil
project-code: 9e366debcee01098f3222ac070f7d1a3405c7ede
checkout: ad537de4b083bbbd8b68f3f6e39a66b86f12569c 2016-11-08 06:01:57 UTC
tags: trunk
comment: initial empty check-in (user: amb)
check-ins: 1
$ echo $RANDOM > file
$ fossil add file; fossil ci -m start
ADDED file
New_Version: 0e060d1e500398f692088acff2981a1ea57b1bde
$ echo $RANDOM > file
$ fossil ci -m split --branch away
New_Version: 9e5cf03ad3df7715e4b924748c684a2c7b211dfc
$ echo $RANDOM >> file
$ fossil ci -m ready
New_Version: f79038314ef61389e4a835b33b9e66349775da10
$ fossil up trunk
UPDATE file
-------------------------------------------------------------------------------
updated-to: 0e060d1e500398f692088acff2981a1ea57b1bde 2016-11-08 06:02:10 UTC
tags: trunk
comment: start (user: amb)
changes: 1 file modified.
"fossil undo" is available to undo changes to the working checkout.
$ echo $RANDOM >> file
$ fossil ci -m aim
New_Version: b8b28ac61c2d99f2943a770bd226b3a06769b974
$ fossil up away
UPDATE file
-------------------------------------------------------------------------------
updated-to: f79038314ef61389e4a835b33b9e66349775da10 2016-11-08 06:02:24 UTC
tags: away
comment: ready (user: amb)
changes: 1 file modified.
"fossil undo" is available to undo changes to the working checkout.
$ fossil merge trunk
MERGE file
"fossil undo" is available to undo changes to the working checkout.
$ fossil ci -m fire
New_Version: d8b1e949c521ca0eabe674426b772e4c805f9572
$ echo $RANDOM > afile
$ fossil add afile; fossil ci -m newfile
ADDED afile
New_Version: 254f76f43e0f72ca6d26a3f02b707426228f700d
$ fossil mv --hard afile Afile
RENAME afile Afile
MOVED_FILE /tmp/trial/afile
$ fossil ci -m renamed
New_Version: 4386173c7f2e2853d4dca7c10cc7e4c8e5a162ac
$ fossil up trunk
REMOVE Afile
UPDATE file
-------------------------------------------------------------------------------
updated-to: b8b28ac61c2d99f2943a770bd226b3a06769b974 2016-11-08 06:02:34 UTC
tags: trunk
comment: aim (user: amb)
changes: 2 files modified.
"fossil undo" is available to undo changes to the working checkout.
$ fossil merge away
UPDATE file
ADDED Afile
"fossil undo" is available to undo changes to the working checkout.
$ fossil ci -m bring
New_Version: ecce9dc98a30421c801783db7dd9ccf2f64b0927
$ fossil up away
-------------------------------------------------------------------------------
checkout: 4386173c7f2e2853d4dca7c10cc7e4c8e5a162ac 2016-11-08 06:03:02 UTC
tags: away
comment: renamed (user: amb)
changes: None. Already up-to-date
$ ed -s file <<EOF
> i
> $RANDOM
> .
> w
> q
> EOF
$ fossil ci -m forth
New_Version: 8beed199505d4d5cd79ba841b641c71071f56694
$ fossil up trunk
UPDATE file
-------------------------------------------------------------------------------
updated-to: ecce9dc98a30421c801783db7dd9ccf2f64b0927 2016-11-08 06:03:24 UTC
tags: trunk
comment: bring (user: amb)
changes: 1 file modified.
"fossil undo" is available to undo changes to the working checkout.
$ echo $RANDOM >> file
$ fossil ci -m the
New_Version: ed49365cd035e7eaadf99ba315bf211e75a915b6
$ fossil up away
UPDATE file
-------------------------------------------------------------------------------
updated-to: 8beed199505d4d5cd79ba841b641c71071f56694 2016-11-08 06:04:46 UTC
tags: away
comment: forth (user: amb)
changes: 1 file modified.
"fossil undo" is available to undo changes to the working checkout.
$ fossil merge trunk
MERGE file
"fossil undo" is available to undo changes to the working checkout.
$ fossil ci -m rain
New_Version: 48a07754f9c0bcbe0d4408e9a83c976ae74c8b85
$ fossil up trunk
UPDATE file
-------------------------------------------------------------------------------
updated-to: ed49365cd035e7eaadf99ba315bf211e75a915b6 2016-11-08 06:05:04 UTC
tags: trunk
comment: the (user: amb)
changes: 1 file modified.
"fossil undo" is available to undo changes to the working checkout.
$ fossil merge away
UPDATE file
DELETE Afile
SQLITE_CONSTRAINT: abort at 41 in [INSERT INTO
vfile(vid,chnged,deleted,rid,mrid,isexe,islink,pathname) SELECT
19,3,0,rid,mrid,isexe,islink,pathname FROM vfile WHERE id=17]: UNIQUE
constraint failed: vfile.pathname, vfile.vid
fossil: UNIQUE constraint failed: vfile.pathname, vfile.vid: {INSERT INTO
vfile(vid,chnged,deleted,rid,mrid,isexe,islink,pathname) SELECT
19,3,0,rid,mrid,isexe,islink,pathname FROM vfile WHERE id=17}
Rolling back prior filesystem changes...
UNDO file
NEW Afile
$ fossil up ecce9dc98a30421c801783db7dd9ccf2f64b0927
UPDATE file
-------------------------------------------------------------------------------
updated-to: ecce9dc98a30421c801783db7dd9ccf2f64b0927 2016-11-08 06:03:24 UTC
tags: trunk
comment: bring (user: amb)
changes: 1 file modified.
"fossil undo" is available to undo changes to the working checkout.
$ fossil merge 8beed199505d4d5cd79ba841b641c71071f56694
UPDATE file
"fossil undo" is available to undo changes to the working checkout.
$ fossil revert
REVERT file
"fossil undo" is available to undo changes to the working checkout.
$ fossil merge away
UPDATE file
DELETE Afile
SQLITE_CONSTRAINT: abort at 41 in [INSERT INTO
vfile(vid,chnged,deleted,rid,mrid,isexe,islink,pathname) SELECT
15,3,0,rid,mrid,isexe,islink,pathname FROM vfile WHERE id=19]: UNIQUE
constraint failed: vfile.pathname, vfile.vid
fossil: UNIQUE constraint failed: vfile.pathname, vfile.vid: {INSERT INTO
vfile(vid,chnged,deleted,rid,mrid,isexe,islink,pathname) SELECT
15,3,0,rid,mrid,isexe,islink,pathname FROM vfile WHERE id=19}
Rolling back prior filesystem changes...
UNDO file
NEW Afile
$
Thoughts?
Thanks,
Andy
--
TAI64 timestamp: 4000000058263ece
_______________________________________________
fossil-dev mailing list
[email protected]
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/fossil-dev