Fossil

Check-in [6b410f91]
Login

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

Overview
Comment:Warn the client that pushes content which generates a fork on the server.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | sync-forkwarn
Files: files | file ages | folders
SHA1:6b410f914ef5be53f7a2afec6af893083e213eaa
User & Date: andybradford 2015-04-09 00:51:18
Context
2015-04-10
00:30
Add warnings to clients which receive content that creates a fork. Defer warnings as much as possible. check-in: 9d453193 user: andybradford tags: sync-forkwarn
2015-04-09
00:51
Warn the client that pushes content which generates a fork on the server. check-in: 6b410f91 user: andybradford tags: sync-forkwarn
2015-04-08
17:05
Improve some comments. No changes to code. check-in: 5a12e8c3 user: mistachkin tags: trunk
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to src/leaf.c.

71
72
73
74
75
76
77

















78
79
80
81
82
83
84
  if( db_step(&q)==SQLITE_ROW ){
    nNonBranch = db_column_int(&q, 0);
  }
  db_reset(&q);
  return nNonBranch;
}



















/*
** Recompute the entire LEAF table.
**
** This can be expensive (5 seconds or so) for a really large repository.
** So it is only done for things like a rebuild.
*/







>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
  if( db_step(&q)==SQLITE_ROW ){
    nNonBranch = db_column_int(&q, 0);
  }
  db_reset(&q);
  return nNonBranch;
}

/*
** Return the primary parent pid given a child rid
*/
int primary_parent_pid_from_rid(int rid){
  static Stmt q;
  int pid = -1;

  db_static_prepare(&q,
     "SELECT pid FROM plink WHERE cid=:rid AND pid>0 AND isprim"
  );
  db_bind_int(&q, ":rid", rid);
  if( db_step(&q)==SQLITE_ROW ){
    pid = db_column_int(&q, 0);
  }
  db_reset(&q);
  return pid;
}

/*
** Recompute the entire LEAF table.
**
** This can be expensive (5 seconds or so) for a really large repository.
** So it is only done for things like a rebuild.
*/

Changes to src/xfer.c.

45
46
47
48
49
50
51

52
53
54
55
56
57
58
...
200
201
202
203
204
205
206



207
208
209
210
211
212
213
...
275
276
277
278
279
280
281



282
283
284
285
286
287
288
...
975
976
977
978
979
980
981

982
983
984
985
986
987
988
...
992
993
994
995
996
997
998



999
1000
1001
1002
1003
1004
1005
....
1013
1014
1015
1016
1017
1018
1019



1020
1021
1022
1023
1024
1025
1026
  int nFileSent;      /* Number of files sent */
  int nDeltaSent;     /* Number of deltas sent */
  int nFileRcvd;      /* Number of files received */
  int nDeltaRcvd;     /* Number of deltas received */
  int nDanglingFile;  /* Number of dangling deltas received */
  int mxSend;         /* Stop sending "file" when pOut reaches this size */
  int resync;         /* Send igot cards for all holdings */

  u8 syncPrivate;     /* True to enable syncing private content */
  u8 nextIsPrivate;   /* If true, next "file" received is a private */
  time_t maxTime;     /* Time when this transfer should be finished */
};


