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 fossil-dev@mailinglists.sqlite.org http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/fossil-dev