Fossil

Check-in [c18f2319]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add the -u/--unversioned flag to the "fossil sync" command. Implement the "fossil unversioned revert" command.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: c18f23190a109b580b55ceb31239f7871013e415
User & Date: drh 2016-08-17 22:19:00
Context
2016-08-18
01:01
Update custom MinGW makefile. check-in: 638536e9 user: mistachkin tags: trunk
2016-08-17
22:19
Add the -u/--unversioned flag to the "fossil sync" command. Implement the "fossil unversioned revert" command. check-in: c18f2319 user: drh tags: trunk
17:25
Send the parent-project-name and parent-project-code configurations when syncing the project configurations. check-in: 08e65c2b user: drh tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/sync.c.

139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
...
297
298
299
300
301
302
303

304
305
306
307
308
309
310
311
312



313
314
315
316
317
318
319
320
321
322
323
324
325
326

327
328
329
330

331
332
333
334
335
336
337
    /* The --verily option to sync, push, and pull forces extra igot cards
    ** to be exchanged.  This can overcome malfunctions in the sync protocol.
    */
    if( find_option("verily",0,0)!=0 ){
      *pSyncFlags |= SYNC_RESYNC;
    }
  }
  if( find_option("uv",0,0)!=0 ){
    *pSyncFlags |= SYNC_UNVERSIONED;
  }
  if( find_option("private",0,0)!=0 ){
    *pSyncFlags |= SYNC_PRIVATE;
  }
  if( find_option("verbose","v",0)!=0 ){
    *pSyncFlags |= SYNC_VERBOSE;
  }
  url_proxy_options();
................................................................................
**   --ipv4                     Use only IPv4, not IPv6
**   --once                     Do not remember URL for subsequent syncs
**   --proxy PROXY              Use the specified HTTP proxy
**   --private                  Sync private branches too
**   -R|--repository REPO       Repository to pull into
**   --ssl-identity FILE        Local SSL credentials, if requested by remote
**   --ssh-command SSH          Use SSH as the "ssh" command

**   -v|--verbose               Additional (debugging) output
**   --verily                   Exchange extra information with the remote
**                              to ensure no content is overlooked
**
** See also: clone, pull, push, remote-url
*/
void sync_cmd(void){
  unsigned configFlags = 0;
  unsigned syncFlags = SYNC_PUSH|SYNC_PULL;



  process_sync_args(&configFlags, &syncFlags, 0);

  /* We should be done with options.. */
  verify_all_options();

  if( db_get_boolean("dont-push",0) ) syncFlags &= ~SYNC_PUSH;
  client_sync(syncFlags, configFlags, 0);
  if( (syncFlags & SYNC_PUSH)==0 ){
    fossil_warning("pull only: the 'dont-push' option is set");
  }
}

/*
** Handle the "fossil unversioned sync" command.

*/
void sync_unversioned(void){
  unsigned configFlags = 0;
  unsigned syncFlags = SYNC_UNVERSIONED;

  process_sync_args(&configFlags, &syncFlags, 1);
  verify_all_options();
  client_sync(syncFlags, 0, 0);
}

/*
** COMMAND: remote-url







<
<
<







 







>









>
>
>













|
>

|

<
>







139
140
141
142
143
144
145



146
147
148
149
150
151
152
...
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331

332
333
334
335
336
337
338
339
    /* The --verily option to sync, push, and pull forces extra igot cards
    ** to be exchanged.  This can overcome malfunctions in the sync protocol.
    */
    if( find_option("verily",0,0)!=0 ){
      *pSyncFlags |= SYNC_RESYNC;
    }
  }



  if( find_option("private",0,0)!=0 ){
    *pSyncFlags |= SYNC_PRIVATE;
  }
  if( find_option("verbose","v",0)!=0 ){
    *pSyncFlags |= SYNC_VERBOSE;
  }
  url_proxy_options();
................................................................................
**   --ipv4                     Use only IPv4, not IPv6
**   --once                     Do not remember URL for subsequent syncs
**   --proxy PROXY              Use the specified HTTP proxy
**   --private                  Sync private branches too
**   -R|--repository REPO       Repository to pull into
**   --ssl-identity FILE        Local SSL credentials, if requested by remote
**   --ssh-command SSH          Use SSH as the "ssh" command
**   -u|--unversioned           Also sync unversioned content
**   -v|--verbose               Additional (debugging) output
**   --verily                   Exchange extra information with the remote
**                              to ensure no content is overlooked
**
** See also: clone, pull, push, remote-url
*/
void sync_cmd(void){
  unsigned configFlags = 0;
  unsigned syncFlags = SYNC_PUSH|SYNC_PULL;
  if( find_option("unversioned","u",0)!=0 ){
    syncFlags |= SYNC_UNVERSIONED;
  }
  process_sync_args(&configFlags, &syncFlags, 0);

  /* We should be done with options.. */
  verify_all_options();

  if( db_get_boolean("dont-push",0) ) syncFlags &= ~SYNC_PUSH;
  client_sync(syncFlags, configFlags, 0);
  if( (syncFlags & SYNC_PUSH)==0 ){
    fossil_warning("pull only: the 'dont-push' option is set");
  }
}