/*
................................................................................
  blob_reset(&hash);
  if( rid==0 ){
    blob_appendf(&pXfer->err, "%s", g.zErrMsg);
    blob_reset(&content);
  }else{
    if( !isPriv ) content_make_public(rid);
    manifest_crosslink(rid, &content, MC_NO_ERRORS);



  }
  assert( blob_is_reset(&content) );
  remote_has(rid);
}

/*
** The aToken[0..nToken-1] blob array is a parse of a "cfile" line
................................................................................
    srcid = 0;
    pXfer->nFileRcvd++;
  }
  rid = content_put_ex(&content, blob_str(&pXfer->aToken[1]), srcid,
                       szC, isPriv);
  Th_AppendToList(pzUuidList, pnUuidList, blob_str(&pXfer->aToken[1]),
                  blob_size(&pXfer->aToken[1]));



  remote_has(rid);
  blob_reset(&content);
}

/*
** Try to send a file as a delta against its parent.
** If successful, return the number of bytes in the delta.
................................................................................
  }
  zScript = xfer_push_code();
  if( zScript ){ /* NOTE: Are TH1 transfer hooks enabled? */
    pzUuidList = &zUuidList;
    pnUuidList = &nUuidList;
  }
  while( blob_line(xfer.pIn, &xfer.line) ){

    if( blob_buffer(&xfer.line)[0]=='#' ) continue;
    if( blob_size(&xfer.line)==0 ) continue;
    xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken));

    /*   file UUID SIZE \n CONTENT
    **   file UUID DELTASRC SIZE \n CONTENT
    **
................................................................................
      if( !isPush ){
        cgi_reset_content();
        @ error not\sauthorized\sto\swrite
        nErr++;
        break;
      }
      xfer_accept_file(&xfer, 0, pzUuidList, pnUuidList);



      if( blob_size(&xfer.err) ){
        cgi_reset_content();
        @ error %T(blob_str(&xfer.err))
        nErr++;
        break;
      }
    }else
................................................................................
      if( !isPush ){
        cgi_reset_content();
        @ error not\sauthorized\sto\swrite
        nErr++;
        break;
      }
      xfer_accept_compressed_file(&xfer, pzUuidList, pnUuidList);



      if( blob_size(&xfer.err) ){
        cgi_reset_content();
        @ error %T(blob_str(&xfer.err))
        nErr++;
        break;
      }
    }else







>







 







>
>
>







 







>
>
>







 







>







 







>
>
>







 







>
>
>







45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
...
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
...
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
...
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
....
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
....
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
  int nFileSent;      /* Number of files sent */
  int nDeltaSent;     /* Number of deltas sent */
  int nFileRcvd;      /* Number of files received */
  int nDeltaRcvd;     /* Number of deltas received */
  int nDanglingFile;  /* Number of dangling deltas received */
  int mxSend;         /* Stop sending "file" when pOut reaches this size */
  int resync;         /* Send igot cards for all holdings */
  int fHasFork;       /* True if a fork has been seen */
  u8 syncPrivate;     /* True to enable syncing private content */
  u8 nextIsPrivate;   /* If true, next "file" received is a private */
  time_t maxTime;     /* Time when this transfer should be finished */
};


/*
................................................................................
  blob_reset(&hash);
  if( rid==0 ){
    blob_appendf(&pXfer->err, "%s", g.zErrMsg);
    blob_reset(&content);
  }else{
    if( !isPriv ) content_make_public(rid);
    manifest_crosslink(rid, &content, MC_NO_ERRORS);
    if( count_nonbranch_children(primary_parent_pid_from_rid(rid))>1 ){
      pXfer->fHasFork = 1;
    }
  }
  assert( blob_is_reset(&content) );
  remote_has(rid);
}

/*
** The aToken[0..nToken-1] blob array is a parse of a "cfile" line
................................................................................
    srcid = 0;
    pXfer->nFileRcvd++;
  }
  rid = content_put_ex(&content, blob_str(&pXfer->aToken[1]), srcid,
                       szC, isPriv);
  Th_AppendToList(pzUuidList, pnUuidList, blob_str(&pXfer->aToken[1]),
                  blob_size(&pXfer->aToken[1]));
  if( count_nonbranch_children(primary_parent_pid_from_rid(rid))>1 ){
    pXfer->fHasFork = 1;
  }
  remote_has(rid);
  blob_reset(&content);
}

/*
** Try to send a file as a delta against its parent.
** If successful, return the number of bytes in the delta.
................................................................................
  }
  zScript = xfer_push_code();
  if( zScript ){ /* NOTE: Are TH1 transfer hooks enabled? */
    pzUuidList = &zUuidList;
    pnUuidList = &nUuidList;
  }
  while( blob_line(xfer.pIn, &xfer.line) ){
    xfer.fHasFork = 0;
    if( blob_buffer(&xfer.line)[0]=='#' ) continue;
    if( blob_size(&xfer.line)==0 ) continue;
    xfer.nToken = blob_tokenize(&xfer.line, xfer.aToken, count(xfer.aToken));

    /*   file UUID SIZE \n CONTENT
    **   file UUID DELTASRC SIZE \n CONTENT
    **
................................................................................
      if( !isPush ){
        cgi_reset_content();
        @ error not\sauthorized\sto\swrite
        nErr++;
        break;
      }
      xfer_accept_file(&xfer, 0, pzUuidList, pnUuidList);
      if( xfer.fHasFork ){
        @ message ******\sWARNING:\sa\sfork\shas\soccurred\s******
      }
      if( blob_size(&xfer.err) ){
        cgi_reset_content();
        @ error %T(blob_str(&xfer.err))
        nErr++;
        break;
      }
    }else
................................................................................
      if( !isPush ){
        cgi_reset_content();
        @ error not\sauthorized\sto\swrite
        nErr++;
        break;
      }
      xfer_accept_compressed_file(&xfer, pzUuidList, pnUuidList);
      if( xfer.fHasFork ){
        @ message ******\sWARNING:\sa\sfork\shas\soccurred\s******
      }
      if( blob_size(&xfer.err) ){
        cgi_reset_content();
        @ error %T(blob_str(&xfer.err))
        nErr++;
        break;
      }
    }else