代码之家  ›  专栏  ›  技术社区  ›  Gunther Schadow

svn:E000002:提交后无法创建符号链接,svn清理失败,如何恢复?

  •  0
  • Gunther Schadow  · 技术社区  · 5 年前

    我添加并提交了两个符号链接到有意不提交的文件,它们是指向不应该提交到svn的安全凭据。

    # svn add submit.cer submit.pkey
    A         submit.cer
    A         submit.pkey
    
    # svn commit submit.sh submit.cer submit.pkey -m "..."
    Sending        submit.sh
    Adding         submit.cer
    Adding         submit.pkey
    Transmitting file data ...
    Committed revision 19433.
    svn: E200000: Commit succeeded, but other errors follow:
    svn: E000002: Error bumping revisions post-commit (details follow):
    svn: E000002: Can't create symbolic link '/home/foobar/proj/.svn/tmp/svn-PvrkP3.tmp': No such file or directory
    
    # svn status
    svn: E155037: Previous operation has not finished; run 'cleanup' if it was interrupted
    
    # svn cleanup
    svn: E000002: Can't create symbolic link '/home/foobar/proj/.svn/tmp/svn-qckOhQ.tmp': No such file or directory
    

    我怎样才能从中恢复过来?

    0 回复  |  直到 5 年前
        1
  •  0
  •   Gunther Schadow    5 年前

    这可能不是最好的答案,但我已经暂时解决了我的问题,只需打开引擎盖,弄脏双手。以下是我所做的:

    我试图创建这些缺失的文件,但它只要求创建其他文件:

    # svn status
    svn: E155037: Previous operation has not finished; run 'cleanup' if it was interrupted
    # touch /home/foobar/proj/.svn/tmp/svn-I03qQS.tmp
    # svn status
    svn: E155037: Previous operation has not finished; run 'cleanup' if it was interrupted
    # svn cleanup
    svn: E000002: Can't create symbolic link '/home/foobar/proj/.svn/tmp/svn-lYugyl.tmp': No such file or directory
    # touch /home/foobar/proj/.svn/tmp/svn-lYugyl.tmp
    # svn cleanup
    svn: E000002: Can't create symbolic link '/home/foobar/proj/.svn/tmp/svn-3exWGo.tmp': No such file or directory
    # touch /home/foobar/proj/.svn/tmp/svn-3exWGo.tmp
    # svn cleanup
    svn: E000002: Can't create symbolic link '/home/foobar/proj/.svn/tmp/svn-TSibma.tmp': No such file or directory
    

    这是svn的旧版本,2012年的版本1.7.4(r1295709),但我比现在尝试升级更清楚。

    让我们看看我能用wc.db做什么

    # sqlite3 wc.db .dump |egrep 'submit.(cer|pkey)'
    INSERT INTO "NODES" VALUES(1,'submit.cer',0,'',1,'proj/submit.cer',19433,'normal',NULL,NULL,'file',X'2873766E3A7370656369616C2031202A29',NULL,'$sha1$115f82f76a709733e88d9f26a7a5f01a47953401',NULL,19433,1579098137216132,'foobar',NULL,NULL,X'2873766E3A77633A72615F6461763A76657273696F6E2D75726C203337202F69722F73766E2F2173766E2F7665722F31393433332F8888882F7375626D69742E63657229',NULL);
    INSERT INTO "NODES" VALUES(1,'submit.pkey',0,'',1,'proj/submit.pkey',19433,'normal',NULL,NULL,'file',X'2873766E3A7370656369616C2031202A29',NULL,'$sha1$99747e06d352668bf515639d0a6ec3dbf86cc1ff',NULL,19433,1579098137216132,'foobar',NULL,NULL,X'2873766E3A77633A72615F6461763A76657273696F6E2D75726C203338202F69722F73766E2F2173766E2F7665722F31393433332F68888882F7375626D69742E706B657929',NULL);
    

    那是什么?

    # sqlite3 wc.db '.schema NODES'
    CREATE TABLE NODES (
       wc_id  INTEGER NOT NULL REFERENCES WCROOT (id),
       local_relpath  TEXT NOT NULL,
       op_depth INTEGER NOT NULL,
       parent_relpath  TEXT,
       repos_id  INTEGER REFERENCES REPOSITORY (id),
       repos_path  TEXT,
       revision  INTEGER,
       presence  TEXT NOT NULL, 
       moved_here  INTEGER,
       moved_to  TEXT,
       kind  TEXT NOT NULL,
       properties  BLOB,
       depth  TEXT,
       checksum  TEXT REFERENCES PRISTINE (checksum),
       symlink_target  TEXT,
       changed_revision  INTEGER,
       changed_date      INTEGER,
       changed_author    TEXT,
       translated_size  INTEGER,
       last_mod_time  INTEGER,
       dav_cache  BLOB,
       file_external  TEXT,
       PRIMARY KEY (wc_id, local_relpath, op_depth)
    );
    

    这里有趣的事情:symlink_target

    sqlite3 wc.db "SELECT symlink_target,NULL,'' FROM NODES WHERE local_relpath = 'submit.cer'"
    ||
    

    因此符号链接目标为NULL,这很可能是导致它失败的原因。不幸的是,我没有可以检查这个的情况:

    sqlite3 wc.db "SELECT local_relpath,symlink_target FROM NODES WHERE symlink_target IS NOT NULL"
    

    没有什么。

    那么,如果我删除这两个节点呢?

    # sqlite3 wc.db "CREATE TABLE BADNODES AS SELECT * FROM NODES WHERE local_relpath IN ('submit.cer', 'submit.pkey')"
    # sqlite3 wc.db "SELECT * FROM BADNODES"
    1|submit.cer|0||1|proj/submit.cer|19433|normal|||file|(svn:special 1 *)||$sha1$a15f82f76a709733e88d9f26a7a5f01a47953401||19433|1579098137216132|foobar|||(svn:wc:ra_dav:version-url 37 /ir/svn/!svn/ver/19433/proj/submit.cer)|
    1|submit.pkey|0||1|proj/submit.pkey|19433|normal|||file|(svn:special 1 *)||$sha1$a9747e06d352668bf515639d0a6ec3dbf86cc1ff||19433|1579098137216132|foobar|||(svn:wc:ra_dav:version-url 38 /ir/svn/!svn/ver/19433/proj/submit.pkey)|
    # sqlite3 wc.db "DELETE FROM NODES WHERE local_relpath IN ('submit.cer', 'submit.pkey')"
    # cd ..
    # svn cleanup
    svn: E155010: The node '/home/foobar/submit.cer' was not found.
    

    所以现在它仍然有一些关于顺从的东西。但从哪里来的?不在数据库中。

    # sqlite3 wc.db .dump |fgrep submit.cer |fgrep -v BADNODES
    # find . -name 'submit.cer'
    # fgrep -Rl submit.cer .
    ./pristine/2a/2a5fe860af1b54b5b63978176e345b2d6cf57e01.svn-base
    ./wc.db
    

    啊哈,这么原始的东西。但这是转移注意力,这个原始文件只是我提交的另一个文件submit.sh,它的文本中包含submit.cer,所以svn不会知道。怎么办 svn cleanup 甚至知道应该有一个名为submit.cer的东西?

    它不能从具有以下值的列中获得此值:

    (svn:wc:ra_dav:version-url 38 /ir/svn/!svn/ver/19433/proj/submit.cer)
    

    这是从列

    dav_cache  BLOB,
    

    值为:

    X'2873766E3A77633A72615F6461763A76657273696F6E2D75726C203337202F69722F73766E2F2173766E2F7665722F31393433332F8888882F7375626D69742E63657229'
    

    因此,我最好搜索所有BLOB列,无论它们是否提到submit.cer文件。这并不难,

    # echo "submit.cer" |od -t x1
    0000000 73 75 62 6d 69 74 2e 63 65 72 0a
    0000013
    

    所以我可以搜索:

    # sqlite3 wc.db .dump |fgrep 7375626D69742E636572
    INSERT INTO "WORK_QUEUE" VALUES(209,X'2866696C652D636F6D6D6974207375626D69742E636572203120302031203029');
    INSERT INTO "BADNODES" VALUES(1,'submit.cer',0,'',1,'proj/submit.cer',19433,'normal',NULL,NULL,'file',X'2873766E3A7370656369616C2031202A29',NULL,'$sha1$115f82f76a709733e88d9f26a7a5f01a47953401',NULL,19433,1579098137216132,'gschadow',NULL,NULL,X'2873766E3A77633A72615F6461763A76657273696F6E2D75726C203337202F69722F73766E2F2173766E2F7665722F31393433332F8888882F7375626D69742E63657229',NULL);
    

    所以,我来了,那个工作队列!

    # sqlite3 wc.db '.schema WORK_QUEUE'
    CREATE TABLE WORK_QUEUE (
       id  INTEGER PRIMARY KEY AUTOINCREMENT,
       work  BLOB NOT NULL
    );
    
    # sqlite3 wc.db 'select * from WORK_QUEUE'
    209|(file-commit submit.cer 1 0 1 0)
    210|(file-commit submit.pkey 1 0 1 0)
    

    不错!那么,如果我把这些从工作队列中移出呢?

    # sqlite3 wc.db 'CREATE TABLE BAD_WORK_QUEUE AS SELECT * FROM WORK_QUEUE'
    # sqlite3 wc.db 'DELETE FROM WORK_QUEUE'
    

    现在是塔达!

    # cd ..
    # svn cleanup
    # svn status |fgrep submit
    ?       submit.cer
    ?       submit.pkey
    

    这看起来真的很有希望,就好像坏链接从未被提交过一样?我们试试吧?哎呀:

    # svn update
    Updating '.':
       C submit.pkey
       C submit.cer
    Updated to revision 19433.
    Summary of conflicts:
      Tree conflicts: 2
    

    但随后,神奇地:

    # svn update
    Updating '.':
    At revision 19433.
    
    # svn status |fgrep submit
    D     C submit.cer
    D     C submit.pkey
    

    太棒了!所以我可以继续我的工作,只是再也不会提交这些符号链接了。

    现在的教训是:在不提交目标的情况下,永远不要提交符号链接!?