/*
** Handle the "fossil unversioned sync" and "fossil unversioned revert"
** commands.
*/
void sync_unversioned(unsigned syncFlags){
  unsigned configFlags = 0;

  (void)find_option("uv-noop",0,0);
  process_sync_args(&configFlags, &syncFlags, 1);
  verify_all_options();
  client_sync(syncFlags, 0, 0);
}

/*
** COMMAND: remote-url

Changes to src/unversioned.c.

307
308
309
310
311
312
313
314


315
316
317
318
319
320
321
...
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
           db_column_text(&q,4),
           zNoContent
        );
      }
    }
    db_finalize(&q);
  }else if( memcmp(zCmd, "revert", nCmd)==0 ){
    fossil_fatal("not yet implemented...");


  }else if( memcmp(zCmd, "rm", nCmd)==0 ){
    int i;
    verify_all_options();
    db_begin_transaction();
    for(i=3; i<g.argc; i++){
      db_multi_exec(
        "UPDATE unversioned"
................................................................................
        mtime, g.argv[i]
      );
    }
    db_unset("uv-hash", 0);
    db_end_transaction(0);
  }else if( memcmp(zCmd,"sync",nCmd)==0 ){
    g.argv[1] = "sync";
    g.argv[2] = "--uv";
    sync_unversioned();
  }else if( memcmp(zCmd, "touch", nCmd)==0 ){
    int i;
    verify_all_options();
    db_begin_transaction();
    for(i=3; i<g.argc; i++){
      db_multi_exec(
        "UPDATE unversioned SET mtime=%lld WHERE name=%Q",







|
>
>







 







|
|







307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
...
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
           db_column_text(&q,4),
           zNoContent
        );
      }
    }
    db_finalize(&q);
  }else if( memcmp(zCmd, "revert", nCmd)==0 ){
    g.argv[1] = "sync";
    g.argv[2] = "--uv-noop";
    sync_unversioned(SYNC_UNVERSIONED|SYNC_UV_REVERT);
  }else if( memcmp(zCmd, "rm", nCmd)==0 ){
    int i;
    verify_all_options();
    db_begin_transaction();
    for(i=3; i<g.argc; i++){
      db_multi_exec(
        "UPDATE unversioned"
................................................................................
        mtime, g.argv[i]
      );
    }
    db_unset("uv-hash", 0);
    db_end_transaction(0);
  }else if( memcmp(zCmd,"sync",nCmd)==0 ){
    g.argv[1] = "sync";
    g.argv[2] = "--uv-noop";
    sync_unversioned(SYNC_UNVERSIONED);
  }else if( memcmp(zCmd, "touch", nCmd)==0 ){
    int i;
    verify_all_options();
    db_begin_transaction();
    for(i=3; i<g.argc; i++){
      db_multi_exec(
        "UPDATE unversioned SET mtime=%lld WHERE name=%Q",

Changes to src/xfer.c.

1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655

1656
1657
1658
1659
1660
1661
1662
1663
....
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
....
1875
1876
1877
1878
1879
1880
1881



1882
1883
1884
1885
1886
1887










1888
1889
1890
1891
1892
1893
1894



1895
1896
1897
1898

1899
1900
1901
1902
1903
1904
1905
....
2014
2015
2016
2017
2018
2019
2020




2021
2022
2023
2024
2025
2026
2027
....
2087
2088
2089
2090
2091
2092
2093

2094
2095
2096
2097
2098
2099
2100
....
2227
2228
2229
2230
2231
2232
2233

2234
2235
2236
2237
2238
2239
2240
static const char zBriefFormat[] =
   "Round-trips: %d   Artifacts sent: %d  received: %d\r";

#if INTERFACE
/*
** Flag options for controlling client_sync()
*/
#define SYNC_PUSH           0x0001
#define SYNC_PULL           0x0002
#define SYNC_CLONE          0x0004
#define SYNC_PRIVATE        0x0008
#define SYNC_VERBOSE        0x0010
#define SYNC_RESYNC         0x0020
#define SYNC_UNVERSIONED    0x0040

#define SYNC_FROMPARENT     0x0080
#endif

/*
** Floating-point absolute value
*/
static double fossil_fabs(double x){
  return x>0.0 ? x : -x;
................................................................................
  if( syncFlags & SYNC_PRIVATE ){
    blob_append(&send, "pragma send-private\n", -1);
  }

  /* When syncing unversioned files, create a TEMP table in which to store
  ** the names of files that do not need to be sent from client to server.
  */
  if( syncFlags & SYNC_UNVERSIONED ){
    db_multi_exec(
       "CREATE TEMP TABLE uv_tosend("
       "  name TEXT PRIMARY KEY,"
       "  mtimeOnly BOOLEAN"
       ") WITHOUT ROWID;"
       "INSERT INTO uv_toSend(name,mtimeOnly)"
       "  SELECT name, 0 FROM unversioned WHERE hash IS NOT NULL;"
................................................................................
        nCardSent += configure_send_group(xfer.pOut, configSendMask, 0);
      }
      configSendMask = 0;
    }

    /* Send unversioned files present here on the client but missing or
    ** obsolete on the server.



    */
    if( uvDoPush ){
      Stmt uvq;
      int rc = SQLITE_OK;
      assert( (syncFlags & SYNC_UNVERSIONED)!=0 );
      assert( uvStatus==2 );










      db_prepare(&uvq, "SELECT name, mtimeOnly FROM uv_tosend");
      while( (rc = db_step(&uvq))==SQLITE_ROW ){
        const char *zName = db_column_text(&uvq, 0);
        send_unversioned_file(&xfer, zName, db_column_int(&uvq,1));
        nCardSent++;
        nArtifactSent++;
        db_multi_exec("DELETE FROM uv_tosend WHERE name=%Q", zName);



        if( blob_size(xfer.pOut)>xfer.mxSend ) break;
      }
      db_finalize(&uvq);
      if( rc==SQLITE_DONE ) uvDoPush = 0;

    }

    /* Append randomness to the end of the message.  This makes all
    ** messages unique so that that the login-card nonce will always
    ** be unique.
    */
    zRandomness = db_text(0, "SELECT hex(randomblob(20))");
................................................................................
      **
      ** Accept an unversioned file from the client.
      */
      if( blob_eq(&xfer.aToken[0], "uvfile") ){
        xfer_accept_unversioned_file(&xfer, 1);
        nArtifactRcvd++;
        nUvFileRcvd++;




      }else

      /*   gimme UUID
      **
      ** Server is requesting a file.  If the file is a manifest, assume
      ** that the server will also want to know all of the content files
      ** associated with the manifest and send those too.
................................................................................
       && (blob_eq(&xfer.aToken[3],"-") || blob_is_uuid(&xfer.aToken[3]))
      ){
        const char *zName = blob_str(&xfer.aToken[1]);
        const char *zHash = blob_str(&xfer.aToken[3]);
        int iStatus;
        if( uvStatus==0 ) uvStatus = 2;
        iStatus = unversioned_status(zName, mtime, zHash);

        if( iStatus<=1 ){
          if( zHash[0]!='-' ){
            blob_appendf(xfer.pOut, "uvgimme %s\n", zName);
            nCardSent++;
            nUvGimmeSent++;
          }else if( iStatus==1 ){
            db_multi_exec(
................................................................................
        ** this client lacks the necessary permissions) then it sends a
        ** "uv-pull-only" pragma so that the client will know not to waste
        ** bandwidth trying to upload unversioned content.  If the server
        ** does accept new unversioned content, it sends "uv-push-ok".
        */
        if( blob_eq(&xfer.aToken[1], "uv-pull-only") ){
          uvStatus = 1;

        }else if( blob_eq(&xfer.aToken[1], "uv-push-ok") ){
          uvStatus = 2;
          uvDoPush = 1;
        }
      }else

      /*   error MESSAGE







|
|
|
|
|
|
|
>
|







 







|







 







>
>
>


<
<


>
>
>
>
>
>
>
>
>
>
|
|
|
|
|
|
|
>
>
>
|
|
|
|
>







 







>
>
>
>







 







>







 







>







1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
....
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
....
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887


1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
....
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
....
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
....
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
static const char zBriefFormat[] =
   "Round-trips: %d   Artifacts sent: %d  received: %d\r";

#if INTERFACE
/*
** Flag options for controlling client_sync()
*/
#define SYNC_PUSH           0x0001    /* push content client to server */
#define SYNC_PULL           0x0002    /* pull content server to client */
#define SYNC_CLONE          0x0004    /* clone the repository */
#define SYNC_PRIVATE        0x0008    /* Also transfer private content */
#define SYNC_VERBOSE        0x0010    /* Extra diagnostics */
#define SYNC_RESYNC         0x0020    /* --verily */
#define SYNC_UNVERSIONED    0x0040    /* Sync unversioned content */
#define SYNC_UV_REVERT      0x0080    /* Copy server unversioned to client */
#define SYNC_FROMPARENT     0x0100    /* Pull from the parent project */
#endif

/*
** Floating-point absolute value
*/
static double fossil_fabs(double x){
  return x>0.0 ? x : -x;
................................................................................
  if( syncFlags & SYNC_PRIVATE ){
    blob_append(&send, "pragma send-private\n", -1);
  }

  /* When syncing unversioned files, create a TEMP table in which to store
  ** the names of files that do not need to be sent from client to server.
  */
  if( (syncFlags & SYNC_UNVERSIONED)!=0 ){
    db_multi_exec(
       "CREATE TEMP TABLE uv_tosend("
       "  name TEXT PRIMARY KEY,"
       "  mtimeOnly BOOLEAN"
       ") WITHOUT ROWID;"
       "INSERT INTO uv_toSend(name,mtimeOnly)"
       "  SELECT name, 0 FROM unversioned WHERE hash IS NOT NULL;"
................................................................................
        nCardSent += configure_send_group(xfer.pOut, configSendMask, 0);
      }
      configSendMask = 0;
    }

    /* Send unversioned files present here on the client but missing or
    ** obsolete on the server.
    **
    ** Or, if the SYNC_UV_REVERT flag is set, delete the local unversioned
    ** files that do not exist on the server.
    */
    if( uvDoPush ){


      assert( (syncFlags & SYNC_UNVERSIONED)!=0 );
      assert( uvStatus==2 );
      if( syncFlags & SYNC_UV_REVERT ){
        db_multi_exec(
          "DELETE FROM unversioned"
          " WHERE name IN (SELECT name FROM uv_tosend);"
          "DELETE FROM uv_tosend;"
        );
        uvDoPush = 0;
      }else{
        Stmt uvq;
        int rc = SQLITE_OK;
        db_prepare(&uvq, "SELECT name, mtimeOnly FROM uv_tosend");
        while( (rc = db_step(&uvq))==SQLITE_ROW ){
          const char *zName = db_column_text(&uvq, 0);
          send_unversioned_file(&xfer, zName, db_column_int(&uvq,1));
          nCardSent++;
          nArtifactSent++;
          db_multi_exec("DELETE FROM uv_tosend WHERE name=%Q", zName);
          if( syncFlags & SYNC_VERBOSE ){
            fossil_print("\rUnversioned-file sent: %s\n", zName);
          }
          if( blob_size(xfer.pOut)>xfer.mxSend ) break;
        }
        db_finalize(&uvq);
        if( rc==SQLITE_DONE ) uvDoPush = 0;
      }
    }

    /* Append randomness to the end of the message.  This makes all
    ** messages unique so that that the login-card nonce will always
    ** be unique.
    */
    zRandomness = db_text(0, "SELECT hex(randomblob(20))");
................................................................................
      **
      ** Accept an unversioned file from the client.
      */
      if( blob_eq(&xfer.aToken[0], "uvfile") ){
        xfer_accept_unversioned_file(&xfer, 1);
        nArtifactRcvd++;
        nUvFileRcvd++;
        if( syncFlags & SYNC_VERBOSE ){
          fossil_print("\rUnversioned-file received: %s\n",
                       blob_str(&xfer.aToken[1]));
        }
      }else

      /*   gimme UUID
      **
      ** Server is requesting a file.  If the file is a manifest, assume
      ** that the server will also want to know all of the content files
      ** associated with the manifest and send those too.
................................................................................
       && (blob_eq(&xfer.aToken[3],"-") || blob_is_uuid(&xfer.aToken[3]))
      ){
        const char *zName = blob_str(&xfer.aToken[1]);
        const char *zHash = blob_str(&xfer.aToken[3]);
        int iStatus;
        if( uvStatus==0 ) uvStatus = 2;
        iStatus = unversioned_status(zName, mtime, zHash);
        if( (syncFlags & SYNC_UV_REVERT)!=0 && iStatus==4 ) iStatus = 2;
        if( iStatus<=1 ){
          if( zHash[0]!='-' ){
            blob_appendf(xfer.pOut, "uvgimme %s\n", zName);
            nCardSent++;
            nUvGimmeSent++;
          }else if( iStatus==1 ){
            db_multi_exec(
................................................................................
        ** this client lacks the necessary permissions) then it sends a
        ** "uv-pull-only" pragma so that the client will know not to waste
        ** bandwidth trying to upload unversioned content.  If the server
        ** does accept new unversioned content, it sends "uv-push-ok".
        */
        if( blob_eq(&xfer.aToken[1], "uv-pull-only") ){
          uvStatus = 1;
          if( syncFlags & SYNC_UV_REVERT ) uvDoPush = 1;
        }else if( blob_eq(&xfer.aToken[1], "uv-push-ok") ){
          uvStatus = 2;
          uvDoPush = 1;
        }
      }else

      /*   error MESSAGE