Fossil

Changes On Branch arjen-doc-updates
Login

Changes On Branch arjen-doc-updates

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

Changes In Branch arjen-doc-updates Excluding Merge-Ins

This is equivalent to a diff from 474850cf to d23f9887

2011-05-30
06:55
Online help for several more commands adapted ... (Closed-Leaf check-in: d23f9887 user: Arjen Markus tags: arjen-doc-updates)
2011-05-27
06:48
Add makefile to ensure no DLLs are used for the MinGW build (zlib was installed as both a static and a dynamic library) Extensions and minor textual revisions to the online help for several commands ... (check-in: 6469b814 user: Arjen Markus tags: arjen-doc-updates)
2011-05-25
13:54
Update the Mac icon for the download page. ... (check-in: a2e1c483 user: drh tags: trunk)
2011-05-24
12:02
Merge the latest trunk changes into the versionable-settings branch. ... (check-in: 9c915adb user: drh tags: versionable-settings)
12:00
Merge the latest trunk changes into the arjen-doc-updates branch. ... (check-in: 5d4ef37a user: drh tags: arjen-doc-updates)
2011-05-23
15:11
Merge the ben-security branch into the trunk. ... (check-in: 474850cf user: drh tags: trunk, release)
15:06
Merge the solaris10 branch into the trunk. ... (check-in: 3e0efc38 user: drh tags: trunk)
2011-05-22
15:08
Follow web app best practise by marking cookies as HttpOnly and, if it's over an https connection, as 'secure' so they will only be transmitted over https. Options supported by major browsers, and harmless where not supported. ... (check-in: e4b57a32 user: ben tags: ben-security)

Changes to BUILD.txt.

1
2
3
4
5
6
7
8
9
10







11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
All of the source code for fossil is contained in the src/ subdirectory.
But there is a lot of generated code, so you will probably want to
use the Makefile.  To do a complete build on unix, just type:

   make

On a windows box, use one of the Makefiles in the win/ subdirectory,
according to your compiler and environment.  For example:

   make -f win/Makefile.w32








If you have trouble, or you want to do something fancy, just look at
top level makefile. There are 6 configuration options that are all well
commented. Instead of editing the Makefile, consider copying the Makefile
to an alternative name such as "GNUMakefile", "BSDMakefile", or "makefile"
and editing the copy.


BUILDING OUTSIDE THE SOURCE TREE

An out of source build is pretty easy:

  1. Make a new directory to do the builds in.
  2. Copy "Makefile" from the source into the build directory and
  modify the SRCDIR macro along the lines of:

    SRCDIR=../src

  3. type: "make"

This will now keep all generates files seperate from the maintained
source code.

--------------------------------------------------------------------------

Here are some notes on what is happening behind the scenes:

* The Makefile just sets up a few macros and then invokes the
  real makefile in src/main.mk.  The src/main.mk makefile is
  automatically generated by a TCL script found at src/makemake.tcl.
  Do not edit src/main.mk directly.  Update src/makemake.tcl and
  then rerun it.

* The *.h header files are automatically generated using a program
  called "makeheaders".  Source code to the makeheaders program is
  found in src/makeheaders.c.  Documentation is found in 
  src/makeheaders.html.

* Most *.c source files are preprocessed using a program called
  "translate".  The sources to translate are found in src/translate.c.
  A header comment in src/translate.c explains in detail what it does.

* The src/mkindex.c program generates some C code that implements
  static lookup tables.  See the header comment in the source code
  for details on what it does.









|
>
>
>
>
>
>
>




















|














|









1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
All of the source code for fossil is contained in the src/ subdirectory.
But there is a lot of generated code, so you will probably want to
use the Makefile.  To do a complete build on unix, just type:

   make

On a windows box, use one of the Makefiles in the win/ subdirectory,
according to your compiler and environment.  For example:

   make -f win/Makefile.mingw

Note:
Some of the Makefiles require that you build in the src directory,
rather than the toplevel directory. These include: Makefile.msc,
Makefile.dmc and Makefile.PellesCGMake.

Fossil requires the zlib library as its only external dependency.

If you have trouble, or you want to do something fancy, just look at
top level makefile. There are 6 configuration options that are all well
commented. Instead of editing the Makefile, consider copying the Makefile
to an alternative name such as "GNUMakefile", "BSDMakefile", or "makefile"
and editing the copy.


BUILDING OUTSIDE THE SOURCE TREE

An out of source build is pretty easy:

  1. Make a new directory to do the builds in.
  2. Copy "Makefile" from the source into the build directory and
  modify the SRCDIR macro along the lines of:

    SRCDIR=../src

  3. type: "make"

This will now keep all generates files separate from the maintained
source code.

--------------------------------------------------------------------------

Here are some notes on what is happening behind the scenes:

* The Makefile just sets up a few macros and then invokes the
  real makefile in src/main.mk.  The src/main.mk makefile is
  automatically generated by a TCL script found at src/makemake.tcl.
  Do not edit src/main.mk directly.  Update src/makemake.tcl and
  then rerun it.

* The *.h header files are automatically generated using a program
  called "makeheaders".  Source code to the makeheaders program is
  found in src/makeheaders.c.  Documentation is found in
  src/makeheaders.html.

* Most *.c source files are preprocessed using a program called
  "translate".  The sources to translate are found in src/translate.c.
  A header comment in src/translate.c explains in detail what it does.

* The src/mkindex.c program generates some C code that implements
  static lookup tables.  See the header comment in the source code
  for details on what it does.

Changes to src/allrepo.c.

52
53
54
55
56
57
58



59
60
61
62
63
64
65
** COMMAND: all
**
** Usage: %fossil all (list|ls|pull|push|rebuild|sync)
**
** The ~/.fossil file records the location of all repositories for a
** user.  This command performs certain operations on all repositories
** that can be useful before or after a period of disconnected operation.



**
** On Win32 systems, the file is named "_fossil" and is located in
** %LOCALAPPDATA%, %APPDATA% or %HOMEPATH%.
**
** Available operations are:
**
**    ignore     Arguments are repositories that should be ignored







>
>
>







52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
** COMMAND: all
**
** Usage: %fossil all (list|ls|pull|push|rebuild|sync)
**
** The ~/.fossil file records the location of all repositories for a
** user.  This command performs certain operations on all repositories
** that can be useful before or after a period of disconnected operation.
**
** The rebuild subcommand is especially useful if the repositories were built
** with an older version of fossil.
**
** On Win32 systems, the file is named "_fossil" and is located in
** %LOCALAPPDATA%, %APPDATA% or %HOMEPATH%.
**
** Available operations are:
**
**    ignore     Arguments are repositories that should be ignored
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
**
**    sync       Run a "sync" on all repositories
**
** Respositories are automatically added to the set of known repositories
** when one of the following commands against the repository: clone, info,
** pull, push, or sync.  Even previously ignored repositories are added back
** to the list of repositories by these commands.





*/
void all_cmd(void){
  int n;
  Stmt q;
  const char *zCmd;
  char *zSyscmd;
  char *zFossil;
  char *zQFilename;
  int nMissing;
  int stopOnError = find_option("dontstop",0,0)==0;
  int rc;
  
  if( g.argc<3 ){
    usage("list|ls|pull|push|rebuild|sync");
  }
  n = strlen(g.argv[2]);
  db_open_config(1);
  zCmd = g.argv[2];
  if( strncmp(zCmd, "list", n)==0 || strncmp(zCmd,"ls",n)==0 ){







>
>
>
>
>











|







78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
**
**    sync       Run a "sync" on all repositories
**
** Respositories are automatically added to the set of known repositories
** when one of the following commands against the repository: clone, info,
** pull, push, or sync.  Even previously ignored repositories are added back
** to the list of repositories by these commands.
**
**
** SUMMARY:     fossil all subcommand|subcommand repository1 ?repository2 ...?
** Subcommands: list, ls, pull push, rebuild or sync
** Or:          ignore repository1 ...
*/
void all_cmd(void){
  int n;
  Stmt q;
  const char *zCmd;
  char *zSyscmd;
  char *zFossil;
  char *zQFilename;
  int nMissing;
  int stopOnError = find_option("dontstop",0,0)==0;
  int rc;

  if( g.argc<3 ){
    usage("list|ls|pull|push|rebuild|sync");
  }
  n = strlen(g.argv[2]);
  db_open_config(1);
  zCmd = g.argv[2];
  if( strncmp(zCmd, "list", n)==0 || strncmp(zCmd,"ls",n)==0 ){
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
    free(zSyscmd);
    free(zQFilename);
    if( stopOnError && rc ){
      nMissing = 0;
      break;
    }
  }
  
  /* If any repositories whose names appear in the ~/.fossil file could not
  ** be found, remove those names from the ~/.fossil file.
  */
  if( nMissing ){
    db_begin_transaction();
    db_reset(&q);
    while( db_step(&q)==SQLITE_ROW ){







|







156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
    free(zSyscmd);
    free(zQFilename);
    if( stopOnError && rc ){
      nMissing = 0;
      break;
    }
  }

  /* If any repositories whose names appear in the ~/.fossil file could not
  ** be found, remove those names from the ~/.fossil file.
  */
  if( nMissing ){
    db_begin_transaction();
    db_reset(&q);
    while( db_step(&q)==SQLITE_ROW ){

Changes to src/bisect.c.

89
90
91
92
93
94
95
96


97
98
99
100
101
102
103
}

/*
** COMMAND: bisect
**
** Usage: %fossil bisect SUBCOMMAND ...
**
** Run various subcommands useful for searching for bugs.


**
**   fossil bisect bad ?VERSION?
**
**     Identify version VERSION as non-working.  If VERSION is omitted,
**     the current checkout is marked as non-working.
**
**   fossil bisect good ?VERSION?







|
>
>







89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
}

/*
** COMMAND: bisect
**
** Usage: %fossil bisect SUBCOMMAND ...
**
** Run various subcommands useful for searching for bugs. It does so
** by marking versions as "good" and "bad" and allowing you to "interpolate"
** as it were between these two versions.
**
**   fossil bisect bad ?VERSION?
**
**     Identify version VERSION as non-working.  If VERSION is omitted,
**     the current checkout is marked as non-working.
**
**   fossil bisect good ?VERSION?
119
120
121
122
123
124
125





126
127
128
129
130
131
132
**
**     Reinitialize a bisect session.  This cancels prior bisect history
**     and allows a bisect session to start over from the beginning.
**
**   fossil bisect vlist
**
**     List the versions in between "bad" and "good".





*/
void bisect_cmd(void){
  int n;
  const char *zCmd;
  db_must_be_within_tree();
  if( g.argc<3 ){
    usage("bisect SUBCOMMAND ARGS...");







>
>
>
>
>







121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
**
**     Reinitialize a bisect session.  This cancels prior bisect history
**     and allows a bisect session to start over from the beginning.
**
**   fossil bisect vlist
**
**     List the versions in between "bad" and "good".
**
** SUMMARY:     fossil bisect subcommand ...
** Subcommands: bad, good ?VERSION?
** Or:          next, reset, vlist
** Or:          options ?NAME? ?VALUE?
*/
void bisect_cmd(void){
  int n;
  const char *zCmd;
  db_must_be_within_tree();
  if( g.argc<3 ){
    usage("bisect SUBCOMMAND ARGS...");

Changes to src/branch.c.

38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
  const char *zColor;    /* Color of the new branch */
  Blob branch;           /* manifest for the new branch */
  Manifest *pParent;     /* Parsed parent manifest */
  Blob mcksum;           /* Self-checksum on the manifest */
  const char *zDateOvrd; /* Override date string */
  const char *zUserOvrd; /* Override user name */
  int isPrivate = 0;     /* True if the branch should be private */
 
  noSign = find_option("nosign","",0)!=0;
  zColor = find_option("bgcolor","c",1);
  isPrivate = find_option("private",0,0)!=0;
  zDateOvrd = find_option("date-override",0,1);
  zUserOvrd = find_option("user-override",0,1);
  verify_all_options();
  if( g.argc<5 ){
    usage("new BRANCH-NAME CHECK-IN ?-bgcolor COLOR?");
  }
  db_find_and_open_repository(0, 0);  
  noSign = db_get_int("omitsign", 0)|noSign;
  
  /* fossil branch new name */
  zBranch = g.argv[3];
  if( zBranch==0 || zBranch[0]==0 ){
    fossil_panic("branch name cannot be empty");
  }
  if( db_exists(
        "SELECT 1 FROM tagxref"







|









|

|







38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
  const char *zColor;    /* Color of the new branch */
  Blob branch;           /* manifest for the new branch */
  Manifest *pParent;     /* Parsed parent manifest */
  Blob mcksum;           /* Self-checksum on the manifest */
  const char *zDateOvrd; /* Override date string */
  const char *zUserOvrd; /* Override user name */
  int isPrivate = 0;     /* True if the branch should be private */

  noSign = find_option("nosign","",0)!=0;
  zColor = find_option("bgcolor","c",1);
  isPrivate = find_option("private",0,0)!=0;
  zDateOvrd = find_option("date-override",0,1);
  zUserOvrd = find_option("user-override",0,1);
  verify_all_options();
  if( g.argc<5 ){
    usage("new BRANCH-NAME CHECK-IN ?-bgcolor COLOR?");
  }
  db_find_and_open_repository(0, 0);
  noSign = db_get_int("omitsign", 0)|noSign;

  /* fossil branch new name */
  zBranch = g.argv[3];
  if( zBranch==0 || zBranch[0]==0 ){
    fossil_panic("branch name cannot be empty");
  }
  if( db_exists(
        "SELECT 1 FROM tagxref"
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
      " ORDER BY tagname",
      rootid);
  while( db_step(&q)==SQLITE_ROW ){
    const char *zTag = db_column_text(&q, 0);
    blob_appendf(&branch, "T -%F *\n", zTag);
  }
  db_finalize(&q);
  
  blob_appendf(&branch, "U %F\n", zUserOvrd ? zUserOvrd : g.zLogin);
  md5sum_blob(&branch, &mcksum);
  blob_appendf(&branch, "Z %b\n", &mcksum);
  if( !noSign && clearsign(&branch, &branch) ){
    Blob ans;
    blob_zero(&ans);
    prompt_user("unable to sign manifest.  continue (y/N)? ", &ans);







|







130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
      " ORDER BY tagname",
      rootid);
  while( db_step(&q)==SQLITE_ROW ){
    const char *zTag = db_column_text(&q, 0);
    blob_appendf(&branch, "T -%F *\n", zTag);
  }
  db_finalize(&q);

  blob_appendf(&branch, "U %F\n", zUserOvrd ? zUserOvrd : g.zLogin);
  md5sum_blob(&branch, &mcksum);
  blob_appendf(&branch, "Z %b\n", &mcksum);
  if( !noSign && clearsign(&branch, &branch) ){
    Blob ans;
    blob_zero(&ans);
    prompt_user("unable to sign manifest.  continue (y/N)? ", &ans);
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
      fossil_nameofexe(), zBranch
    );
  }


  /* Commit */
  db_end_transaction(0);
  
  /* Do an autosync push, if requested */
  autosync(AUTOSYNC_PUSH);
}

/*
** COMMAND: branch
**







|







170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
      fossil_nameofexe(), zBranch
    );
  }


  /* Commit */
  db_end_transaction(0);

  /* Do an autosync push, if requested */
  autosync(AUTOSYNC_PUSH);
}

/*
** COMMAND: branch
**
194
195
196
197
198
199
200





201
202
203
204
205
206
207
**        --private option makes the branch private.
**
**    %fossil branch list
**    %fossil branch ls
**
**        List all branches
**





*/
void branch_cmd(void){
  int n;
  const char *zCmd = "list";
  db_find_and_open_repository(0, 0);
  if( g.argc<2 ){
    usage("new|list|ls ...");







>
>
>
>
>







194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
**        --private option makes the branch private.
**
**    %fossil branch list
**    %fossil branch ls
**
**        List all branches
**
**
** SUMMARY:     fossil branch subcommand ...
** Subcommands: new branchname basis ?-R|-repository file? ?--bgcolor color?
**                  ?--private?
** Or:          list, ls
*/
void branch_cmd(void){
  int n;
  const char *zCmd = "list";
  db_find_and_open_repository(0, 0);
  if( g.argc<2 ){
    usage("new|list|ls ...");
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
** This routine is called while for each check-in that is rendered by
** the timeline of a "brlist" page.  Add some additional hyperlinks
** to the end of the line.
*/
static void brtimeline_extra(int rid){
  Stmt q;
  if( !g.okHistory ) return;
  db_prepare(&q, 
    "SELECT substr(tagname,5) FROM tagxref, tag"
    " WHERE tagxref.rid=%d"
    "   AND tagxref.tagid=tag.tagid"
    "   AND tagxref.tagtype>0"
    "   AND tag.tagname GLOB 'sym-*'",
    rid
  );







|







339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
** This routine is called while for each check-in that is rendered by
** the timeline of a "brlist" page.  Add some additional hyperlinks
** to the end of the line.
*/
static void brtimeline_extra(int rid){
  Stmt q;
  if( !g.okHistory ) return;
  db_prepare(&q,
    "SELECT substr(tagname,5) FROM tagxref, tag"
    " WHERE tagxref.rid=%d"
    "   AND tagxref.tagid=tag.tagid"
    "   AND tagxref.tagtype>0"
    "   AND tag.tagname GLOB 'sym-*'",
    rid
  );

Changes to src/checkin.c.

35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
  Blob *report,          /* Append the status report here */
  const char *zPrefix,   /* Prefix on each line of the report */
  int missingIsFatal     /* MISSING and NOT_A_FILE are fatal errors */
){
  Stmt q;
  int nPrefix = strlen(zPrefix);
  int nErr = 0;
  db_prepare(&q, 
    "SELECT pathname, deleted, chnged, rid, coalesce(origname!=pathname,0)"
    "  FROM vfile "
    " WHERE file_is_selected(id)"
    "   AND (chnged OR deleted OR rid=0 OR pathname!=origname) ORDER BY 1"
  );
  while( db_step(&q)==SQLITE_ROW ){
    const char *zPathname = db_column_text(&q,0);







|







35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
  Blob *report,          /* Append the status report here */
  const char *zPrefix,   /* Prefix on each line of the report */
  int missingIsFatal     /* MISSING and NOT_A_FILE are fatal errors */
){
  Stmt q;
  int nPrefix = strlen(zPrefix);
  int nErr = 0;
  db_prepare(&q,
    "SELECT pathname, deleted, chnged, rid, coalesce(origname!=pathname,0)"
    "  FROM vfile "
    " WHERE file_is_selected(id)"
    "   AND (chnged OR deleted OR rid=0 OR pathname!=origname) ORDER BY 1"
  );
  while( db_step(&q)==SQLITE_ROW ){
    const char *zPathname = db_column_text(&q,0);
105
106
107
108
109
110
111



112
113
114
115
116
117
118
** Report on the edit status of all files in the current checkout.
** See also the "status" and "extra" commands.
**
** Options:
**
**    --sha1sum         Verify file status using SHA1 hashing rather
**                      than relying on file mtimes.



*/
void changes_cmd(void){
  Blob report;
  int vid;
  int useSha1sum = find_option("sha1sum", 0, 0)!=0;
  db_must_be_within_tree();
  blob_zero(&report);







>
>
>







105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
** Report on the edit status of all files in the current checkout.
** See also the "status" and "extra" commands.
**
** Options:
**
**    --sha1sum         Verify file status using SHA1 hashing rather
**                      than relying on file mtimes.
**
**
** SUMMARY: fossil changes ?--sha1sum?
*/
void changes_cmd(void){
  Blob report;
  int vid;
  int useSha1sum = find_option("sha1sum", 0, 0)!=0;
  db_must_be_within_tree();
  blob_zero(&report);
129
130
131
132
133
134
135



136
137
138
139
140
141
142
**
** Report on the status of the current checkout.
**
** Options:
**
**    --sha1sum         Verify file status using SHA1 hashing rather
**                      than relying on file mtimes.



*/
void status_cmd(void){
  int vid;
  db_must_be_within_tree();
       /* 012345678901234 */
  fossil_print("repository:   %s\n", db_lget("repository",""));
  fossil_print("local-root:   %s\n", g.zLocalRoot);







>
>
>







132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
**
** Report on the status of the current checkout.
**
** Options:
**
**    --sha1sum         Verify file status using SHA1 hashing rather
**                      than relying on file mtimes.
**
**
** SUMMARY: fossil status ?--sha1sum?
*/
void status_cmd(void){
  int vid;
  db_must_be_within_tree();
       /* 012345678901234 */
  fossil_print("repository:   %s\n", db_lget("repository",""));
  fossil_print("local-root:   %s\n", g.zLocalRoot);
151
152
153
154
155
156
157



158
159
160
161
162
163
164
/*
** COMMAND: ls
**
** Usage: %fossil ls [-l]
**
** Show the names of all files in the current checkout.  The -l provides
** extra information about each file.



*/
void ls_cmd(void){
  int vid;
  Stmt q;
  int isBrief;

  isBrief = find_option("l","l", 0)==0;







>
>
>







157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/*
** COMMAND: ls
**
** Usage: %fossil ls [-l]
**
** Show the names of all files in the current checkout.  The -l provides
** extra information about each file.
**
**
** SUMMARY: fossil ls ?-l?
*/
void ls_cmd(void){
  int vid;
  Stmt q;
  int isBrief;

  isBrief = find_option("l","l", 0)==0;
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216




217
218
219
220
221
222
223
  db_finalize(&q);
}

/*
** COMMAND: extras
** Usage: %fossil extras ?--dotfiles? ?--ignore GLOBPATTERN?
**
** Print a list of all files in the source tree that are not part of
** the current checkout.  See also the "clean" command.
**
** Files and subdirectories whose names begin with "." are normally
** ignored but can be included by adding the --dotfiles option.
**
** The GLOBPATTERN is a comma-separated list of GLOB expressions for
** files that are ignored.  The GLOBPATTERN specified by the "ignore-glob"
** is used if the --ignore option is omitted.




*/
void extra_cmd(void){
  Blob path;
  Blob repo;
  Stmt q;
  int n;
  const char *zIgnoreFlag = find_option("ignore",0,1);







|







|
>
>
>
>







210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
  db_finalize(&q);
}

/*
** COMMAND: extras
** Usage: %fossil extras ?--dotfiles? ?--ignore GLOBPATTERN?
**
** Print a list of all files in the source tree that are NOT part of
** the current checkout.  See also the "clean" command.
**
** Files and subdirectories whose names begin with "." are normally
** ignored but can be included by adding the --dotfiles option.
**
** The GLOBPATTERN is a comma-separated list of GLOB expressions for
** files that are ignored.  The GLOBPATTERN specified by the "ignore-glob"
** setting is used if the --ignore option is omitted. (See the settings
** command for more information.)
**
**
** SUMMARY: fossil extras ?-dotfiles? ?--ignore globpattern?
*/
void extra_cmd(void){
  Blob path;
  Blob repo;
  Stmt q;
  int n;
  const char *zIgnoreFlag = find_option("ignore",0,1);
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259


260
261
262
263
264
265
266
267
268
269
270
271
272




273
274
275
276
277
278
279
  blob_init(&path, g.zLocalRoot, n-1);
  if( zIgnoreFlag==0 ){
    zIgnoreFlag = db_get("ignore-glob", 0);
  }
  pIgnore = glob_create(zIgnoreFlag);
  vfile_scan(&path, blob_size(&path), allFlag, pIgnore);
  glob_free(pIgnore);
  db_prepare(&q, 
      "SELECT x FROM sfile"
      " WHERE x NOT IN (%s)"
      " ORDER BY 1",
      fossil_all_reserved_names()
  );
  if( file_tree_name(g.zRepositoryName, &repo, 0) ){
    db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo);
  }
  while( db_step(&q)==SQLITE_ROW ){
    fossil_print("%s\n", db_column_text(&q, 0));
  }
  db_finalize(&q);
}

/*
** COMMAND: clean
** Usage: %fossil clean ?--force? ?--dotfiles? ?--ignore GLOBPATTERN?
**
** Delete all "extra" files in the source tree.  "Extra" files are
** files that are not officially part of the checkout.  See also


** the "extra" command. This operation cannot be undone. 
**
** You will be prompted before removing each file. If you are
** sure you wish to remove all "extra" files you can specify the
** optional --force flag and no prompts will be issued.
**
** Files and subdirectories whose names begin with "." are
** normally ignored.  They are included if the "--dotfiles" option
** is used.
**
** The GLOBPATTERN is a comma-separated list of GLOB expressions for
** files that are ignored.  The GLOBPATTERN specified by the "ignore-glob"
** is used if the --ignore option is omitted.




*/
void clean_cmd(void){
  int allFlag;
  int dotfilesFlag;
  const char *zIgnoreFlag;
  Blob path, repo;
  Stmt q;







|




















>
>
|



|







|
>
>
>
>







245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
  blob_init(&path, g.zLocalRoot, n-1);
  if( zIgnoreFlag==0 ){
    zIgnoreFlag = db_get("ignore-glob", 0);
  }
  pIgnore = glob_create(zIgnoreFlag);
  vfile_scan(&path, blob_size(&path), allFlag, pIgnore);
  glob_free(pIgnore);
  db_prepare(&q,
      "SELECT x FROM sfile"
      " WHERE x NOT IN (%s)"
      " ORDER BY 1",
      fossil_all_reserved_names()
  );
  if( file_tree_name(g.zRepositoryName, &repo, 0) ){
    db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo);
  }
  while( db_step(&q)==SQLITE_ROW ){
    fossil_print("%s\n", db_column_text(&q, 0));
  }
  db_finalize(&q);
}

/*
** COMMAND: clean
** Usage: %fossil clean ?--force? ?--dotfiles? ?--ignore GLOBPATTERN?
**
** Delete all "extra" files in the source tree.  "Extra" files are
** files that are not officially part of the checkout.  See also
** the "extras" command.
**
** TAKE CARE: This operation cannot be undone!
**
** You will be prompted before removing each file. If you are
** sure you wish to remove all "extra" files you can specify the
** --force flag and no prompts will be issued.
**
** Files and subdirectories whose names begin with "." are
** normally ignored.  They are included if the "--dotfiles" option
** is used.
**
** The GLOBPATTERN is a comma-separated list of GLOB expressions for
** files that are ignored.  The GLOBPATTERN specified by the "ignore-glob"
** setting is used if the --ignore option is omitted. (See the settings
** command for more information.)
**
**
** SUMMARY: fossil clean ?--force? ?--dotfiles? ?--ignore globpattern?
*/
void clean_cmd(void){
  int allFlag;
  int dotfilesFlag;
  const char *zIgnoreFlag;
  Blob path, repo;
  Stmt q;
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
  }
  db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY)");
  n = strlen(g.zLocalRoot);
  blob_init(&path, g.zLocalRoot, n-1);
  pIgnore = glob_create(zIgnoreFlag);
  vfile_scan(&path, blob_size(&path), dotfilesFlag, pIgnore);
  glob_free(pIgnore);
  db_prepare(&q, 
      "SELECT %Q || x FROM sfile"
      " WHERE x NOT IN (%s)"
      " ORDER BY 1",
      g.zLocalRoot, fossil_all_reserved_names()
  );
  if( file_tree_name(g.zRepositoryName, &repo, 0) ){
    db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo);







|







308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
  }
  db_multi_exec("CREATE TEMP TABLE sfile(x TEXT PRIMARY KEY)");
  n = strlen(g.zLocalRoot);
  blob_init(&path, g.zLocalRoot, n-1);
  pIgnore = glob_create(zIgnoreFlag);
  vfile_scan(&path, blob_size(&path), dotfilesFlag, pIgnore);
  glob_free(pIgnore);
  db_prepare(&q,
      "SELECT %Q || x FROM sfile"
      " WHERE x NOT IN (%s)"
      " ORDER BY 1",
      g.zLocalRoot, fossil_all_reserved_names()
  );
  if( file_tree_name(g.zRepositoryName, &repo, 0) ){
    db_multi_exec("DELETE FROM sfile WHERE x=%B", &repo);
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
                 " Use -f to override.", zUuid, zDate);
  }
#endif
}

/*
** zDate should be a valid date string.  Convert this string into the
** format YYYY-MM-DDTHH:MM:SS.  If the string is not a valid date, 
** print a fatal error and quit.
*/
char *date_in_standard_format(const char *zInputDate){
  char *zDate;
  zDate = db_text(0, "SELECT strftime('%%Y-%%m-%%dT%%H:%%M:%%f',%Q)",
                  zInputDate);
  if( zDate[0]==0 ){







|







514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
                 " Use -f to override.", zUuid, zDate);
  }
#endif
}

/*
** zDate should be a valid date string.  Convert this string into the
** format YYYY-MM-DDTHH:MM:SS.  If the string is not a valid date,
** print a fatal error and quit.
*/
char *date_in_standard_format(const char *zInputDate){
  char *zDate;
  zDate = db_text(0, "SELECT strftime('%%Y-%%m-%%dT%%H:%%M:%%f',%Q)",
                  zInputDate);
  if( zDate[0]==0 ){
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
    int isexe = db_column_int(&q, 4);
    int isSelected = db_column_int(&q, 5);
    const char *zPerm;
    int cmp;
#if !defined(_WIN32)
    /* For unix, extract the "executable" permission bit directly from
    ** the filesystem.  On windows, the "executable" bit is retained
    ** unchanged from the original. 
    */
    blob_resize(&filename, nBasename);
    blob_append(&filename, zName, -1);
    isexe = file_isexe(blob_str(&filename));
#endif
    if( isexe ){
      zPerm = " x";







|







596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
    int isexe = db_column_int(&q, 4);
    int isSelected = db_column_int(&q, 5);
    const char *zPerm;
    int cmp;
#if !defined(_WIN32)
    /* For unix, extract the "executable" permission bit directly from
    ** the filesystem.  On windows, the "executable" bit is retained
    ** unchanged from the original.
    */
    blob_resize(&filename, nBasename);
    blob_append(&filename, zName, -1);
    isexe = file_isexe(blob_str(&filename));
#endif
    if( isexe ){
      zPerm = " x";
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
        " ORDER BY tagname",
        vid, zBranch);
    while( db_step(&q)==SQLITE_ROW ){
      const char *zTag = db_column_text(&q, 0);
      blob_appendf(pOut, "T -%F *\n", zTag);
    }
    db_finalize(&q);
  }  
  blob_appendf(pOut, "U %F\n", zUserOvrd ? zUserOvrd : g.zLogin);
  md5sum_blob(pOut, &mcksum);
  blob_appendf(pOut, "Z %b\n", &mcksum);
  if( pnFBcard ) *pnFBcard = nFBcard;
}

/*







|







688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
        " ORDER BY tagname",
        vid, zBranch);
    while( db_step(&q)==SQLITE_ROW ){
      const char *zTag = db_column_text(&q, 0);
      blob_appendf(pOut, "T -%F *\n", zTag);
    }
    db_finalize(&q);
  }
  blob_appendf(pOut, "U %F\n", zUserOvrd ? zUserOvrd : g.zLogin);
  md5sum_blob(pOut, &mcksum);
  blob_appendf(pOut, "Z %b\n", &mcksum);
  if( pnFBcard ) *pnFBcard = nFBcard;
}

/*
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
** COMMAND: ci
** COMMAND: commit
**
** Usage: %fossil commit ?OPTIONS? ?FILE...?
**
** Create a new version containing all of the changes in the current
** checkout.  You will be prompted to enter a check-in comment unless
** the comment has been specified on the command-line using "-m" or a 
** file containing the comment using -M.  The editor defined in the
** "editor" fossil option (see %fossil help set) will be used, or from
** the "VISUAL" or "EDITOR" environment variables (in that order) if
** no editor is set.
**
** All files that have changed will be committed unless some subset of
** files is specified on the command line.







|







756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
** COMMAND: ci
** COMMAND: commit
**
** Usage: %fossil commit ?OPTIONS? ?FILE...?
**
** Create a new version containing all of the changes in the current
** checkout.  You will be prompted to enter a check-in comment unless
** the comment has been specified on the command-line using "-m" or a
** file containing the comment using -M.  The editor defined in the
** "editor" fossil option (see %fossil help set) will be used, or from
** the "VISUAL" or "EDITOR" environment variables (in that order) if
** no editor is set.
**
** All files that have changed will be committed unless some subset of
** files is specified on the command line.
759
760
761
762
763
764
765
766








767


768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
** option appears.  A check-in is not allowed against a closed check-in.
**
** The --private option creates a private check-in that is never synced.
** Children of private check-ins are automatically private.
**
** the --tag option applies the symbolic tag name to the check-in.
**
** Options:








**


**    --comment|-m COMMENT-TEXT
**    --message-file|-M COMMENT-FILE
**    --branch NEW-BRANCH-NAME
**    --bgcolor COLOR
**    --nosign
**    --force|-f
**    --private
**    --baseline
**    --delta
**    --tag TAG-NAME
**    
*/
void commit_cmd(void){
  int hasChanges;        /* True if unsaved changes exist */
  int vid;               /* blob-id of parent version */
  int nrid;              /* blob-id of a modified file */
  int nvid;              /* Blob-id of the new check-in */
  Blob comment;          /* Check-in comment */







|
>
>
>
>
>
>
>
>

>
>










|







778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
** option appears.  A check-in is not allowed against a closed check-in.
**
** The --private option creates a private check-in that is never synced.
** Children of private check-ins are automatically private.
**
** the --tag option applies the symbolic tag name to the check-in.
**
** Notes:
** - If you commit without the --branch option, the last branch (or the
**   trunk) will be used.
** - If you do not specify a commit message or an empty message, the commit
**   will be aborted.
** - fossil prefers text files in the UNIX format (line-endings only "LF").
**   If it encounters text files in the Windows format (CRLF), it will
**   warn about that.
**   (File that are considered binary are stored as-is)
**
** SUMMARY: fossil commit ?OPTIONS? ?FILE...?
** Options:
**    --comment|-m COMMENT-TEXT
**    --message-file|-M COMMENT-FILE
**    --branch NEW-BRANCH-NAME
**    --bgcolor COLOR
**    --nosign
**    --force|-f
**    --private
**    --baseline
**    --delta
**    --tag TAG-NAME
**
*/
void commit_cmd(void){
  int hasChanges;        /* True if unsaved changes exist */
  int vid;               /* blob-id of parent version */
  int nrid;              /* blob-id of a modified file */
  int nvid;              /* Blob-id of the new check-in */
  Blob comment;          /* Check-in comment */
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
  const char *zTag;      /* Symbolic tag to apply to this check-in */
  Blob manifest;         /* Manifest in baseline form */
  Blob muuid;            /* Manifest uuid */
  Blob cksum1, cksum2;   /* Before and after commit checksums */
  Blob cksum1b;          /* Checksum recorded in the manifest */
  int szD;               /* Size of the delta manifest */
  int szB;               /* Size of the baseline manifest */
 
  url_proxy_options();
  noSign = find_option("nosign",0,0)!=0;
  forceDelta = find_option("delta",0,0)!=0;
  forceBaseline = find_option("baseline",0,0)!=0;
  if( forceDelta && forceBaseline ){
    fossil_fatal("cannot use --delta and --baseline together");
  }







|







832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
  const char *zTag;      /* Symbolic tag to apply to this check-in */
  Blob manifest;         /* Manifest in baseline form */
  Blob muuid;            /* Manifest uuid */
  Blob cksum1, cksum2;   /* Before and after commit checksums */
  Blob cksum1b;          /* Checksum recorded in the manifest */
  int szD;               /* Size of the delta manifest */
  int szB;               /* Size of the baseline manifest */

  url_proxy_options();
  noSign = find_option("nosign",0,0)!=0;
  forceDelta = find_option("delta",0,0)!=0;
  forceBaseline = find_option("baseline",0,0)!=0;
  if( forceDelta && forceBaseline ){
    fossil_fatal("cannot use --delta and --baseline together");
  }
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
  user_select();
  /*
  ** Check that the user exists.
  */
  if( !db_exists("SELECT 1 FROM user WHERE login=%Q", g.zLogin) ){
    fossil_fatal("no such user: %s", g.zLogin);
  }
  
  hasChanges = unsaved_changes();
  db_begin_transaction();
  db_record_repository_filename(0);
  if( hasChanges==0 && !isAMerge && !forceFlag ){
    fossil_fatal("nothing has changed");
  }

  /* If one or more files that were named on the command line have not
  ** been modified, bail out now.
  */
  if( g.aCommitFile ){
    Blob unmodified;
    memset(&unmodified, 0, sizeof(Blob));
    blob_init(&unmodified, 0, 0);
    db_blob(&unmodified, 
      "SELECT pathname FROM vfile"
      " WHERE chnged = 0 AND origname IS NULL AND file_is_selected(id)"
    );
    if( strlen(blob_str(&unmodified)) ){
      fossil_fatal("file %s has not changed", blob_str(&unmodified));
    }
  }

  /*
  ** Do not allow a commit that will cause a fork unless the --force flag
  ** is used or unless this is a private check-in.
  */
  if( zBranch==0 && forceFlag==0 && g.markPrivate==0 && !is_a_leaf(vid) ){
    fossil_fatal("would fork.  \"update\" first or use -f or --force.");
  }

  /*
  ** Do not allow a commit against a closed leaf 
  */
  if( db_exists("SELECT 1 FROM tagxref"
                " WHERE tagid=%d AND rid=%d AND tagtype>0",
                TAG_CLOSED, vid) ){
    fossil_fatal("cannot commit against a closed leaf");
  }








|














|

















|







926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
  user_select();
  /*
  ** Check that the user exists.
  */
  if( !db_exists("SELECT 1 FROM user WHERE login=%Q", g.zLogin) ){
    fossil_fatal("no such user: %s", g.zLogin);
  }

  hasChanges = unsaved_changes();
  db_begin_transaction();
  db_record_repository_filename(0);
  if( hasChanges==0 && !isAMerge && !forceFlag ){
    fossil_fatal("nothing has changed");
  }

  /* If one or more files that were named on the command line have not
  ** been modified, bail out now.
  */
  if( g.aCommitFile ){
    Blob unmodified;
    memset(&unmodified, 0, sizeof(Blob));
    blob_init(&unmodified, 0, 0);
    db_blob(&unmodified,
      "SELECT pathname FROM vfile"
      " WHERE chnged = 0 AND origname IS NULL AND file_is_selected(id)"
    );
    if( strlen(blob_str(&unmodified)) ){
      fossil_fatal("file %s has not changed", blob_str(&unmodified));
    }
  }

  /*
  ** Do not allow a commit that will cause a fork unless the --force flag
  ** is used or unless this is a private check-in.
  */
  if( zBranch==0 && forceFlag==0 && g.markPrivate==0 && !is_a_leaf(vid) ){
    fossil_fatal("would fork.  \"update\" first or use -f or --force.");
  }

  /*
  ** Do not allow a commit against a closed leaf
  */
  if( db_exists("SELECT 1 FROM tagxref"
                " WHERE tagid=%d AND rid=%d AND tagtype>0",
                TAG_CLOSED, vid) ){
    fossil_fatal("cannot commit against a closed leaf");
  }

963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
    }
  }else{
    db_multi_exec("REPLACE INTO vvar VALUES('ci-comment',%B)", &comment);
    db_end_transaction(0);
    db_begin_transaction();
  }

  /* Step 1: Insert records for all modified files into the blob 
  ** table. If there were arguments passed to this command, only
  ** the identified fils are inserted (if they have been modified).
  */
  db_prepare(&q,
    "SELECT id, %Q || pathname, mrid, %s FROM vfile "
    "WHERE chnged==1 AND NOT deleted AND file_is_selected(id)",
    g.zLocalRoot, glob_expr("pathname", db_get("crnl-glob",""))







|







992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
    }
  }else{
    db_multi_exec("REPLACE INTO vvar VALUES('ci-comment',%B)", &comment);
    db_end_transaction(0);
    db_begin_transaction();
  }

  /* Step 1: Insert records for all modified files into the blob
  ** table. If there were arguments passed to this command, only
  ** the identified fils are inserted (if they have been modified).
  */
  db_prepare(&q,
    "SELECT id, %Q || pathname, mrid, %s FROM vfile "
    "WHERE chnged==1 AND NOT deleted AND file_is_selected(id)",
    g.zLocalRoot, glob_expr("pathname", db_get("crnl-glob",""))
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
    prompt_user("unable to sign manifest.  continue (y/N)? ", &ans);
    if( blob_str(&ans)[0]!='y' ){
      fossil_exit(1);
    }
  }

  /* If the --test option is specified, output the manifest file
  ** and rollback the transaction.  
  */
  if( testRun ){
    blob_write_to_file(&manifest, "");
  }

  if( outputManifest ){
    zManifestFile = mprintf("%smanifest", g.zLocalRoot);







|







1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
    prompt_user("unable to sign manifest.  continue (y/N)? ", &ans);
    if( blob_str(&ans)[0]!='y' ){
      fossil_exit(1);
    }
  }

  /* If the --test option is specified, output the manifest file
  ** and rollback the transaction.
  */
  if( testRun ){
    blob_write_to_file(&manifest, "");
  }

  if( outputManifest ){
    zManifestFile = mprintf("%smanifest", g.zLocalRoot);
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
    blob_zero(&muuid);
    blob_appendf(&muuid, "%s\n", zUuid);
    blob_write_to_file(&muuid, zManifestFile);
    free(zManifestFile);
    blob_reset(&muuid);
  }

  
  /* Update the vfile and vmerge tables */
  db_multi_exec(
    "DELETE FROM vfile WHERE (vid!=%d OR deleted) AND file_is_selected(id);"
    "DELETE FROM vmerge WHERE file_is_selected(id) OR id=0;"
    "UPDATE vfile SET vid=%d;"
    "UPDATE vfile SET rid=mrid, chnged=0, deleted=0, origname=NULL"
    " WHERE file_is_selected(id);"







|







1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
    blob_zero(&muuid);
    blob_appendf(&muuid, "%s\n", zUuid);
    blob_write_to_file(&muuid, zManifestFile);
    free(zManifestFile);
    blob_reset(&muuid);
  }


  /* Update the vfile and vmerge tables */
  db_multi_exec(
    "DELETE FROM vfile WHERE (vid!=%d OR deleted) AND file_is_selected(id);"
    "DELETE FROM vmerge WHERE file_is_selected(id) OR id=0;"
    "UPDATE vfile SET vid=%d;"
    "UPDATE vfile SET rid=mrid, chnged=0, deleted=0, origname=NULL"
    " WHERE file_is_selected(id);"
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
    vfile_aggregate_checksum_repository(nvid, &cksum2);
    if( blob_compare(&cksum1, &cksum2) ){
      vfile_compare_repository_to_disk(nvid);
      fossil_fatal("working checkout does not match what would have ended "
                   "up in the repository:  %b versus %b",
                   &cksum1, &cksum2);
    }
  
    /* Verify that the manifest checksum matches the expected checksum */
    vfile_aggregate_checksum_manifest(nvid, &cksum2, &cksum1b);
    if( blob_compare(&cksum1, &cksum1b) ){
      fossil_fatal("manifest checksum self-test failed: "
                   "%b versus %b", &cksum1, &cksum1b);
    }
    if( blob_compare(&cksum1, &cksum2) ){
      fossil_fatal(
         "working checkout does not match manifest after commit: "
         "%b versus %b", &cksum1, &cksum2);
    }
  
    /* Verify that the commit did not modify any disk images. */
    vfile_aggregate_checksum_disk(nvid, &cksum2);
    if( blob_compare(&cksum1, &cksum2) ){
      fossil_fatal("working checkout before and after commit does not match");
    }
  }

  /* Clear the undo/redo stack */
  undo_reset();

  /* Commit */
  db_multi_exec("DELETE FROM vvar WHERE name='ci-comment'");
  if( testRun ){
    db_end_transaction(1);
    exit(1);
  }
  db_end_transaction(0);

  if( !g.markPrivate ){
    autosync(AUTOSYNC_PUSH);  
  }
  if( count_nonbranch_children(vid)>1 ){
    fossil_print("**** warning: a fork has occurred *****\n");
  }
}







|











|



















|





1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
    vfile_aggregate_checksum_repository(nvid, &cksum2);
    if( blob_compare(&cksum1, &cksum2) ){
      vfile_compare_repository_to_disk(nvid);
      fossil_fatal("working checkout does not match what would have ended "
                   "up in the repository:  %b versus %b",
                   &cksum1, &cksum2);
    }

    /* Verify that the manifest checksum matches the expected checksum */
    vfile_aggregate_checksum_manifest(nvid, &cksum2, &cksum1b);
    if( blob_compare(&cksum1, &cksum1b) ){
      fossil_fatal("manifest checksum self-test failed: "
                   "%b versus %b", &cksum1, &cksum1b);
    }
    if( blob_compare(&cksum1, &cksum2) ){
      fossil_fatal(
         "working checkout does not match manifest after commit: "
         "%b versus %b", &cksum1, &cksum2);
    }

    /* Verify that the commit did not modify any disk images. */
    vfile_aggregate_checksum_disk(nvid, &cksum2);
    if( blob_compare(&cksum1, &cksum2) ){
      fossil_fatal("working checkout before and after commit does not match");
    }
  }

  /* Clear the undo/redo stack */
  undo_reset();

  /* Commit */
  db_multi_exec("DELETE FROM vvar WHERE name='ci-comment'");
  if( testRun ){
    db_end_transaction(1);
    exit(1);
  }
  db_end_transaction(0);

  if( !g.markPrivate ){
    autosync(AUTOSYNC_PUSH);
  }
  if( count_nonbranch_children(vid)>1 ){
    fossil_print("**** warning: a fork has occurred *****\n");
  }
}

Changes to src/checkout.c.

164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189



190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
    }
    if( !db_exists("SELECT 1 FROM vfile WHERE pathname='manifest.uuid'") ){
      zManFile = mprintf("%smanifest.uuid", g.zLocalRoot);
      file_delete(zManFile);
      free(zManFile);
    }
  }
    
}

/*
** COMMAND: checkout
** COMMAND: co
**
** Usage: %fossil checkout VERSION ?-f|--force? ?--keep?
**
** Check out a version specified on the command-line.  This command
** will abort if there are edited files in the current checkout unless
** the --force option appears on the command-line.  The --keep option
** leaves files on disk unchanged, except the manifest and manifest.uuid
** files.
**
** The --latest flag can be used in place of VERSION to checkout the
** latest version in the repository.
**
** See also the "update" command.



*/
void checkout_cmd(void){
  int forceFlag;                 /* Force checkout even if edits exist */
  int keepFlag;                  /* Do not change any files on disk */
  int latestFlag;                /* Checkout the latest version */
  char *zVers;                   /* Version to checkout */
  int promptFlag;                /* True to prompt before overwriting */
  int vid, prior;
  Blob cksum1, cksum1b, cksum2;
  
  db_must_be_within_tree();
  db_begin_transaction();
  forceFlag = find_option("force","f",0)!=0;
  keepFlag = find_option("keep",0,0)!=0;
  latestFlag = find_option("latest",0,0)!=0;
  promptFlag = find_option("prompt",0,0)!=0 || forceFlag==0;
  if( (latestFlag!=0 && g.argc!=2) || (latestFlag==0 && g.argc!=3) ){







|


















>
>
>









|







164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
    }
    if( !db_exists("SELECT 1 FROM vfile WHERE pathname='manifest.uuid'") ){
      zManFile = mprintf("%smanifest.uuid", g.zLocalRoot);
      file_delete(zManFile);
      free(zManFile);
    }
  }

}

/*
** COMMAND: checkout
** COMMAND: co
**
** Usage: %fossil checkout VERSION ?-f|--force? ?--keep?
**
** Check out a version specified on the command-line.  This command
** will abort if there are edited files in the current checkout unless
** the --force option appears on the command-line.  The --keep option
** leaves files on disk unchanged, except the manifest and manifest.uuid
** files.
**
** The --latest flag can be used in place of VERSION to checkout the
** latest version in the repository.
**
** See also the "update" command.
**
** SUMMARY: fossil checkout VERSION ?-f|--force? ?--keep?
** Note: VERSION can also be --latest
*/
void checkout_cmd(void){
  int forceFlag;                 /* Force checkout even if edits exist */
  int keepFlag;                  /* Do not change any files on disk */
  int latestFlag;                /* Checkout the latest version */
  char *zVers;                   /* Version to checkout */
  int promptFlag;                /* True to prompt before overwriting */
  int vid, prior;
  Blob cksum1, cksum1b, cksum2;

  db_must_be_within_tree();
  db_begin_transaction();
  forceFlag = find_option("force","f",0)!=0;
  keepFlag = find_option("keep",0,0)!=0;
  latestFlag = find_option("latest",0,0)!=0;
  promptFlag = find_option("prompt",0,0)!=0 || forceFlag==0;
  if( (latestFlag!=0 && g.argc!=2) || (latestFlag==0 && g.argc!=3) ){
278
279
280
281
282
283
284
285
286


287
288
289
290
291
292
293
294
295
296
297

/*
** COMMAND: close
**
** Usage: %fossil close ?-f|--force?
**
** The opposite of "open".  Close the current database connection.
** Require a -f or --force flag if there are unsaved changed in the
** current check-out.


*/
void close_cmd(void){
  int forceFlag = find_option("force","f",0)!=0;
  db_must_be_within_tree();
  if( !forceFlag && unsaved_changes()==1 ){
    fossil_fatal("there are unsaved changes in the current checkout");
  }
  unlink_local_database(1);
  db_close(1);
  unlink_local_database(0);
}







|

>
>











281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302

/*
** COMMAND: close
**
** Usage: %fossil close ?-f|--force?
**
** The opposite of "open".  Close the current database connection.
** Require a -f or --force flag if there are unsaved changes in the
** current check-out.
**
** SUMMARY: fossil close ?-f|--force?
*/
void close_cmd(void){
  int forceFlag = find_option("force","f",0)!=0;
  db_must_be_within_tree();
  if( !forceFlag && unsaved_changes()==1 ){
    fossil_fatal("there are unsaved changes in the current checkout");
  }
  unlink_local_database(1);
  db_close(1);
  unlink_local_database(0);
}

Changes to src/clone.c.

25
26
27
28
29
30
31
32
33
34
35
36
37

38
39
40
41
42
43
44
45
46
47
48

/*
** COMMAND: clone
**
** Usage: %fossil clone ?OPTIONS? URL FILENAME
**
** Make a clone of a repository specified by URL in the local
** file named FILENAME.  
**
** By default, your current login name is used to create the default
** admin user. This can be overridden using the -A|--admin-user
** parameter.
**

** Options:
**
**    --admin-user|-A USERNAME    Make USERNAME the administrator
**    --private                   Also clone private branches 
**
*/
void clone_cmd(void){
  char *zPassword;
  const char *zDefaultUser;   /* Optional name of the default user */
  int nErr = 0;
  int bPrivate;               /* Also clone private branches */







|





>

<

|







25
26
27
28
29
30
31
32
33
34
35
36
37
38
39

40
41
42
43
44
45
46
47
48

/*
** COMMAND: clone
**
** Usage: %fossil clone ?OPTIONS? URL FILENAME
**
** Make a clone of a repository specified by URL in the local
** file named FILENAME.
**
** By default, your current login name is used to create the default
** admin user. This can be overridden using the -A|--admin-user
** parameter.
**
** SUMMARY: fossil clone ?OPTIONS? URL FILENAME
** Options:

**    --admin-user|-A USERNAME    Make USERNAME the administrator
**    --private                   Also clone private branches
**
*/
void clone_cmd(void){
  char *zPassword;
  const char *zDefaultUser;   /* Optional name of the default user */
  int nErr = 0;
  int bPrivate;               /* Also clone private branches */

Changes to src/configure.c.

59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
  { "/user",         CONFIGSET_USER,  "Users and privilege settings"         },
  { "/all",          CONFIGSET_ALL,   "All of the above"                     },
};


/*
** The following is a list of settings that we are willing to
** transfer.  
**
** Setting names that begin with an alphabetic characters refer to
** single entries in the CONFIG table.  Setting names that begin with
** "@" are for special processing.
*/
static struct {
  const char *zName;   /* Name of the configuration parameter */







|







59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
  { "/user",         CONFIGSET_USER,  "Users and privilege settings"         },
  { "/all",          CONFIGSET_ALL,   "All of the above"                     },
};


/*
** The following is a list of settings that we are willing to
** transfer.
**
** Setting names that begin with an alphabetic characters refer to
** single entries in the CONFIG table.  Setting names that begin with
** "@" are for special processing.
*/
static struct {
  const char *zName;   /* Name of the configuration parameter */
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
** evaluated will populate the corresponding table with data.
*/
void configure_render_special_name(const char *zName, Blob *pOut){
  Stmt q;
  if( fossil_strcmp(zName, "@shun")==0 ){
    db_prepare(&q, "SELECT uuid FROM shun");
    while( db_step(&q)==SQLITE_ROW ){
      blob_appendf(pOut, "INSERT OR IGNORE INTO shun VALUES('%s');\n", 
        db_column_text(&q, 0)
      );
    }
    db_finalize(&q);
  }else if( fossil_strcmp(zName, "@reportfmt")==0 ){
    db_prepare(&q, "SELECT title, cols, sqlcode FROM reportfmt");
    while( db_step(&q)==SQLITE_ROW ){
      blob_appendf(pOut, "INSERT INTO _xfer_reportfmt(title,cols,sqlcode)"
                         " VALUES(%Q,%Q,%Q);\n", 
        db_column_text(&q, 0),
        db_column_text(&q, 1),
        db_column_text(&q, 2)
      );
    }
    db_finalize(&q);
  }else if( fossil_strcmp(zName, "@user")==0 ){
    db_prepare(&q, 
        "SELECT login, CASE WHEN length(pw)==40 THEN pw END,"
        "       cap, info, quote(photo) FROM user");
    while( db_step(&q)==SQLITE_ROW ){
      blob_appendf(pOut, "INSERT INTO _xfer_user(login,pw,cap,info,photo)"
                         " VALUES(%Q,%Q,%Q,%Q,%s);\n",
        db_column_text(&q, 0),
        db_column_text(&q, 1),







|








|







|







173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
** evaluated will populate the corresponding table with data.
*/
void configure_render_special_name(const char *zName, Blob *pOut){
  Stmt q;
  if( fossil_strcmp(zName, "@shun")==0 ){
    db_prepare(&q, "SELECT uuid FROM shun");
    while( db_step(&q)==SQLITE_ROW ){
      blob_appendf(pOut, "INSERT OR IGNORE INTO shun VALUES('%s');\n",
        db_column_text(&q, 0)
      );
    }
    db_finalize(&q);
  }else if( fossil_strcmp(zName, "@reportfmt")==0 ){
    db_prepare(&q, "SELECT title, cols, sqlcode FROM reportfmt");
    while( db_step(&q)==SQLITE_ROW ){
      blob_appendf(pOut, "INSERT INTO _xfer_reportfmt(title,cols,sqlcode)"
                         " VALUES(%Q,%Q,%Q);\n",
        db_column_text(&q, 0),
        db_column_text(&q, 1),
        db_column_text(&q, 2)
      );
    }
    db_finalize(&q);
  }else if( fossil_strcmp(zName, "@user")==0 ){
    db_prepare(&q,
        "SELECT login, CASE WHEN length(pw)==40 THEN pw END,"
        "       cap, info, quote(photo) FROM user");
    while( db_step(&q)==SQLITE_ROW ){
      blob_appendf(pOut, "INSERT INTO _xfer_user(login,pw,cap,info,photo)"
                         " VALUES(%Q,%Q,%Q,%Q,%s);\n",
        db_column_text(&q, 0),
        db_column_text(&q, 1),
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
    @ );
    @ INSERT INTO _xfer_reportfmt
    @    SELECT rn,owner,title,cols,sqlcode FROM reportfmt;
    @ INSERT INTO _xfer_user
    @    SELECT uid,login,pw,cap,cookie,ipaddr,cexpire,info,photo FROM user;
  ;
  db_multi_exec(zSQL1);
  
  /* When the replace flag is set, add triggers that run the first time
  ** that new data is seen.  The triggers run only once and delete all the
  ** existing data.
  */
  if( replaceFlag ){
    static const char zSQL2[] =
      @ CREATE TRIGGER _xfer_r1 BEFORE INSERT ON _xfer_reportfmt







|







288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
    @ );
    @ INSERT INTO _xfer_reportfmt
    @    SELECT rn,owner,title,cols,sqlcode FROM reportfmt;
    @ INSERT INTO _xfer_user
    @    SELECT uid,login,pw,cap,cookie,ipaddr,cexpire,info,photo FROM user;
  ;
  db_multi_exec(zSQL1);

  /* When the replace flag is set, add triggers that run the first time
  ** that new data is seen.  The triggers run only once and delete all the
  ** existing data.
  */
  if( replaceFlag ){
    static const char zSQL2[] =
      @ CREATE TRIGGER _xfer_r1 BEFORE INSERT ON _xfer_reportfmt
769
770
771
772
773
774
775
















776
777
778
779
780
781
782
**
**         Restore the configuration to the default.  AREA as above.
**
**    %fossil configuration sync AREA ?URL?
**
**         Synchronize configuration changes in the local repository with
**         the remote repository at URL.  
















*/
void configuration_cmd(void){
  int n;
  const char *zMethod;
  if( g.argc<3 ){
    usage("export|import|merge|pull|reset ...");
  }







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







769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
**
**         Restore the configuration to the default.  AREA as above.
**
**    %fossil configuration sync AREA ?URL?
**
**         Synchronize configuration changes in the local repository with
**         the remote repository at URL.  
**
**
** SUMMARY: fossil configure METHOD ... ?-R|--repository REPOSITORY?
** Where:   METHOD = export, import, merge, pull, push or reset
**
**          For methods export, pull, push and reset:
**
**              fossil configure METHOD AREA ?FILENAME|URL? ?-R|--repository REPOSITORY?
**
**          AREA = all email project shun skin ticket user
**
**          FILENAME used with methods export, URL used with the others
**
**          For methods import and merge
**
**              fossil configure METHOD FILENAME -R|--repository REPOSITORY?
*/
void configuration_cmd(void){
  int n;
  const char *zMethod;
  if( g.argc<3 ){
    usage("export|import|merge|pull|reset ...");
  }
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
         zSince, zSince
      );
    }else{
      iStart = 0;
    }
    export_config(mask, g.argv[3], iStart, g.argv[4]);
  }else
  if( strncmp(zMethod, "import", n)==0 
       || strncmp(zMethod, "merge", n)==0 ){
    Blob in;
    int groupMask;
    if( g.argc!=4 ) usage(mprintf("%s FILENAME",zMethod));
    blob_read_from_file(&in, g.argv[3]);
    db_begin_transaction();
    if( zMethod[0]=='i' ){







|







813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
         zSince, zSince
      );
    }else{
      iStart = 0;
    }
    export_config(mask, g.argv[3], iStart, g.argv[4]);
  }else
  if( strncmp(zMethod, "import", n)==0
       || strncmp(zMethod, "merge", n)==0 ){
    Blob in;
    int groupMask;
    if( g.argc!=4 ) usage(mprintf("%s FILENAME",zMethod));
    blob_read_from_file(&in, g.argv[3]);
    db_begin_transaction();
    if( zMethod[0]=='i' ){
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
    }
  }else
  if( strncmp(zMethod, "reset", n)==0 ){
    int mask, i;
    char *zBackup;
    if( g.argc!=4 ) usage("reset AREA");
    mask = configure_name_to_mask(g.argv[3], 1);
    zBackup = db_text(0, 
       "SELECT strftime('config-backup-%%Y%%m%%d%%H%%M%%f','now')");
    db_begin_transaction();
    export_config(mask, g.argv[3], 0, zBackup);
    for(i=0; i<count(aConfig); i++){
      const char *zName = aConfig[i].zName;
      if( (aConfig[i].groupMask & mask)==0 ) continue;
      if( zName[0]!='@' ){







|







876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
    }
  }else
  if( strncmp(zMethod, "reset", n)==0 ){
    int mask, i;
    char *zBackup;
    if( g.argc!=4 ) usage("reset AREA");
    mask = configure_name_to_mask(g.argv[3], 1);
    zBackup = db_text(0,
       "SELECT strftime('config-backup-%%Y%%m%%d%%H%%M%%f','now')");
    db_begin_transaction();
    export_config(mask, g.argv[3], 0, zBackup);
    for(i=0; i<count(aConfig); i++){
      const char *zName = aConfig[i].zName;
      if( (aConfig[i].groupMask & mask)==0 ) continue;
      if( zName[0]!='@' ){

Changes to src/content.c.

113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
  bag_clear(&contentCache.available);
  bag_clear(&contentCache.inCache);
  contentCache.n = 0;
  contentCache.szTotal = 0;
}

/*
** Return the srcid associated with rid.  Or return 0 if rid is 
** original content and not a delta.
*/
static int findSrcid(int rid){
  static Stmt q;
  int srcid;
  db_static_prepare(&q, "SELECT srcid FROM delta WHERE rid=:rid");
  db_bind_int(&q, ":rid", rid);







|







113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
  bag_clear(&contentCache.available);
  bag_clear(&contentCache.inCache);
  contentCache.n = 0;
  contentCache.szTotal = 0;
}

/*
** Return the srcid associated with rid.  Or return 0 if rid is
** original content and not a delta.
*/
static int findSrcid(int rid){
  static Stmt q;
  int srcid;
  db_static_prepare(&q, "SELECT srcid FROM delta WHERE rid=:rid");
  db_bind_int(&q, ":rid", rid);
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
** Check to see if content is available for artifact "rid".  Return
** true if it is.  Return false if rid is a phantom or depends on
** a phantom.
*/
int content_is_available(int rid){
  int srcid;
  int depth = 0;  /* Limit to recursion depth */
  while( depth++ < 10000000 ){  
    if( bag_find(&contentCache.missing, rid) ){
      return 0;
    }
    if( bag_find(&contentCache.available, rid) ){
      return 1;
    }
    if( content_size(rid, -1)<0 ){







|







153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
** Check to see if content is available for artifact "rid".  Return
** true if it is.  Return false if rid is a phantom or depends on
** a phantom.
*/
int content_is_available(int rid){
  int srcid;
  int depth = 0;  /* Limit to recursion depth */
  while( depth++ < 10000000 ){
    if( bag_find(&contentCache.missing, rid) ){
      return 0;
    }
    if( bag_find(&contentCache.available, rid) ){
      return 1;
    }
    if( content_size(rid, -1)<0 ){
305
306
307
308
309
310
311
312
313
314



315
316
317
318




319
320
321
322
323
324
325
}

/*
** COMMAND: artifact
**
** Usage: %fossil artifact ARTIFACT-ID ?OUTPUT-FILENAME? ?OPTIONS?
**
** Extract an artifact by its SHA1 hash and write the results on
** standard output, or if the optional 4th argument is given, in
** the named output file.



**
** Options:
**
**    -R|--repository FILE       Extract artifacts from repository FILE




*/
void artifact_cmd(void){
  int rid;
  Blob content;
  const char *zFile;
  db_find_and_open_repository(OPEN_ANY_SCHEMA, 0);
  if( g.argc!=4 && g.argc!=3 ) usage("ARTIFACT-ID ?FILENAME? ?OPTIONS?");







|
|
|
>
>
>




>
>
>
>







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
}

/*
** COMMAND: artifact
**
** Usage: %fossil artifact ARTIFACT-ID ?OUTPUT-FILENAME? ?OPTIONS?
**
** Extract an artifact (file) by its artifact ID (the SHA1 hash) and write
** the results on standard output, or if the optional 4th argument
** is given, in the named output file.
**
** You can find the artifact ID in the Files section of the repository's
** web interface (see the server/ui commands).
**
** Options:
**
**    -R|--repository FILE       Extract artifacts from repository FILE
**
**
** SUMMARY: fossil artifact ARTIFACT-ID ?OUTPUT-FILENAME? ?OPTIONS?
** Options: -R|--repository
*/
void artifact_cmd(void){
  int rid;
  Blob content;
  const char *zFile;
  db_find_and_open_repository(OPEN_ANY_SCHEMA, 0);
  if( g.argc!=4 && g.argc!=3 ) usage("ARTIFACT-ID ?FILENAME? ?OPTIONS?");
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
      db_multi_exec("DELETE FROM orphan WHERE baseline=%d", rid);
    }

    /* Recursively dephantomize all artifacts that are derived by
    ** delta from artifact rid and which have not already been
    ** cross-linked.  */
    nChildUsed = 0;
    db_prepare(&q, 
       "SELECT rid FROM delta"
       " WHERE srcid=%d"
       "   AND NOT EXISTS(SELECT 1 FROM mlink WHERE mid=delta.rid)",
       rid
    );
    while( db_step(&q)==SQLITE_ROW ){
      int child = db_column_int(&q, 0);







|







415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
      db_multi_exec("DELETE FROM orphan WHERE baseline=%d", rid);
    }

    /* Recursively dephantomize all artifacts that are derived by
    ** delta from artifact rid and which have not already been
    ** cross-linked.  */
    nChildUsed = 0;
    db_prepare(&q,
       "SELECT rid FROM delta"
       " WHERE srcid=%d"
       "   AND NOT EXISTS(SELECT 1 FROM mlink WHERE mid=delta.rid)",
       rid
    );
    while( db_step(&q)==SQLITE_ROW ){
      int child = db_column_int(&q, 0);
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
}

/*
** Write content into the database.  Return the record ID.  If the
** content is already in the database, just return the record ID.
**
** If srcId is specified, then pBlob is delta content from
** the srcId record.  srcId might be a phantom.  
**
** pBlob is normally uncompressed text.  But if nBlob>0 then the
** pBlob value has already been compressed and nBlob is its uncompressed
** size.  If nBlob>0 then zUuid must be valid.
**
** zUuid is the UUID of the artifact, if it is specified.  When srcId is
** specified then zUuid must always be specified.  If srcId is zero,







|







454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
}

/*
** Write content into the database.  Return the record ID.  If the
** content is already in the database, just return the record ID.
**
** If srcId is specified, then pBlob is delta content from
** the srcId record.  srcId might be a phantom.
**
** pBlob is normally uncompressed text.  But if nBlob>0 then the
** pBlob value has already been compressed and nBlob is its uncompressed
** size.  If nBlob>0 then zUuid must be valid.
**
** zUuid is the UUID of the artifact, if it is specified.  When srcId is
** specified then zUuid must always be specified.  If srcId is zero,
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
  int size;
  int rid;
  Stmt s1;
  Blob cmpr;
  Blob hash;
  int markAsUnclustered = 0;
  int isDephantomize = 0;
  
  assert( g.repositoryOpen );
  assert( pBlob!=0 );
  assert( srcId==0 || zUuid!=0 );
  if( zUuid==0 ){
    assert( pBlob!=0 );
    assert( nBlob==0 );
    sha1sum_blob(pBlob, &hash);







|







485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
  int size;
  int rid;
  Stmt s1;
  Blob cmpr;
  Blob hash;
  int markAsUnclustered = 0;
  int isDephantomize = 0;

  assert( g.repositoryOpen );
  assert( pBlob!=0 );
  assert( srcId==0 || zUuid!=0 );
  if( zUuid==0 ){
    assert( pBlob!=0 );
    assert( nBlob==0 );
    sha1sum_blob(pBlob, &hash);
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594

  /* If the srcId is specified, then the data we just added is
  ** really a delta.  Record this fact in the delta table.
  */
  if( srcId ){
    db_multi_exec("REPLACE INTO delta(rid,srcid) VALUES(%d,%d)", rid, srcId);
  }
  if( !isDephantomize && bag_find(&contentCache.missing, rid) && 
      (srcId==0 || content_is_available(srcId)) ){
    content_mark_available(rid);
  }
  if( isDephantomize ){
    after_dephantomize(rid, 0);
  }
  
  /* Add the element to the unclustered table if has never been
  ** previously seen.
  */
  if( markAsUnclustered ){
    db_multi_exec("INSERT OR IGNORE INTO unclustered VALUES(%d)", rid);
  }








|






|







580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601

  /* If the srcId is specified, then the data we just added is
  ** really a delta.  Record this fact in the delta table.
  */
  if( srcId ){
    db_multi_exec("REPLACE INTO delta(rid,srcid) VALUES(%d,%d)", rid, srcId);
  }
  if( !isDephantomize && bag_find(&contentCache.missing, rid) &&
      (srcId==0 || content_is_available(srcId)) ){
    content_mark_available(rid);
  }
  if( isDephantomize ){
    after_dephantomize(rid, 0);
  }

  /* Add the element to the unclustered table if has never been
  ** previously seen.
  */
  if( markAsUnclustered ){
    db_multi_exec("INSERT OR IGNORE INTO unclustered VALUES(%d)", rid);
  }

621
622
623
624
625
626
627
628
629
630
631
632
633
634
635

/*
** Create a new phantom with the given UUID and return its artifact ID.
*/
int content_new(const char *zUuid, int isPrivate){
  int rid;
  static Stmt s1, s2, s3;
  
  assert( g.repositoryOpen );
  db_begin_transaction();
  if( uuid_is_shunned(zUuid) ){
    db_end_transaction(0);
    return 0;
  }
  db_static_prepare(&s1,







|







628
629
630
631
632
633
634
635
636
637
638
639
640
641
642

/*
** Create a new phantom with the given UUID and return its artifact ID.
*/
int content_new(const char *zUuid, int isPrivate){
  int rid;
  static Stmt s1, s2, s3;

  assert( g.repositoryOpen );
  db_begin_transaction();
  if( uuid_is_shunned(zUuid) ){
    db_end_transaction(0);
    return 0;
  }
  db_static_prepare(&s1,
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
  int rc;
  db_static_prepare(&s1,
    "SELECT 1 FROM private WHERE rid=:rid"
  );
  db_bind_int(&s1, ":rid", rid);
  rc = db_step(&s1);
  db_reset(&s1);
  return rc==SQLITE_ROW;  
}

/*
** Make sure an artifact is public.  
*/
void content_make_public(int rid){
  static Stmt s1;
  db_static_prepare(&s1,
    "DELETE FROM private WHERE rid=:rid"
  );
  db_bind_int(&s1, ":rid", rid);







|



|







724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
  int rc;
  db_static_prepare(&s1,
    "SELECT 1 FROM private WHERE rid=:rid"
  );
  db_bind_int(&s1, ":rid", rid);
  rc = db_step(&s1);
  db_reset(&s1);
  return rc==SQLITE_ROW;
}

/*
** Make sure an artifact is public.
*/
void content_make_public(int rid){
  static Stmt s1;
  db_static_prepare(&s1,
    "DELETE FROM private WHERE rid=:rid"
  );
  db_bind_int(&s1, ":rid", rid);
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
** the source of the delta.  It is OK to delta private->private and
** public->private and public->public.  Just no private->public delta.
**
** If srcid is a delta that depends on rid, then srcid is
** converted to undeltaed text.
**
** If either rid or srcid contain less than 50 bytes, or if the
** resulting delta does not achieve a compression of at least 25% 
** the rid is left untouched.
**
** Return 1 if a delta is made and 0 if no delta occurs.
*/
int content_deltify(int rid, int srcid, int force){
  int s;
  Blob data, src, delta;







|







755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
** the source of the delta.  It is OK to delta private->private and
** public->private and public->public.  Just no private->public delta.
**
** If srcid is a delta that depends on rid, then srcid is
** converted to undeltaed text.
**
** If either rid or srcid contain less than 50 bytes, or if the
** resulting delta does not achieve a compression of at least 25%
** the rid is left untouched.
**
** Return 1 if a delta is made and 0 if no delta occurs.
*/
int content_deltify(int rid, int srcid, int force){
  int s;
  Blob data, src, delta;

Changes to src/db.c.

34
35
36
37
38
39
40





41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#endif
#include <sqlite3.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>
#include "db.h"






#if INTERFACE
/*
** An single SQL statement is represented as an instance of the following
** structure.
*/
struct Stmt {
  Blob sql;               /* The SQL for this statement */
  sqlite3_stmt *pStmt;    /* The results of sqlite3_prepare() */
  Stmt *pNext, *pPrev;    /* List of all unfinalized statements */
  int nStep;              /* Number of sqlite3_step() calls */
};
#endif /* INTERFACE */

/*
** Call this routine when a database error occurs.
*/
static void db_err(const char *zFormat, ...){
  va_list ap;
  char *z;
  static const char zRebuildMsg[] = 
      "If you have recently updated your fossil executable, you might\n"
      "need to run \"fossil all rebuild\" to bring the repository\n"
      "schemas up to date.\n";
  va_start(ap, zFormat);
  z = vmprintf(zFormat, ap);
  va_end(ap);
  if( g.xferPanic ){







>
>
>
>
>




















|







34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#endif
#include <sqlite3.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <time.h>
#include "db.h"

#if defined(_WIN32) || defined(WIN32)
# include <io.h>
#define access(f,m) _access((f),(m))
#endif

#if INTERFACE
/*
** An single SQL statement is represented as an instance of the following
** structure.
*/
struct Stmt {
  Blob sql;               /* The SQL for this statement */
  sqlite3_stmt *pStmt;    /* The results of sqlite3_prepare() */
  Stmt *pNext, *pPrev;    /* List of all unfinalized statements */
  int nStep;              /* Number of sqlite3_step() calls */
};
#endif /* INTERFACE */

/*
** Call this routine when a database error occurs.
*/
static void db_err(const char *zFormat, ...){
  va_list ap;
  char *z;
  static const char zRebuildMsg[] =
      "If you have recently updated your fossil executable, you might\n"
      "need to run \"fossil all rebuild\" to bring the repository\n"
      "schemas up to date.\n";
  va_start(ap, zFormat);
  z = vmprintf(zFormat, ap);
  va_end(ap);
  if( g.xferPanic ){
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
       zDbName, &db,
       SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
       zVfs
  );
  if( rc!=SQLITE_OK ){
    db_err(sqlite3_errmsg(db));
  }
  sqlite3_busy_timeout(db, 5000); 
  sqlite3_wal_autocheckpoint(db, 1);  /* Set to checkpoint frequently */
  sqlite3_create_function(db, "now", 0, SQLITE_ANY, 0, db_now_function, 0, 0);
  return db;
}


/*







|







645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
       zDbName, &db,
       SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE,
       zVfs
  );
  if( rc!=SQLITE_OK ){
    db_err(sqlite3_errmsg(db));
  }
  sqlite3_busy_timeout(db, 5000);
  sqlite3_wal_autocheckpoint(db, 1);  /* Set to checkpoint frequently */
  sqlite3_create_function(db, "now", 0, SQLITE_ANY, 0, db_now_function, 0, 0);
  return db;
}


/*
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
  db_open_or_attach(zDbName, "localdb");
  g.localOpen = 1;
  db_open_config(0);
  db_open_repository(0);

  /* If the "isexe" column is missing from the vfile table, then
  ** add it now.   This code added on 2010-03-06.  After all users have
  ** upgraded, this code can be safely deleted. 
  */
  rc = sqlite3_prepare(g.db, "SELECT isexe FROM vfile", -1, &pStmt, 0);
  nPrepare++;
  sqlite3_finalize(pStmt);
  if( rc==SQLITE_ERROR ){
    sqlite3_exec(g.db, "ALTER TABLE vfile ADD COLUMN isexe BOOLEAN", 0, 0, 0);
  }

#if 0
  /* If the "mtime" column is missing from the vfile table, then
  ** add it now.   This code added on 2008-12-06.  After all users have
  ** upgraded, this code can be safely deleted. 
  */
  rc = sqlite3_prepare(g.db, "SELECT mtime FROM vfile", -1, &pStmt, 0);
  sqlite3_finalize(pStmt);
  if( rc==SQLITE_ERROR ){
    sqlite3_exec(g.db, "ALTER TABLE vfile ADD COLUMN mtime INTEGER", 0, 0, 0);
  }
#endif

#if 0
  /* If the "origname" column is missing from the vfile table, then
  ** add it now.   This code added on 2008-11-09.  After all users have
  ** upgraded, this code can be safely deleted. 
  */
  rc = sqlite3_prepare(g.db, "SELECT origname FROM vfile", -1, &pStmt, 0);
  sqlite3_finalize(pStmt);
  if( rc==SQLITE_ERROR ){
    sqlite3_exec(g.db, "ALTER TABLE vfile ADD COLUMN origname TEXT", 0, 0, 0);
  }
#endif

  return 1;
}

/*
** Locate the root directory of the local repository tree.  The root
** directory is found by searching for a file named "_FOSSIL_" or ".fos"
** that contains a valid repository database.
**
** If no valid _FOSSIL_ or .fos file is found, we move up one level and 
** try again. Once the file is found, the g.zLocalRoot variable is set
** to the root of the repository tree and this routine returns 1.  If
** no database is found, then this routine return 0.
**
** This routine always opens the user database regardless of whether or
** not the repository database is found.  If the _FOSSIL_ or .fos file
** is found, it is attached to the open database connection too.
*/
int db_open_local(void){
  int i, n;
  char zPwd[2000];
  static const char *aDbName[] = { "/_FOSSIL_", "/.fos" };
  
  if( g.localOpen) return 1;
  file_getcwd(zPwd, sizeof(zPwd)-20);
  n = strlen(zPwd);
  while( n>0 ){
    if( file_access(zPwd, W_OK) ) break;
    for(i=0; i<sizeof(aDbName)/sizeof(aDbName[0]); i++){
      sqlite3_snprintf(sizeof(zPwd)-n, &zPwd[n], "%s", aDbName[i]);







|











|











|
















|












|







754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
  db_open_or_attach(zDbName, "localdb");
  g.localOpen = 1;
  db_open_config(0);
  db_open_repository(0);

  /* If the "isexe" column is missing from the vfile table, then
  ** add it now.   This code added on 2010-03-06.  After all users have
  ** upgraded, this code can be safely deleted.
  */
  rc = sqlite3_prepare(g.db, "SELECT isexe FROM vfile", -1, &pStmt, 0);
  nPrepare++;
  sqlite3_finalize(pStmt);
  if( rc==SQLITE_ERROR ){
    sqlite3_exec(g.db, "ALTER TABLE vfile ADD COLUMN isexe BOOLEAN", 0, 0, 0);
  }

#if 0
  /* If the "mtime" column is missing from the vfile table, then
  ** add it now.   This code added on 2008-12-06.  After all users have
  ** upgraded, this code can be safely deleted.
  */
  rc = sqlite3_prepare(g.db, "SELECT mtime FROM vfile", -1, &pStmt, 0);
  sqlite3_finalize(pStmt);
  if( rc==SQLITE_ERROR ){
    sqlite3_exec(g.db, "ALTER TABLE vfile ADD COLUMN mtime INTEGER", 0, 0, 0);
  }
#endif

#if 0
  /* If the "origname" column is missing from the vfile table, then
  ** add it now.   This code added on 2008-11-09.  After all users have
  ** upgraded, this code can be safely deleted.
  */
  rc = sqlite3_prepare(g.db, "SELECT origname FROM vfile", -1, &pStmt, 0);
  sqlite3_finalize(pStmt);
  if( rc==SQLITE_ERROR ){
    sqlite3_exec(g.db, "ALTER TABLE vfile ADD COLUMN origname TEXT", 0, 0, 0);
  }
#endif

  return 1;
}

/*
** Locate the root directory of the local repository tree.  The root
** directory is found by searching for a file named "_FOSSIL_" or ".fos"
** that contains a valid repository database.
**
** If no valid _FOSSIL_ or .fos file is found, we move up one level and
** try again. Once the file is found, the g.zLocalRoot variable is set
** to the root of the repository tree and this routine returns 1.  If
** no database is found, then this routine return 0.
**
** This routine always opens the user database regardless of whether or
** not the repository database is found.  If the _FOSSIL_ or .fos file
** is found, it is attached to the open database connection too.
*/
int db_open_local(void){
  int i, n;
  char zPwd[2000];
  static const char *aDbName[] = { "/_FOSSIL_", "/.fos" };

  if( g.localOpen) return 1;
  file_getcwd(zPwd, sizeof(zPwd)-20);
  n = strlen(zPwd);
  while( n>0 ){
    if( file_access(zPwd, W_OK) ) break;
    for(i=0; i<sizeof(aDbName)/sizeof(aDbName[0]); i++){
      sqlite3_snprintf(sizeof(zPwd)-n, &zPwd[n], "%s", aDbName[i]);
1164
1165
1166
1167
1168
1169
1170




1171
1172
1173
1174
1175
1176
1177
** parameter.
**
** Options:
**
**    --admin-user|-A USERNAME
**    --date-override DATETIME
**




*/
void create_repository_cmd(void){
  char *zPassword;
  const char *zDate;          /* Date of the initial check-in */
  const char *zDefaultUser;   /* Optional name of the default user */

  zDate = find_option("date-override",0,1);







>
>
>
>







1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
** parameter.
**
** Options:
**
**    --admin-user|-A USERNAME
**    --date-override DATETIME
**
**
** SUMMARY: fossil new ?OPTIONS? FILENAME
** Options: --admin-user|-A, --date-override
**
*/
void create_repository_cmd(void){
  char *zPassword;
  const char *zDate;          /* Date of the initial check-in */
  const char *zDefaultUser;   /* Optional name of the default user */

  zDate = find_option("date-override",0,1);
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
  db_open_config(0);
  db_begin_transaction();
  db_initial_setup(zDate, zDefaultUser, 1);
  db_end_transaction(0);
  fossil_print("project-id: %s\n", db_get("project-code", 0));
  fossil_print("server-id:  %s\n", db_get("server-code", 0));
  zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin);
  fossil_print("admin-user: %s (initial password is \"%s\")\n", 
               g.zLogin, zPassword);
}

/*
** SQL functions for debugging.
**
** The print() function writes its arguments on stdout, but only







|







1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
  db_open_config(0);
  db_begin_transaction();
  db_initial_setup(zDate, zDefaultUser, 1);
  db_end_transaction(0);
  fossil_print("project-id: %s\n", db_get("project-code", 0));
  fossil_print("server-id:  %s\n", db_get("server-code", 0));
  zPassword = db_text(0, "SELECT pw FROM user WHERE login=%Q", g.zLogin);
  fossil_print("admin-user: %s (initial password is \"%s\")\n",
               g.zLogin, zPassword);
}

/*
** SQL functions for debugging.
**
** The print() function writes its arguments on stdout, but only
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
  if( g.zLogin!=0 ){
    sqlite3_result_text(context, g.zLogin, -1, SQLITE_STATIC);
  }
}

/*
** Implement the cgi() SQL function.  cgi() takes a an argument which is
** a name of CGI query parameter. The value of that parameter is returned, 
** if available. optional second argument will be returned if the first
** doesn't exist as a CGI parameter.
*/
static void db_sql_cgi(sqlite3_context *context, int argc, sqlite3_value **argv){
  const char* zP;
  if( argc!=1 && argc!=2 ) return;
  zP = P((const char*)sqlite3_value_text(argv[0]));







|







1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
  if( g.zLogin!=0 ){
    sqlite3_result_text(context, g.zLogin, -1, SQLITE_STATIC);
  }
}

/*
** Implement the cgi() SQL function.  cgi() takes a an argument which is
** a name of CGI query parameter. The value of that parameter is returned,
** if available. optional second argument will be returned if the first
** doesn't exist as a CGI parameter.
*/
static void db_sql_cgi(sqlite3_context *context, int argc, sqlite3_value **argv){
  const char* zP;
  if( argc!=1 && argc!=2 ) return;
  zP = P((const char*)sqlite3_value_text(argv[0]));
1539
1540
1541
1542
1543
1544
1545



1546




1547
1548
1549
1550
1551
1552
1553
**
** Open a connection to the local repository in FILENAME.  A checkout
** for the repository is created with its root at the working directory.
** If VERSION is specified then that version is checked out.  Otherwise
** the latest version is checked out.  No files other than "manifest"
** and "manifest.uuid" are modified if the --keep option is present.
**



** See also the "close" command.




*/
void cmd_open(void){
  Blob path;
  int vid;
  int keepFlag;
  int allowNested;
  static char *azNewArgv[] = { 0, "checkout", "--prompt", 0, 0, 0 };







>
>
>

>
>
>
>







1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
**
** Open a connection to the local repository in FILENAME.  A checkout
** for the repository is created with its root at the working directory.
** If VERSION is specified then that version is checked out.  Otherwise
** the latest version is checked out.  No files other than "manifest"
** and "manifest.uuid" are modified if the --keep option is present.
**
** You can find the version IDs via the web interface
** (see the server/ui commands).
**
** See also the "close" command.
**
**
** SUMMARY: fossil open FILENAME ?VERSION? ?OPTIONS?
** Options: --keep, --nested
*/
void cmd_open(void){
  Blob path;
  int vid;
  int keepFlag;
  int allowNested;
  static char *azNewArgv[] = { 0, "checkout", "--prompt", 0, 0, 0 };
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689

1690
1691
1692
1693
1694
1695
1696
  { 0,0,0,0 }
};

/*
** COMMAND: settings
** COMMAND: unset
**
** %fossil settings ?PROPERTY? ?VALUE? ?-global?
** %fossil unset PROPERTY ?-global?
**
** The "settings" command with no arguments lists all properties and their
** values.  With just a property name it shows the value of that property.
** With a value argument it changes the property for the current repository.
**
** The "unset" command clears a property setting.
**
**
**    auto-captcha     If enabled, the Login page provides a button to
**                     fill in the captcha password.  Default: on
**
**    auto-shun        If enabled, automatically pull the shunning list

**                     from a server to which the client autosyncs.
**                     Default: on
**
**    autosync         If enabled, automatically pull prior to commit
**                     or update and automatically push after commit or
**                     tag or branch creation.  If the value is "pullonly"
**                     then only pull operations occur automatically.







|






|






>







1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
  { 0,0,0,0 }
};

/*
** COMMAND: settings
** COMMAND: unset
**
** %fossil settings ?PROPERTY? ?VALUE? ?--global?
** %fossil unset PROPERTY ?-global?
**
** The "settings" command with no arguments lists all properties and their
** values.  With just a property name it shows the value of that property.
** With a value argument it changes the property for the current repository.
**
** The "unset" command clears a property setting (restoring fossil's default).
**
**
**    auto-captcha     If enabled, the Login page provides a button to
**                     fill in the captcha password.  Default: on
**
**    auto-shun        If enabled, automatically pull the shunning list
**                     (for removing unwanted files and Wiki pages)
**                     from a server to which the client autosyncs.
**                     Default: on
**
**    autosync         If enabled, automatically pull prior to commit
**                     or update and automatically push after commit or
**                     tag or branch creation.  If the value is "pullonly"
**                     then only pull operations occur automatically.
1715
1716
1717
1718
1719
1720
1721

1722
1723
1724
1725
1726
1727
1728
**    diff-command     External command to run when performing a diff.
**                     If undefined, the internal text diff will be used.
**
**    dont-push        Prevent this repository from pushing from client to
**                     server.  Useful when setting up a private branch.
**
**    editor           Text editor command used for check-in comments.

**
**    gdiff-command    External command to run when performing a graphical
**                     diff. If undefined, text diff will be used.
**
**    gmerge-command   A graphical merge conflict resolver command operating
**                     on four files.
**                     Ex: kdiff3 "%baseline" "%original" "%merge" -o "%output"







>







1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
**    diff-command     External command to run when performing a diff.
**                     If undefined, the internal text diff will be used.
**
**    dont-push        Prevent this repository from pushing from client to
**                     server.  Useful when setting up a private branch.
**
**    editor           Text editor command used for check-in comments.
**                     (The default depends on the platform)
**
**    gdiff-command    External command to run when performing a graphical
**                     diff. If undefined, text diff will be used.
**
**    gmerge-command   A graphical merge conflict resolver command operating
**                     on four files.
**                     Ex: kdiff3 "%baseline" "%original" "%merge" -o "%output"
1777
1778
1779
1780
1781
1782
1783











1784
1785
1786
1787
1788
1789
1790
**    ssh-command      Command used to talk to a remote machine with
**                     the "ssh://" protocol.
**
**    web-browser      A shell command used to launch your preferred
**                     web browser when given a URL as an argument.
**                     Defaults to "start" on windows, "open" on Mac,
**                     and "firefox" on Unix.











*/
void setting_cmd(void){
  int i;
  int globalFlag = find_option("global","g",0)!=0;
  int unsetFlag = g.argv[1][0]=='u';
  db_open_config(1);
  if( !globalFlag ){







>
>
>
>
>
>
>
>
>
>
>







1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
**    ssh-command      Command used to talk to a remote machine with
**                     the "ssh://" protocol.
**
**    web-browser      A shell command used to launch your preferred
**                     web browser when given a URL as an argument.
**                     Defaults to "start" on windows, "open" on Mac,
**                     and "firefox" on Unix.
**
** SUMMARY: fossil settings ?PROPERTY? ?VALUE? ?OPTIONS?
**          fossil unset PROPERTY ?OPTIONS?
** Options: --global
** Where:   PROPERTY = auto-captcha, auto-shun, autosync, binary-glob,
**                     clearsign, crnl-glob, default-perms, diff-command,
**                     dont-push, editor, gdiff-command, gmerge-command,
**                     http-port, https-login, ignore-glob, localauth,
**                     main-branch, manifest, max-upload, mtime-changes,
**                     pgp-command, proxy, repo-cksum, self-register,
**                     ssh-command, web-browser
*/
void setting_cmd(void){
  int i;
  int globalFlag = find_option("global","g",0)!=0;
  int unsetFlag = g.argv[1][0]=='u';
  db_open_config(1);
  if( !globalFlag ){
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
** %fossil test-timespan TIMESTAMP
**
** Print the approximate span of time from now to TIMESTAMP.
*/
void test_timespan_cmd(void){
  double rDiff;
  if( g.argc!=3 ) usage("TIMESTAMP");
  sqlite3_open(":memory:", &g.db);  
  rDiff = db_double(0.0, "SELECT julianday('now') - julianday(%Q)", g.argv[2]);
  fossil_print("Time differences: %s\n", db_timespan_name(rDiff));
  sqlite3_close(g.db);
  g.db = 0;
}







|





1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
** %fossil test-timespan TIMESTAMP
**
** Print the approximate span of time from now to TIMESTAMP.
*/
void test_timespan_cmd(void){
  double rDiff;
  if( g.argc!=3 ) usage("TIMESTAMP");
  sqlite3_open(":memory:", &g.db);
  rDiff = db_double(0.0, "SELECT julianday('now') - julianday(%Q)", g.argv[2]);
  fossil_print("Time differences: %s\n", db_timespan_name(rDiff));
  sqlite3_close(g.db);
  g.db = 0;
}

Changes to src/descendants.c.

69
70
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
102
103
104
105
106
107
108
109
110
    /* Initialize the bags. */
    bag_init(&seen);
    bag_init(&pending);
    bag_insert(&pending, iBase);

    /* This query returns all non-branch-merge children of check-in :rid.
    **
    ** If a a child is a merge of a fork within the same branch, it is 
    ** returned.  Only merge children in different branches are excluded.
    */
    db_prepare(&q1,
      "SELECT cid FROM plink"
      " WHERE pid=:rid"
      "   AND (isprim"
      "        OR coalesce((SELECT value FROM tagxref"
                        "   WHERE tagid=%d AND rid=plink.pid), 'trunk')"
                 "=coalesce((SELECT value FROM tagxref"
                        "   WHERE tagid=%d AND rid=plink.cid), 'trunk'))",
      TAG_BRANCH, TAG_BRANCH
    );
  
    /* This query returns a single row if check-in :rid is the first
    ** check-in of a new branch.
    */
    db_prepare(&isBr, 
       "SELECT 1 FROM tagxref"
       " WHERE rid=:rid AND tagid=%d AND tagtype=2"
       "   AND srcid>0",
       TAG_BRANCH
    );
  
    /* This statement inserts check-in :rid into the LEAVES table.
    */
    db_prepare(&ins, "INSERT OR IGNORE INTO leaves VALUES(:rid)");
  
    while( bag_count(&pending) ){
      int rid = bag_first(&pending);
      int cnt = 0;
      bag_remove(&pending, rid);
      db_bind_int(&q1, ":rid", rid);
      while( db_step(&q1)==SQLITE_ROW ){
        int cid = db_column_int(&q1, 0);







|












|



|





|



|







69
70
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
102
103
104
105
106
107
108
109
110
    /* Initialize the bags. */
    bag_init(&seen);
    bag_init(&pending);
    bag_insert(&pending, iBase);

    /* This query returns all non-branch-merge children of check-in :rid.
    **
    ** If a a child is a merge of a fork within the same branch, it is
    ** returned.  Only merge children in different branches are excluded.
    */
    db_prepare(&q1,
      "SELECT cid FROM plink"
      " WHERE pid=:rid"
      "   AND (isprim"
      "        OR coalesce((SELECT value FROM tagxref"
                        "   WHERE tagid=%d AND rid=plink.pid), 'trunk')"
                 "=coalesce((SELECT value FROM tagxref"
                        "   WHERE tagid=%d AND rid=plink.cid), 'trunk'))",
      TAG_BRANCH, TAG_BRANCH
    );

    /* This query returns a single row if check-in :rid is the first
    ** check-in of a new branch.
    */
    db_prepare(&isBr,
       "SELECT 1 FROM tagxref"
       " WHERE rid=:rid AND tagid=%d AND tagtype=2"
       "   AND srcid>0",
       TAG_BRANCH
    );

    /* This statement inserts check-in :rid into the LEAVES table.
    */
    db_prepare(&ins, "INSERT OR IGNORE INTO leaves VALUES(:rid)");

    while( bag_count(&pending) ){
      int rid = bag_first(&pending);
      int cnt = 0;
      bag_remove(&pending, rid);
      db_bind_int(&q1, ":rid", rid);
      while( db_step(&q1)==SQLITE_ROW ){
        int cid = db_column_int(&q1, 0);
231
232
233
234
235
236
237



238
239
240
241
242
243
244
/*
** COMMAND:  descendants
**
** Usage: %fossil descendants ?BASELINE-ID?
**
** Find all leaf descendants of the baseline specified or if the argument
** is omitted, of the baseline currently checked out.



*/
void descendants_cmd(void){
  Stmt q;
  int base;

  db_must_be_within_tree();
  if( g.argc==2 ){







>
>
>







231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
/*
** COMMAND:  descendants
**
** Usage: %fossil descendants ?BASELINE-ID?
**
** Find all leaf descendants of the baseline specified or if the argument
** is omitted, of the baseline currently checked out.
**
**
** SUMMARY: fossil descendants ?BASELINE-ID?
*/
void descendants_cmd(void){
  Stmt q;
  int base;

  db_must_be_within_tree();
  if( g.argc==2 ){
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271




272
273
274
275
276
277
278
  print_timeline(&q, 20);
  db_finalize(&q);
}

/*
** COMMAND:  leaves
**
** Usage: %fossil leaves ?--all? ?--closed?
**
** Find leaves of all branches.  By default show only open leaves.
** The --all flag causes all leaves (closed and open) to be shown.
** The --closed flag shows only closed leaves.
**
** The --recompute flag causes the content of the "leaf" table in the
** repository database to be recomputed.




*/
void leaves_cmd(void){
  Stmt q;
  Blob sql;
  int showAll = find_option("all", 0, 0)!=0;
  int showClosed = find_option("closed", 0, 0)!=0;
  int recomputeFlag = find_option("recompute",0,0)!=0;







|







>
>
>
>







260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
  print_timeline(&q, 20);
  db_finalize(&q);
}

/*
** COMMAND:  leaves
**
** Usage: %fossil leaves ?--all? ?--closed? ?--recompute?
**
** Find leaves of all branches.  By default show only open leaves.
** The --all flag causes all leaves (closed and open) to be shown.
** The --closed flag shows only closed leaves.
**
** The --recompute flag causes the content of the "leaf" table in the
** repository database to be recomputed.
**
**
** SUMMARY: fossil leaves ?OPTIONS?
** Options: --all, --closed, --recompute
*/
void leaves_cmd(void){
  Stmt q;
  Blob sql;
  int showAll = find_option("all", 0, 0)!=0;
  int showClosed = find_option("closed", 0, 0)!=0;
  int recomputeFlag = find_option("recompute",0,0)!=0;

Changes to src/diff.c.

60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
  int nFrom;         /* Number of lines in aFrom[] */
  DLine *aTo;        /* File on right side of the diff */
  int nTo;           /* Number of lines in aTo[] */
};

/*
** Return an array of DLine objects containing a pointer to the
** start of each line and a hash of that line.  The lower 
** bits of the hash store the length of each line.
**
** Trailing whitespace is removed from each line.  2010-08-20:  Not any
** more.  If trailing whitespace is ignored, the "patch" command gets
** confused by the diff output.  Ticket [a9f7b23c2e376af5b0e5b]
**
** Return 0 if the file is binary or contains a line that is







|







60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
  int nFrom;         /* Number of lines in aFrom[] */
  DLine *aTo;        /* File on right side of the diff */
  int nTo;           /* Number of lines in aTo[] */
};

/*
** Return an array of DLine objects containing a pointer to the
** start of each line and a hash of that line.  The lower
** bits of the hash store the length of each line.
**
** Trailing whitespace is removed from each line.  2010-08-20:  Not any
** more.  If trailing whitespace is ignored, the "patch" command gets
** confused by the diff output.  Ticket [a9f7b23c2e376af5b0e5b]
**
** Return 0 if the file is binary or contains a line that is
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
        return;
      }
    }
    if( nCopy==0 && nDel==0 ){
      p->aEdit[p->nEdit-1] += nIns;
      return;
    }
  }  
  if( p->nEdit+3>p->nEditAlloc ){
    expandEdit(p, p->nEdit*2 + 15);
    if( p->aEdit==0 ) return;
  }
  p->aEdit[p->nEdit++] = nCopy;
  p->aEdit[p->nEdit++] = nDel;
  p->aEdit[p->nEdit++] = nIns;
}


/*
** Given a diff context in which the aEdit[] array has been filled
** in, compute a context diff into pOut.
*/
static void contextDiff(DContext *p, Blob *pOut, int nContext){
  DLine *A;     /* Left side of the diff */
  DLine *B;     /* Right side of the diff */  
  int a = 0;    /* Index of next line in A[] */
  int b = 0;    /* Index of next line in B[] */
  int *R;       /* Array of COPY/DELETE/INSERT triples */
  int r;        /* Index into R[] */
  int nr;       /* Number of COPY/DELETE/INSERT triples to process */
  int mxr;      /* Maximum value for r */
  int na, nb;   /* Number of lines shown from A and B */







|
















|







169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
        return;
      }
    }
    if( nCopy==0 && nDel==0 ){
      p->aEdit[p->nEdit-1] += nIns;
      return;
    }
  }
  if( p->nEdit+3>p->nEditAlloc ){
    expandEdit(p, p->nEdit*2 + 15);
    if( p->aEdit==0 ) return;
  }
  p->aEdit[p->nEdit++] = nCopy;
  p->aEdit[p->nEdit++] = nDel;
  p->aEdit[p->nEdit++] = nIns;
}


/*
** Given a diff context in which the aEdit[] array has been filled
** in, compute a context diff into pOut.
*/
static void contextDiff(DContext *p, Blob *pOut, int nContext){
  DLine *A;     /* Left side of the diff */
  DLine *B;     /* Right side of the diff */
  int a = 0;    /* Index of next line in A[] */
  int b = 0;    /* Index of next line in B[] */
  int *R;       /* Array of COPY/DELETE/INSERT triples */
  int r;        /* Index into R[] */
  int nr;       /* Number of COPY/DELETE/INSERT triples to process */
  int mxr;      /* Maximum value for r */
  int na, nb;   /* Number of lines shown from A and B */
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
** If there are two or more possible answers of the same length, the
** returned sequence should be the one closest to the center of the
** input range.
**
** Ideally, the common sequence should be the longest possible common
** sequence.  However, an exact computation of LCS is O(N*N) which is
** way too slow for larger files.  So this routine uses an O(N)
** heuristic approximation based on hashing that usually works about 
** as well.  But if the O(N) algorithm doesn't get a good solution
** and N is not too large, we fall back to an exact solution by
** calling optimalLCS().
*/
static void longestCommonSequence(
  DContext *p,               /* Two files being compared */
  int iS1, int iE1,          /* Range of lines in p->aFrom[] */







|







339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
** If there are two or more possible answers of the same length, the
** returned sequence should be the one closest to the center of the
** input range.
**
** Ideally, the common sequence should be the longest possible common
** sequence.  However, an exact computation of LCS is O(N*N) which is
** way too slow for larger files.  So this routine uses an O(N)
** heuristic approximation based on hashing that usually works about
** as well.  But if the O(N) algorithm doesn't get a good solution
** and N is not too large, we fall back to an exact solution by
** calling optimalLCS().
*/
static void longestCommonSequence(
  DContext *p,               /* Two files being compared */
  int iS1, int iE1,          /* Range of lines in p->aFrom[] */
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
  iEXb = iEXp = iS1;
  iSYb = iSYp = iS2;
  iEYb = iEYp = iS2;
  mid = (iE1 + iS1)/2;
  for(i=iS1; i<iE1; i++){
    int limit = 0;
    j = p->aTo[p->aFrom[i].h % p->nTo].iHash;
    while( j>0 
      && (j-1<iS2 || j>=iE2 || !same_dline(&p->aFrom[i], &p->aTo[j-1]))
    ){
      if( limit++ > 10 ){
        j = 0;
        break;
      }
      j = p->aTo[j-1].iNext;







|







370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
  iEXb = iEXp = iS1;
  iSYb = iSYp = iS2;
  iEYb = iEYp = iS2;
  mid = (iE1 + iS1)/2;
  for(i=iS1; i<iE1; i++){
    int limit = 0;
    j = p->aTo[p->aFrom[i].h % p->nTo].iHash;
    while( j>0
      && (j-1<iS2 || j>=iE2 || !same_dline(&p->aFrom[i], &p->aTo[j-1]))
    ){
      if( limit++ > 10 ){
        j = 0;
        break;
      }
      j = p->aTo[j-1].iNext;
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
    optimalLCS(p, iS1, iE1, iS2, iE2, piSX, piEX, piSY, piEY);
  }else{
    *piSX = iSXb;
    *piSY = iSYb;
    *piEX = iEXb;
    *piEY = iEYb;
  }
  /* printf("LCS(%d..%d/%d..%d) = %d..%d/%d..%d\n", 
     iS1, iE1, iS2, iE2, *piSX, *piEX, *piSY, *piEY);  */
}

/*
** Do a single step in the difference.  Compute a sequence of
** copy/delete/insert steps that will convert lines iS1 through iE1-1 of
** the input into lines iS2 through iE2-1 of the output and write







|







423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
    optimalLCS(p, iS1, iE1, iS2, iE2, piSX, piEX, piSY, piEY);
  }else{
    *piSX = iSXb;
    *piSY = iSYb;
    *piEX = iEXb;
    *piEY = iEYb;
  }
  /* printf("LCS(%d..%d/%d..%d) = %d..%d/%d..%d\n",
     iS1, iE1, iS2, iE2, *piSX, *piEX, *piSY, *piEY);  */
}

/*
** Do a single step in the difference.  Compute a sequence of
** copy/delete/insert steps that will convert lines iS1 through iE1-1 of
** the input into lines iS2 through iE2-1 of the output and write
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
  }
}

/*
** Generate a report of the differences between files pA and pB.
** If pOut is not NULL then a unified diff is appended there.  It
** is assumed that pOut has already been initialized.  If pOut is
** NULL, then a pointer to an array of integers is returned.  
** The integers come in triples.  For each triple,
** the elements are the number of lines copied, the number of
** lines deleted, and the number of lines inserted.  The vector
** is terminated by a triple of all zeros.
**
** This diff utility does not work on binary files.  If a binary
** file is encountered, 0 is returned and pOut is written with
** text "cannot compute difference between binary files".
*/
int *text_diff(
  Blob *pA_Blob,   /* FROM file */
  Blob *pB_Blob,   /* TO file */
  Blob *pOut,      /* Write unified diff here if not NULL */
  int nContext,    /* Amount of context to unified diff */
  int ignoreEolWs  /* Ignore whitespace at the end of lines */
){
  DContext c;
 
  /* Prepare the input files */
  memset(&c, 0, sizeof(c));
  c.aFrom = break_into_lines(blob_str(pA_Blob), blob_size(pA_Blob),
                             &c.nFrom, ignoreEolWs);
  c.aTo = break_into_lines(blob_str(pB_Blob), blob_size(pB_Blob),
                           &c.nTo, ignoreEolWs);
  if( c.aFrom==0 || c.aTo==0 ){







|

















|







523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
  }
}

/*
** Generate a report of the differences between files pA and pB.
** If pOut is not NULL then a unified diff is appended there.  It
** is assumed that pOut has already been initialized.  If pOut is
** NULL, then a pointer to an array of integers is returned.
** The integers come in triples.  For each triple,
** the elements are the number of lines copied, the number of
** lines deleted, and the number of lines inserted.  The vector
** is terminated by a triple of all zeros.
**
** This diff utility does not work on binary files.  If a binary
** file is encountered, 0 is returned and pOut is written with
** text "cannot compute difference between binary files".
*/
int *text_diff(
  Blob *pA_Blob,   /* FROM file */
  Blob *pB_Blob,   /* TO file */
  Blob *pOut,      /* Write unified diff here if not NULL */
  int nContext,    /* Amount of context to unified diff */
  int ignoreEolWs  /* Ignore whitespace at the end of lines */
){
  DContext c;

  /* Prepare the input files */
  memset(&c, 0, sizeof(c));
  c.aFrom = break_into_lines(blob_str(pA_Blob), blob_size(pA_Blob),
                             &c.nFrom, ignoreEolWs);
  c.aTo = break_into_lines(blob_str(pB_Blob), blob_size(pB_Blob),
                           &c.nTo, ignoreEolWs);
  if( c.aFrom==0 || c.aTo==0 ){
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
  /* Clear out the diff results */
  free(p->c.aEdit);
  p->c.aEdit = 0;
  p->c.nEdit = 0;
  p->c.nEditAlloc = 0;

  /* Clear out the from file */
  free(p->c.aFrom);    
  blob_zero(pParent);

  /* Return no errors */
  return 0;
}









|







708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
  /* Clear out the diff results */
  free(p->c.aEdit);
  p->c.aEdit = 0;
  p->c.nEdit = 0;
  p->c.nEditAlloc = 0;

  /* Clear out the from file */
  free(p->c.aFrom);
  blob_zero(pParent);

  /* Return no errors */
  return 0;
}


779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
  if( !content_get(rid, &toAnnotate) ){
    fossil_panic("unable to retrieve content of artifact #%d", rid);
  }
  db_multi_exec("CREATE TEMP TABLE ok(rid INTEGER PRIMARY KEY)");
  compute_ancestors(mid, 1000000000);
  annotation_start(p, &toAnnotate);

  db_prepare(&q, 
    "SELECT mlink.fid,"
    "       (SELECT uuid FROM blob WHERE rid=mlink.%s),"
    "       date(event.mtime), "
    "       coalesce(event.euser,event.user) "
    "  FROM mlink, event"
    " WHERE mlink.fnid=%d"
    "   AND mlink.mid IN ok"







|







779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
  if( !content_get(rid, &toAnnotate) ){
    fossil_panic("unable to retrieve content of artifact #%d", rid);
  }
  db_multi_exec("CREATE TEMP TABLE ok(rid INTEGER PRIMARY KEY)");
  compute_ancestors(mid, 1000000000);
  annotation_start(p, &toAnnotate);

  db_prepare(&q,
    "SELECT mlink.fid,"
    "       (SELECT uuid FROM blob WHERE rid=mlink.%s),"
    "       date(event.mtime), "
    "       coalesce(event.euser,event.user) "
    "  FROM mlink, event"
    " WHERE mlink.fnid=%d"
    "   AND mlink.mid IN ok"
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
  while( db_step(&q)==SQLITE_ROW ){
    int pid = db_column_int(&q, 0);
    const char *zUuid = db_column_text(&q, 1);
    const char *zDate = db_column_text(&q, 2);
    const char *zUser = db_column_text(&q, 3);
    if( webLabel ){
      zLabel = mprintf(
          "<a href='%s/info/%s' target='infowindow'>%.10s</a> %s %9.9s", 
          g.zTop, zUuid, zUuid, zDate, zUser
      );
    }else{
      zLabel = mprintf("%.10s %s %9.9s", zUuid, zDate, zUser);
    }
    p->nVers++;
    p->azVers = fossil_realloc(p->azVers, p->nVers*sizeof(p->azVers[0]) );







|







801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
  while( db_step(&q)==SQLITE_ROW ){
    int pid = db_column_int(&q, 0);
    const char *zUuid = db_column_text(&q, 1);
    const char *zDate = db_column_text(&q, 2);
    const char *zUser = db_column_text(&q, 3);
    if( webLabel ){
      zLabel = mprintf(
          "<a href='%s/info/%s' target='infowindow'>%.10s</a> %s %9.9s",
          g.zTop, zUuid, zUuid, zDate, zUser
      );
    }else{
      zLabel = mprintf("%.10s %s %9.9s", zUuid, zDate, zUser);
    }
    p->nVers++;
    p->azVers = fossil_realloc(p->azVers, p->nVers*sizeof(p->azVers[0]) );
877
878
879
880
881
882
883




884
885
886
887
888
889
890
** Output the text of a file with markings to show when each line of
** the file was last modified.
**
** Options:
**   --limit N       Only look backwards in time by N versions
**   --log           List all versions analyzed
**   --filevers      Show file version numbers rather than check-in versions




*/
void annotate_cmd(void){
  int fnid;         /* Filename ID */
  int fid;          /* File instance ID */
  int mid;          /* Manifest where file was checked in */
  Blob treename;    /* FILENAME translated to canonical form */
  char *zFilename;  /* Cannonical filename */







>
>
>
>







877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
** Output the text of a file with markings to show when each line of
** the file was last modified.
**
** Options:
**   --limit N       Only look backwards in time by N versions
**   --log           List all versions analyzed
**   --filevers      Show file version numbers rather than check-in versions
**
**
** SUMMARY: fossil annotate FILENAME ?options?
** Options: --limit N, --log, --filevers
*/
void annotate_cmd(void){
  int fnid;         /* Filename ID */
  int fid;          /* File instance ID */
  int mid;          /* Manifest where file was checked in */
  Blob treename;    /* FILENAME translated to canonical form */
  char *zFilename;  /* Cannonical filename */
924
925
926
927
928
929
930
931
932
933
934
  if( showLog ){
    for(i=0; i<ann.nVers; i++){
      printf("version %3d: %s\n", i+1, ann.azVers[i]);
    }
    printf("---------------------------------------------------\n");
  }
  for(i=0; i<ann.nOrig; i++){
    fossil_print("%s: %.*s\n", 
                 ann.aOrig[i].zSrc, ann.aOrig[i].n, ann.aOrig[i].z);
  }
}







|



928
929
930
931
932
933
934
935
936
937
938
  if( showLog ){
    for(i=0; i<ann.nVers; i++){
      printf("version %3d: %s\n", i+1, ann.azVers[i]);
    }
    printf("---------------------------------------------------\n");
  }
  for(i=0; i<ann.nOrig; i++){
    fossil_print("%s: %.*s\n",
                 ann.aOrig[i].zSrc, ann.aOrig[i].n, ann.aOrig[i].z);
  }
}

Changes to src/diffcmd.c.

410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435






436
437
438
439
440
441
442
** COMMAND: diff
** COMMAND: gdiff
**
** Usage: %fossil diff|gdiff ?options? ?FILE?
**
** Show the difference between the current version of FILE (as it
** exists on disk) and that same file as it was checked out.  Or
** if the FILE argument is omitted, show the unsaved changed currently
** in the working check-out.
**
** If the "--from VERSION" or "-r VERSION" option is used it specifies
** the source check-in for the diff operation.  If not specified, the 
** source check-in is the base check-in for the current check-out.
**
** If the "--to VERSION" option appears, it specifies the check-in from
** which the second version of the file or files is taken.  If there is
** no "--to" option then the (possibly edited) files in the current check-out
** are used.
**
** The "-i" command-line option forces the use of the internal diff logic
** rather than any external diff program that might be configured using
** the "setting" command.  If no external diff program is configured, then
** the "-i" option is a no-op.  The "-i" option converts "gdiff" into "diff".
**
** The "-N" or "--new-file" option causes the complete text of added or
** deleted files to be displayed.






*/
void diff_cmd(void){
  int isGDiff;               /* True for gdiff.  False for normal diff */
  int isInternDiff;          /* True for internal diff */
  int hasNFlag;              /* True if -N or --new-file flag is used */
  const char *zFrom;         /* Source version number */
  const char *zTo;           /* Target version number */







|



|














>
>
>
>
>
>







410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
** COMMAND: diff
** COMMAND: gdiff
**
** Usage: %fossil diff|gdiff ?options? ?FILE?
**
** Show the difference between the current version of FILE (as it
** exists on disk) and that same file as it was checked out.  Or
** if the FILE argument is omitted, show the unsaved changes currently
** in the working check-out.
**
** If the "--from VERSION" or "-r VERSION" option is used it specifies
** the source check-in for the diff operation.  If not specified, the
** source check-in is the base check-in for the current check-out.
**
** If the "--to VERSION" option appears, it specifies the check-in from
** which the second version of the file or files is taken.  If there is
** no "--to" option then the (possibly edited) files in the current check-out
** are used.
**
** The "-i" command-line option forces the use of the internal diff logic
** rather than any external diff program that might be configured using
** the "setting" command.  If no external diff program is configured, then
** the "-i" option is a no-op.  The "-i" option converts "gdiff" into "diff".
**
** The "-N" or "--new-file" option causes the complete text of added or
** deleted files to be displayed.
**
**
** SUMMARY: fossil diff ?options? ?FILE?
**          fossil gdiff ?options? ?FILE?
** Options: -i, --from VERSION, --to VERSION, -N|--new-file
**
*/
void diff_cmd(void){
  int isGDiff;               /* True for gdiff.  False for normal diff */
  int isInternDiff;          /* True for internal diff */
  int hasNFlag;              /* True if -N or --new-file flag is used */
  const char *zFrom;         /* Source version number */
  const char *zTo;           /* Target version number */

Changes to src/export.c.

84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99



100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
/*
** COMMAND: export
**
** Usage: %fossil export --git ?REPOSITORY?
**
** Write an export of all check-ins to standard output.  The export is
** written in the git-fast-export file format assuming the --git option is
** provided.  The git-fast-export format is currently the only VCS 
** interchange format supported, though other formats may be added in
** the future.
**
** Run this command within a checkout.  Or use the -R or --repository
** option to specify a Fossil repository to be exported.
**
** Only check-ins are exported using --git.  Git does not support tickets 
** or wiki or events or attachments, so none of those are exported.



*/
void export_cmd(void){
  Stmt q;
  int i;
  int firstCkin;       /* Integer offset to check-in marks */
  Bag blobs, vers;
  bag_init(&blobs);
  bag_init(&vers);

  find_option("git", 0, 0);   /* Ignore the --git option for now */
  db_find_and_open_repository(0, 2);
  verify_all_options();
  if( g.argc!=2 && g.argc!=3 ){ usage("--git ?REPOSITORY?"); }

  /* Step 1:  Generate "blob" records for every artifact that is part
  ** of a check-in 
  */
  fossil_binary_mode(stdout);
  db_prepare(&q, "SELECT DISTINCT fid FROM mlink WHERE fid>0");
  while( db_step(&q)==SQLITE_ROW ){
    int rid = db_column_int(&q, 0);
    Blob content;
    content_get(rid, &content);







|



|
|

|

>
>
>















|







84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
/*
** COMMAND: export
**
** Usage: %fossil export --git ?REPOSITORY?
**
** Write an export of all check-ins to standard output.  The export is
** written in the git-fast-export file format assuming the --git option is
** provided.  The git-fast-export format is currently the only VCS
** interchange format supported, though other formats may be added in
** the future.
**
** Run this command within a checkout or specify the name of the
** Fossil repository to be exported.
**
** Only check-ins are exported using --git.  Git does not support tickets
** or wiki or events or attachments, so none of those are exported.
**
**
** SUMMARY: fossil export --git ?REPOSITORY?
*/
void export_cmd(void){
  Stmt q;
  int i;
  int firstCkin;       /* Integer offset to check-in marks */
  Bag blobs, vers;
  bag_init(&blobs);
  bag_init(&vers);

  find_option("git", 0, 0);   /* Ignore the --git option for now */
  db_find_and_open_repository(0, 2);
  verify_all_options();
  if( g.argc!=2 && g.argc!=3 ){ usage("--git ?REPOSITORY?"); }

  /* Step 1:  Generate "blob" records for every artifact that is part
  ** of a check-in
  */
  fossil_binary_mode(stdout);
  db_prepare(&q, "SELECT DISTINCT fid FROM mlink WHERE fid>0");
  while( db_step(&q)==SQLITE_ROW ){
    int rid = db_column_int(&q, 0);
    Blob content;
    content_get(rid, &content);

Added win/Makefile.mingw_static.



























































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
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
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
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
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
#!/usr/bin/make
#
# This is a makefile for us on windows using mingw.
#
#### The toplevel directory of the source tree.  Fossil can be built
#    in a directory that is separate from the source tree.  Just change
#    the following to point from the build directory to the src/ folder.
#
SRCDIR = src

#### The directory into which object code files should be written.
#
#
OBJDIR = wbld

#### C Compiler and options for use in building executables that
#    will run on the platform that is doing the build.  This is used
#    to compile code-generator programs as part of the build process.
#    See TCC below for the C compiler for building the finished binary.
#
BCC = gcc

#### Enable HTTPS support via OpenSSL (links to libssl and libcrypto)
#
# FOSSIL_ENABLE_SSL=1

#### The directory in which the zlib compression library is installed.
#
#
ZLIBDIR = /programs/gnuwin32

#### C Compile and options for use in building executables that 
#    will run on the target platform.  This is usually the same
#    as BCC, unless you are cross-compiling.  This C compiler builds
#    the finished binary for fossil.  The BCC compiler above is used
#    for building intermediate code-generator tools.
#
TCC = gcc -Os -Wall -DFOSSIL_I18N=0 -Wl,-Bstatic -L$(ZLIBDIR)/lib -I$(ZLIBDIR)/include

# With HTTPS support
ifdef FOSSIL_ENABLE_SSL
TCC += -static -DFOSSIL_ENABLE_SSL=1
endif

#### Extra arguments for linking the finished binary.  Fossil needs
#    to link against the Z-Lib compression library.  There are no
#    other dependencies.  We sometimes add the -static option here
#    so that we can build a static executable that will run in a
#    chroot jail.
#
#LIB = -lz -lws2_32
# OpenSSL:
ifdef FOSSIL_ENABLE_SSL
LIB += -lssl -lcrypto -lgdi32
endif
LIB += -lmingwex -lz -lws2_32

#### Tcl shell for use in running the fossil testsuite.  This is only
#    used for testing.  If you do not run
#
TCLSH = tclsh

#### Nullsoft installer makensis location
#
MAKENSIS = "c:\Program Files\NSIS\makensis.exe"

#### Include a configuration file that can override any one of these settings.
#
-include config.w32

# STOP HERE
# You should not need to change anything below this line
#--------------------------------------------------------
XTCC = $(TCC) $(CFLAGS) -I. -I$(SRCDIR)

SRC = \
  $(SRCDIR)/add.c \
  $(SRCDIR)/allrepo.c \
  $(SRCDIR)/attach.c \
  $(SRCDIR)/bag.c \
  $(SRCDIR)/bisect.c \
  $(SRCDIR)/blob.c \
  $(SRCDIR)/branch.c \
  $(SRCDIR)/browse.c \
  $(SRCDIR)/captcha.c \
  $(SRCDIR)/cgi.c \
  $(SRCDIR)/checkin.c \
  $(SRCDIR)/checkout.c \
  $(SRCDIR)/clearsign.c \
  $(SRCDIR)/clone.c \
  $(SRCDIR)/comformat.c \
  $(SRCDIR)/configure.c \
  $(SRCDIR)/content.c \
  $(SRCDIR)/db.c \
  $(SRCDIR)/delta.c \
  $(SRCDIR)/deltacmd.c \
  $(SRCDIR)/descendants.c \
  $(SRCDIR)/diff.c \
  $(SRCDIR)/diffcmd.c \
  $(SRCDIR)/doc.c \
  $(SRCDIR)/encode.c \
  $(SRCDIR)/event.c \
  $(SRCDIR)/export.c \
  $(SRCDIR)/file.c \
  $(SRCDIR)/finfo.c \
  $(SRCDIR)/graph.c \
  $(SRCDIR)/gzip.c \
  $(SRCDIR)/http.c \
  $(SRCDIR)/http_socket.c \
  $(SRCDIR)/http_ssl.c \
  $(SRCDIR)/http_transport.c \
  $(SRCDIR)/import.c \
  $(SRCDIR)/info.c \
  $(SRCDIR)/leaf.c \
  $(SRCDIR)/login.c \
  $(SRCDIR)/main.c \
  $(SRCDIR)/manifest.c \
  $(SRCDIR)/md5.c \
  $(SRCDIR)/merge.c \
  $(SRCDIR)/merge3.c \
  $(SRCDIR)/name.c \
  $(SRCDIR)/path.c \
  $(SRCDIR)/pivot.c \
  $(SRCDIR)/popen.c \
  $(SRCDIR)/pqueue.c \
  $(SRCDIR)/printf.c \
  $(SRCDIR)/rebuild.c \
  $(SRCDIR)/report.c \
  $(SRCDIR)/rss.c \
  $(SRCDIR)/schema.c \
  $(SRCDIR)/search.c \
  $(SRCDIR)/setup.c \
  $(SRCDIR)/sha1.c \
  $(SRCDIR)/shun.c \
  $(SRCDIR)/skins.c \
  $(SRCDIR)/sqlcmd.c \
  $(SRCDIR)/stash.c \
  $(SRCDIR)/stat.c \
  $(SRCDIR)/style.c \
  $(SRCDIR)/sync.c \
  $(SRCDIR)/tag.c \
  $(SRCDIR)/tar.c \
  $(SRCDIR)/th_main.c \
  $(SRCDIR)/timeline.c \
  $(SRCDIR)/tkt.c \
  $(SRCDIR)/tktsetup.c \
  $(SRCDIR)/undo.c \
  $(SRCDIR)/update.c \
  $(SRCDIR)/url.c \
  $(SRCDIR)/user.c \
  $(SRCDIR)/verify.c \
  $(SRCDIR)/vfile.c \
  $(SRCDIR)/wiki.c \
  $(SRCDIR)/wikiformat.c \
  $(SRCDIR)/winhttp.c \
  $(SRCDIR)/xfer.c \
  $(SRCDIR)/zip.c

TRANS_SRC = \
  $(OBJDIR)/add_.c \
  $(OBJDIR)/allrepo_.c \
  $(OBJDIR)/attach_.c \
  $(OBJDIR)/bag_.c \
  $(OBJDIR)/bisect_.c \
  $(OBJDIR)/blob_.c \
  $(OBJDIR)/branch_.c \
  $(OBJDIR)/browse_.c \
  $(OBJDIR)/captcha_.c \
  $(OBJDIR)/cgi_.c \
  $(OBJDIR)/checkin_.c \
  $(OBJDIR)/checkout_.c \
  $(OBJDIR)/clearsign_.c \
  $(OBJDIR)/clone_.c \
  $(OBJDIR)/comformat_.c \
  $(OBJDIR)/configure_.c \
  $(OBJDIR)/content_.c \
  $(OBJDIR)/db_.c \
  $(OBJDIR)/delta_.c \
  $(OBJDIR)/deltacmd_.c \
  $(OBJDIR)/descendants_.c \
  $(OBJDIR)/diff_.c \
  $(OBJDIR)/diffcmd_.c \
  $(OBJDIR)/doc_.c \
  $(OBJDIR)/encode_.c \
  $(OBJDIR)/event_.c \
  $(OBJDIR)/export_.c \
  $(OBJDIR)/file_.c \
  $(OBJDIR)/finfo_.c \
  $(OBJDIR)/graph_.c \
  $(OBJDIR)/gzip_.c \
  $(OBJDIR)/http_.c \
  $(OBJDIR)/http_socket_.c \
  $(OBJDIR)/http_ssl_.c \
  $(OBJDIR)/http_transport_.c \
  $(OBJDIR)/import_.c \
  $(OBJDIR)/info_.c \
  $(OBJDIR)/leaf_.c \
  $(OBJDIR)/login_.c \
  $(OBJDIR)/main_.c \
  $(OBJDIR)/manifest_.c \
  $(OBJDIR)/md5_.c \
  $(OBJDIR)/merge_.c \
  $(OBJDIR)/merge3_.c \
  $(OBJDIR)/name_.c \
  $(OBJDIR)/path_.c \
  $(OBJDIR)/pivot_.c \
  $(OBJDIR)/popen_.c \
  $(OBJDIR)/pqueue_.c \
  $(OBJDIR)/printf_.c \
  $(OBJDIR)/rebuild_.c \
  $(OBJDIR)/report_.c \
  $(OBJDIR)/rss_.c \
  $(OBJDIR)/schema_.c \
  $(OBJDIR)/search_.c \
  $(OBJDIR)/setup_.c \
  $(OBJDIR)/sha1_.c \
  $(OBJDIR)/shun_.c \
  $(OBJDIR)/skins_.c \
  $(OBJDIR)/sqlcmd_.c \
  $(OBJDIR)/stash_.c \
  $(OBJDIR)/stat_.c \
  $(OBJDIR)/style_.c \
  $(OBJDIR)/sync_.c \
  $(OBJDIR)/tag_.c \
  $(OBJDIR)/tar_.c \
  $(OBJDIR)/th_main_.c \
  $(OBJDIR)/timeline_.c \
  $(OBJDIR)/tkt_.c \
  $(OBJDIR)/tktsetup_.c \
  $(OBJDIR)/undo_.c \
  $(OBJDIR)/update_.c \
  $(OBJDIR)/url_.c \
  $(OBJDIR)/user_.c \
  $(OBJDIR)/verify_.c \
  $(OBJDIR)/vfile_.c \
  $(OBJDIR)/wiki_.c \
  $(OBJDIR)/wikiformat_.c \
  $(OBJDIR)/winhttp_.c \
  $(OBJDIR)/xfer_.c \
  $(OBJDIR)/zip_.c

OBJ = \
 $(OBJDIR)/add.o \
 $(OBJDIR)/allrepo.o \
 $(OBJDIR)/attach.o \
 $(OBJDIR)/bag.o \
 $(OBJDIR)/bisect.o \
 $(OBJDIR)/blob.o \
 $(OBJDIR)/branch.o \
 $(OBJDIR)/browse.o \
 $(OBJDIR)/captcha.o \
 $(OBJDIR)/cgi.o \
 $(OBJDIR)/checkin.o \
 $(OBJDIR)/checkout.o \
 $(OBJDIR)/clearsign.o \
 $(OBJDIR)/clone.o \
 $(OBJDIR)/comformat.o \
 $(OBJDIR)/configure.o \
 $(OBJDIR)/content.o \
 $(OBJDIR)/db.o \
 $(OBJDIR)/delta.o \
 $(OBJDIR)/deltacmd.o \
 $(OBJDIR)/descendants.o \
 $(OBJDIR)/diff.o \
 $(OBJDIR)/diffcmd.o \
 $(OBJDIR)/doc.o \
 $(OBJDIR)/encode.o \
 $(OBJDIR)/event.o \
 $(OBJDIR)/export.o \
 $(OBJDIR)/file.o \
 $(OBJDIR)/finfo.o \
 $(OBJDIR)/graph.o \
 $(OBJDIR)/gzip.o \
 $(OBJDIR)/http.o \
 $(OBJDIR)/http_socket.o \
 $(OBJDIR)/http_ssl.o \
 $(OBJDIR)/http_transport.o \
 $(OBJDIR)/import.o \
 $(OBJDIR)/info.o \
 $(OBJDIR)/leaf.o \
 $(OBJDIR)/login.o \
 $(OBJDIR)/main.o \
 $(OBJDIR)/manifest.o \
 $(OBJDIR)/md5.o \
 $(OBJDIR)/merge.o \
 $(OBJDIR)/merge3.o \
 $(OBJDIR)/name.o \
 $(OBJDIR)/path.o \
 $(OBJDIR)/pivot.o \
 $(OBJDIR)/popen.o \
 $(OBJDIR)/pqueue.o \
 $(OBJDIR)/printf.o \
 $(OBJDIR)/rebuild.o \
 $(OBJDIR)/report.o \
 $(OBJDIR)/rss.o \
 $(OBJDIR)/schema.o \
 $(OBJDIR)/search.o \
 $(OBJDIR)/setup.o \
 $(OBJDIR)/sha1.o \
 $(OBJDIR)/shun.o \
 $(OBJDIR)/skins.o \
 $(OBJDIR)/sqlcmd.o \
 $(OBJDIR)/stash.o \
 $(OBJDIR)/stat.o \
 $(OBJDIR)/style.o \
 $(OBJDIR)/sync.o \
 $(OBJDIR)/tag.o \
 $(OBJDIR)/tar.o \
 $(OBJDIR)/th_main.o \
 $(OBJDIR)/timeline.o \
 $(OBJDIR)/tkt.o \
 $(OBJDIR)/tktsetup.o \
 $(OBJDIR)/undo.o \
 $(OBJDIR)/update.o \
 $(OBJDIR)/url.o \
 $(OBJDIR)/user.o \
 $(OBJDIR)/verify.o \
 $(OBJDIR)/vfile.o \
 $(OBJDIR)/wiki.o \
 $(OBJDIR)/wikiformat.o \
 $(OBJDIR)/winhttp.o \
 $(OBJDIR)/xfer.o \
 $(OBJDIR)/zip.o

APPNAME = fossil.exe
TRANSLATE   = $(subst /,\\,$(OBJDIR)/translate.exe)
MAKEHEADERS = $(subst /,\\,$(OBJDIR)/makeheaders.exe)
MKINDEX     = $(subst /,\\,$(OBJDIR)/mkindex.exe)
VERSION     = $(subst /,\\,$(OBJDIR)/version.exe)


all:	$(OBJDIR) $(APPNAME)

$(OBJDIR)/icon.o:	$(SRCDIR)/../win/icon.rc
	cp $(SRCDIR)/../win/icon.rc $(OBJDIR)
	windres $(OBJDIR)/icon.rc -o $(OBJDIR)/icon.o

install:	$(APPNAME)
	mv $(APPNAME) $(INSTALLDIR)

$(OBJDIR):
	mkdir $(OBJDIR)

$(OBJDIR)/translate:	$(SRCDIR)/translate.c
	$(BCC) -o $(OBJDIR)/translate $(SRCDIR)/translate.c

$(OBJDIR)/makeheaders:	$(SRCDIR)/makeheaders.c
	$(BCC) -o $(OBJDIR)/makeheaders $(SRCDIR)/makeheaders.c

$(OBJDIR)/mkindex:	$(SRCDIR)/mkindex.c
	$(BCC) -o $(OBJDIR)/mkindex $(SRCDIR)/mkindex.c

$(VERSION): $(SRCDIR)/../win/version.c
	$(BCC) -o $(OBJDIR)/version $(SRCDIR)/../win/version.c

# WARNING. DANGER. Running the testsuite modifies the repository the
# build is done from, i.e. the checkout belongs to. Do not sync/push
# the repository after running the tests.
test:	$(APPNAME)
	$(TCLSH) test/tester.tcl $(APPNAME)

$(OBJDIR)/VERSION.h:	$(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest $(VERSION)
	$(VERSION) $(SRCDIR)/../manifest.uuid $(SRCDIR)/../manifest >$(OBJDIR)/VERSION.h

EXTRAOBJ =  $(OBJDIR)/sqlite3.o  $(OBJDIR)/shell.o  $(OBJDIR)/th.o  $(OBJDIR)/th_lang.o

$(APPNAME):	$(OBJDIR)/headers $(OBJ) $(EXTRAOBJ) $(OBJDIR)/icon.o
	$(TCC) -o $(APPNAME) $(OBJ) $(EXTRAOBJ) $(LIB) $(OBJDIR)/icon.o

# This rule prevents make from using its default rules to try build
# an executable named "manifest" out of the file named "manifest.c"
#
$(SRCDIR)/../manifest:	
	# noop

# Requires msys to be installed in addition to the mingw, for the "rm"
# command.  "del" will not work here because it is not a separate command
# but a MSDOS-shell builtin.
#
clean:	
	rm -rf $(OBJDIR) $(APPNAME)

setup: $(OBJDIR) $(APPNAME)
	$(MAKENSIS) ./fossil.nsi


$(OBJDIR)/page_index.h: $(TRANS_SRC) $(OBJDIR)/mkindex
	$(MKINDEX) $(TRANS_SRC) >$@
$(OBJDIR)/headers:	$(OBJDIR)/page_index.h $(OBJDIR)/makeheaders $(OBJDIR)/VERSION.h
	$(MAKEHEADERS)  $(OBJDIR)/add_.c:$(OBJDIR)/add.h $(OBJDIR)/allrepo_.c:$(OBJDIR)/allrepo.h $(OBJDIR)/attach_.c:$(OBJDIR)/attach.h $(OBJDIR)/bag_.c:$(OBJDIR)/bag.h $(OBJDIR)/bisect_.c:$(OBJDIR)/bisect.h $(OBJDIR)/blob_.c:$(OBJDIR)/blob.h $(OBJDIR)/branch_.c:$(OBJDIR)/branch.h $(OBJDIR)/browse_.c:$(OBJDIR)/browse.h $(OBJDIR)/captcha_.c:$(OBJDIR)/captcha.h $(OBJDIR)/cgi_.c:$(OBJDIR)/cgi.h $(OBJDIR)/checkin_.c:$(OBJDIR)/checkin.h $(OBJDIR)/checkout_.c:$(OBJDIR)/checkout.h $(OBJDIR)/clearsign_.c:$(OBJDIR)/clearsign.h $(OBJDIR)/clone_.c:$(OBJDIR)/clone.h $(OBJDIR)/comformat_.c:$(OBJDIR)/comformat.h $(OBJDIR)/configure_.c:$(OBJDIR)/configure.h $(OBJDIR)/content_.c:$(OBJDIR)/content.h $(OBJDIR)/db_.c:$(OBJDIR)/db.h $(OBJDIR)/delta_.c:$(OBJDIR)/delta.h $(OBJDIR)/deltacmd_.c:$(OBJDIR)/deltacmd.h $(OBJDIR)/descendants_.c:$(OBJDIR)/descendants.h $(OBJDIR)/diff_.c:$(OBJDIR)/diff.h $(OBJDIR)/diffcmd_.c:$(OBJDIR)/diffcmd.h $(OBJDIR)/doc_.c:$(OBJDIR)/doc.h $(OBJDIR)/encode_.c:$(OBJDIR)/encode.h $(OBJDIR)/event_.c:$(OBJDIR)/event.h $(OBJDIR)/export_.c:$(OBJDIR)/export.h $(OBJDIR)/file_.c:$(OBJDIR)/file.h $(OBJDIR)/finfo_.c:$(OBJDIR)/finfo.h $(OBJDIR)/graph_.c:$(OBJDIR)/graph.h $(OBJDIR)/gzip_.c:$(OBJDIR)/gzip.h $(OBJDIR)/http_.c:$(OBJDIR)/http.h $(OBJDIR)/http_socket_.c:$(OBJDIR)/http_socket.h $(OBJDIR)/http_ssl_.c:$(OBJDIR)/http_ssl.h $(OBJDIR)/http_transport_.c:$(OBJDIR)/http_transport.h $(OBJDIR)/import_.c:$(OBJDIR)/import.h $(OBJDIR)/info_.c:$(OBJDIR)/info.h $(OBJDIR)/leaf_.c:$(OBJDIR)/leaf.h $(OBJDIR)/login_.c:$(OBJDIR)/login.h $(OBJDIR)/main_.c:$(OBJDIR)/main.h $(OBJDIR)/manifest_.c:$(OBJDIR)/manifest.h $(OBJDIR)/md5_.c:$(OBJDIR)/md5.h $(OBJDIR)/merge_.c:$(OBJDIR)/merge.h $(OBJDIR)/merge3_.c:$(OBJDIR)/merge3.h $(OBJDIR)/name_.c:$(OBJDIR)/name.h $(OBJDIR)/path_.c:$(OBJDIR)/path.h $(OBJDIR)/pivot_.c:$(OBJDIR)/pivot.h $(OBJDIR)/popen_.c:$(OBJDIR)/popen.h $(OBJDIR)/pqueue_.c:$(OBJDIR)/pqueue.h $(OBJDIR)/printf_.c:$(OBJDIR)/printf.h $(OBJDIR)/rebuild_.c:$(OBJDIR)/rebuild.h $(OBJDIR)/report_.c:$(OBJDIR)/report.h $(OBJDIR)/rss_.c:$(OBJDIR)/rss.h $(OBJDIR)/schema_.c:$(OBJDIR)/schema.h $(OBJDIR)/search_.c:$(OBJDIR)/search.h $(OBJDIR)/setup_.c:$(OBJDIR)/setup.h $(OBJDIR)/sha1_.c:$(OBJDIR)/sha1.h $(OBJDIR)/shun_.c:$(OBJDIR)/shun.h $(OBJDIR)/skins_.c:$(OBJDIR)/skins.h $(OBJDIR)/sqlcmd_.c:$(OBJDIR)/sqlcmd.h $(OBJDIR)/stash_.c:$(OBJDIR)/stash.h $(OBJDIR)/stat_.c:$(OBJDIR)/stat.h $(OBJDIR)/style_.c:$(OBJDIR)/style.h $(OBJDIR)/sync_.c:$(OBJDIR)/sync.h $(OBJDIR)/tag_.c:$(OBJDIR)/tag.h $(OBJDIR)/tar_.c:$(OBJDIR)/tar.h $(OBJDIR)/th_main_.c:$(OBJDIR)/th_main.h $(OBJDIR)/timeline_.c:$(OBJDIR)/timeline.h $(OBJDIR)/tkt_.c:$(OBJDIR)/tkt.h $(OBJDIR)/tktsetup_.c:$(OBJDIR)/tktsetup.h $(OBJDIR)/undo_.c:$(OBJDIR)/undo.h $(OBJDIR)/update_.c:$(OBJDIR)/update.h $(OBJDIR)/url_.c:$(OBJDIR)/url.h $(OBJDIR)/user_.c:$(OBJDIR)/user.h $(OBJDIR)/verify_.c:$(OBJDIR)/verify.h $(OBJDIR)/vfile_.c:$(OBJDIR)/vfile.h $(OBJDIR)/wiki_.c:$(OBJDIR)/wiki.h $(OBJDIR)/wikiformat_.c:$(OBJDIR)/wikiformat.h $(OBJDIR)/winhttp_.c:$(OBJDIR)/winhttp.h $(OBJDIR)/xfer_.c:$(OBJDIR)/xfer.h $(OBJDIR)/zip_.c:$(OBJDIR)/zip.h $(SRCDIR)/sqlite3.h $(SRCDIR)/th.h $(OBJDIR)/VERSION.h
	echo Done >$(OBJDIR)/headers

$(OBJDIR)/headers: Makefile
Makefile:
$(OBJDIR)/add_.c:	$(SRCDIR)/add.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/add.c >$(OBJDIR)/add_.c

$(OBJDIR)/add.o:	$(OBJDIR)/add_.c $(OBJDIR)/add.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/add.o -c $(OBJDIR)/add_.c

add.h:	$(OBJDIR)/headers
$(OBJDIR)/allrepo_.c:	$(SRCDIR)/allrepo.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/allrepo.c >$(OBJDIR)/allrepo_.c

$(OBJDIR)/allrepo.o:	$(OBJDIR)/allrepo_.c $(OBJDIR)/allrepo.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/allrepo.o -c $(OBJDIR)/allrepo_.c

allrepo.h:	$(OBJDIR)/headers
$(OBJDIR)/attach_.c:	$(SRCDIR)/attach.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/attach.c >$(OBJDIR)/attach_.c

$(OBJDIR)/attach.o:	$(OBJDIR)/attach_.c $(OBJDIR)/attach.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/attach.o -c $(OBJDIR)/attach_.c

attach.h:	$(OBJDIR)/headers
$(OBJDIR)/bag_.c:	$(SRCDIR)/bag.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/bag.c >$(OBJDIR)/bag_.c

$(OBJDIR)/bag.o:	$(OBJDIR)/bag_.c $(OBJDIR)/bag.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/bag.o -c $(OBJDIR)/bag_.c

bag.h:	$(OBJDIR)/headers
$(OBJDIR)/bisect_.c:	$(SRCDIR)/bisect.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/bisect.c >$(OBJDIR)/bisect_.c

$(OBJDIR)/bisect.o:	$(OBJDIR)/bisect_.c $(OBJDIR)/bisect.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/bisect.o -c $(OBJDIR)/bisect_.c

bisect.h:	$(OBJDIR)/headers
$(OBJDIR)/blob_.c:	$(SRCDIR)/blob.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/blob.c >$(OBJDIR)/blob_.c

$(OBJDIR)/blob.o:	$(OBJDIR)/blob_.c $(OBJDIR)/blob.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/blob.o -c $(OBJDIR)/blob_.c

blob.h:	$(OBJDIR)/headers
$(OBJDIR)/branch_.c:	$(SRCDIR)/branch.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/branch.c >$(OBJDIR)/branch_.c

$(OBJDIR)/branch.o:	$(OBJDIR)/branch_.c $(OBJDIR)/branch.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/branch.o -c $(OBJDIR)/branch_.c

branch.h:	$(OBJDIR)/headers
$(OBJDIR)/browse_.c:	$(SRCDIR)/browse.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/browse.c >$(OBJDIR)/browse_.c

$(OBJDIR)/browse.o:	$(OBJDIR)/browse_.c $(OBJDIR)/browse.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/browse.o -c $(OBJDIR)/browse_.c

browse.h:	$(OBJDIR)/headers
$(OBJDIR)/captcha_.c:	$(SRCDIR)/captcha.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/captcha.c >$(OBJDIR)/captcha_.c

$(OBJDIR)/captcha.o:	$(OBJDIR)/captcha_.c $(OBJDIR)/captcha.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/captcha.o -c $(OBJDIR)/captcha_.c

captcha.h:	$(OBJDIR)/headers
$(OBJDIR)/cgi_.c:	$(SRCDIR)/cgi.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/cgi.c >$(OBJDIR)/cgi_.c

$(OBJDIR)/cgi.o:	$(OBJDIR)/cgi_.c $(OBJDIR)/cgi.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/cgi.o -c $(OBJDIR)/cgi_.c

cgi.h:	$(OBJDIR)/headers
$(OBJDIR)/checkin_.c:	$(SRCDIR)/checkin.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/checkin.c >$(OBJDIR)/checkin_.c

$(OBJDIR)/checkin.o:	$(OBJDIR)/checkin_.c $(OBJDIR)/checkin.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/checkin.o -c $(OBJDIR)/checkin_.c

checkin.h:	$(OBJDIR)/headers
$(OBJDIR)/checkout_.c:	$(SRCDIR)/checkout.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/checkout.c >$(OBJDIR)/checkout_.c

$(OBJDIR)/checkout.o:	$(OBJDIR)/checkout_.c $(OBJDIR)/checkout.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/checkout.o -c $(OBJDIR)/checkout_.c

checkout.h:	$(OBJDIR)/headers
$(OBJDIR)/clearsign_.c:	$(SRCDIR)/clearsign.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/clearsign.c >$(OBJDIR)/clearsign_.c

$(OBJDIR)/clearsign.o:	$(OBJDIR)/clearsign_.c $(OBJDIR)/clearsign.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/clearsign.o -c $(OBJDIR)/clearsign_.c

clearsign.h:	$(OBJDIR)/headers
$(OBJDIR)/clone_.c:	$(SRCDIR)/clone.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/clone.c >$(OBJDIR)/clone_.c

$(OBJDIR)/clone.o:	$(OBJDIR)/clone_.c $(OBJDIR)/clone.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/clone.o -c $(OBJDIR)/clone_.c

clone.h:	$(OBJDIR)/headers
$(OBJDIR)/comformat_.c:	$(SRCDIR)/comformat.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/comformat.c >$(OBJDIR)/comformat_.c

$(OBJDIR)/comformat.o:	$(OBJDIR)/comformat_.c $(OBJDIR)/comformat.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/comformat.o -c $(OBJDIR)/comformat_.c

comformat.h:	$(OBJDIR)/headers
$(OBJDIR)/configure_.c:	$(SRCDIR)/configure.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/configure.c >$(OBJDIR)/configure_.c

$(OBJDIR)/configure.o:	$(OBJDIR)/configure_.c $(OBJDIR)/configure.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/configure.o -c $(OBJDIR)/configure_.c

configure.h:	$(OBJDIR)/headers
$(OBJDIR)/content_.c:	$(SRCDIR)/content.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/content.c >$(OBJDIR)/content_.c

$(OBJDIR)/content.o:	$(OBJDIR)/content_.c $(OBJDIR)/content.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/content.o -c $(OBJDIR)/content_.c

content.h:	$(OBJDIR)/headers
$(OBJDIR)/db_.c:	$(SRCDIR)/db.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/db.c >$(OBJDIR)/db_.c

$(OBJDIR)/db.o:	$(OBJDIR)/db_.c $(OBJDIR)/db.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/db.o -c $(OBJDIR)/db_.c

db.h:	$(OBJDIR)/headers
$(OBJDIR)/delta_.c:	$(SRCDIR)/delta.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/delta.c >$(OBJDIR)/delta_.c

$(OBJDIR)/delta.o:	$(OBJDIR)/delta_.c $(OBJDIR)/delta.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/delta.o -c $(OBJDIR)/delta_.c

delta.h:	$(OBJDIR)/headers
$(OBJDIR)/deltacmd_.c:	$(SRCDIR)/deltacmd.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/deltacmd.c >$(OBJDIR)/deltacmd_.c

$(OBJDIR)/deltacmd.o:	$(OBJDIR)/deltacmd_.c $(OBJDIR)/deltacmd.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/deltacmd.o -c $(OBJDIR)/deltacmd_.c

deltacmd.h:	$(OBJDIR)/headers
$(OBJDIR)/descendants_.c:	$(SRCDIR)/descendants.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/descendants.c >$(OBJDIR)/descendants_.c

$(OBJDIR)/descendants.o:	$(OBJDIR)/descendants_.c $(OBJDIR)/descendants.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/descendants.o -c $(OBJDIR)/descendants_.c

descendants.h:	$(OBJDIR)/headers
$(OBJDIR)/diff_.c:	$(SRCDIR)/diff.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/diff.c >$(OBJDIR)/diff_.c

$(OBJDIR)/diff.o:	$(OBJDIR)/diff_.c $(OBJDIR)/diff.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/diff.o -c $(OBJDIR)/diff_.c

diff.h:	$(OBJDIR)/headers
$(OBJDIR)/diffcmd_.c:	$(SRCDIR)/diffcmd.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/diffcmd.c >$(OBJDIR)/diffcmd_.c

$(OBJDIR)/diffcmd.o:	$(OBJDIR)/diffcmd_.c $(OBJDIR)/diffcmd.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/diffcmd.o -c $(OBJDIR)/diffcmd_.c

diffcmd.h:	$(OBJDIR)/headers
$(OBJDIR)/doc_.c:	$(SRCDIR)/doc.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/doc.c >$(OBJDIR)/doc_.c

$(OBJDIR)/doc.o:	$(OBJDIR)/doc_.c $(OBJDIR)/doc.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/doc.o -c $(OBJDIR)/doc_.c

doc.h:	$(OBJDIR)/headers
$(OBJDIR)/encode_.c:	$(SRCDIR)/encode.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/encode.c >$(OBJDIR)/encode_.c

$(OBJDIR)/encode.o:	$(OBJDIR)/encode_.c $(OBJDIR)/encode.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/encode.o -c $(OBJDIR)/encode_.c

encode.h:	$(OBJDIR)/headers
$(OBJDIR)/event_.c:	$(SRCDIR)/event.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/event.c >$(OBJDIR)/event_.c

$(OBJDIR)/event.o:	$(OBJDIR)/event_.c $(OBJDIR)/event.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/event.o -c $(OBJDIR)/event_.c

event.h:	$(OBJDIR)/headers
$(OBJDIR)/export_.c:	$(SRCDIR)/export.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/export.c >$(OBJDIR)/export_.c

$(OBJDIR)/export.o:	$(OBJDIR)/export_.c $(OBJDIR)/export.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/export.o -c $(OBJDIR)/export_.c

export.h:	$(OBJDIR)/headers
$(OBJDIR)/file_.c:	$(SRCDIR)/file.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/file.c >$(OBJDIR)/file_.c

$(OBJDIR)/file.o:	$(OBJDIR)/file_.c $(OBJDIR)/file.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/file.o -c $(OBJDIR)/file_.c

file.h:	$(OBJDIR)/headers
$(OBJDIR)/finfo_.c:	$(SRCDIR)/finfo.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/finfo.c >$(OBJDIR)/finfo_.c

$(OBJDIR)/finfo.o:	$(OBJDIR)/finfo_.c $(OBJDIR)/finfo.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/finfo.o -c $(OBJDIR)/finfo_.c

finfo.h:	$(OBJDIR)/headers
$(OBJDIR)/graph_.c:	$(SRCDIR)/graph.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/graph.c >$(OBJDIR)/graph_.c

$(OBJDIR)/graph.o:	$(OBJDIR)/graph_.c $(OBJDIR)/graph.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/graph.o -c $(OBJDIR)/graph_.c

graph.h:	$(OBJDIR)/headers
$(OBJDIR)/gzip_.c:	$(SRCDIR)/gzip.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/gzip.c >$(OBJDIR)/gzip_.c

$(OBJDIR)/gzip.o:	$(OBJDIR)/gzip_.c $(OBJDIR)/gzip.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/gzip.o -c $(OBJDIR)/gzip_.c

gzip.h:	$(OBJDIR)/headers
$(OBJDIR)/http_.c:	$(SRCDIR)/http.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/http.c >$(OBJDIR)/http_.c

$(OBJDIR)/http.o:	$(OBJDIR)/http_.c $(OBJDIR)/http.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/http.o -c $(OBJDIR)/http_.c

http.h:	$(OBJDIR)/headers
$(OBJDIR)/http_socket_.c:	$(SRCDIR)/http_socket.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/http_socket.c >$(OBJDIR)/http_socket_.c

$(OBJDIR)/http_socket.o:	$(OBJDIR)/http_socket_.c $(OBJDIR)/http_socket.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/http_socket.o -c $(OBJDIR)/http_socket_.c

http_socket.h:	$(OBJDIR)/headers
$(OBJDIR)/http_ssl_.c:	$(SRCDIR)/http_ssl.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/http_ssl.c >$(OBJDIR)/http_ssl_.c

$(OBJDIR)/http_ssl.o:	$(OBJDIR)/http_ssl_.c $(OBJDIR)/http_ssl.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/http_ssl.o -c $(OBJDIR)/http_ssl_.c

http_ssl.h:	$(OBJDIR)/headers
$(OBJDIR)/http_transport_.c:	$(SRCDIR)/http_transport.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/http_transport.c >$(OBJDIR)/http_transport_.c

$(OBJDIR)/http_transport.o:	$(OBJDIR)/http_transport_.c $(OBJDIR)/http_transport.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/http_transport.o -c $(OBJDIR)/http_transport_.c

http_transport.h:	$(OBJDIR)/headers
$(OBJDIR)/import_.c:	$(SRCDIR)/import.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/import.c >$(OBJDIR)/import_.c

$(OBJDIR)/import.o:	$(OBJDIR)/import_.c $(OBJDIR)/import.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/import.o -c $(OBJDIR)/import_.c

import.h:	$(OBJDIR)/headers
$(OBJDIR)/info_.c:	$(SRCDIR)/info.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/info.c >$(OBJDIR)/info_.c

$(OBJDIR)/info.o:	$(OBJDIR)/info_.c $(OBJDIR)/info.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/info.o -c $(OBJDIR)/info_.c

info.h:	$(OBJDIR)/headers
$(OBJDIR)/leaf_.c:	$(SRCDIR)/leaf.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/leaf.c >$(OBJDIR)/leaf_.c

$(OBJDIR)/leaf.o:	$(OBJDIR)/leaf_.c $(OBJDIR)/leaf.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/leaf.o -c $(OBJDIR)/leaf_.c

leaf.h:	$(OBJDIR)/headers
$(OBJDIR)/login_.c:	$(SRCDIR)/login.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/login.c >$(OBJDIR)/login_.c

$(OBJDIR)/login.o:	$(OBJDIR)/login_.c $(OBJDIR)/login.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/login.o -c $(OBJDIR)/login_.c

login.h:	$(OBJDIR)/headers
$(OBJDIR)/main_.c:	$(SRCDIR)/main.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/main.c >$(OBJDIR)/main_.c

$(OBJDIR)/main.o:	$(OBJDIR)/main_.c $(OBJDIR)/main.h $(OBJDIR)/page_index.h $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/main.o -c $(OBJDIR)/main_.c

main.h:	$(OBJDIR)/headers
$(OBJDIR)/manifest_.c:	$(SRCDIR)/manifest.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/manifest.c >$(OBJDIR)/manifest_.c

$(OBJDIR)/manifest.o:	$(OBJDIR)/manifest_.c $(OBJDIR)/manifest.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/manifest.o -c $(OBJDIR)/manifest_.c

manifest.h:	$(OBJDIR)/headers
$(OBJDIR)/md5_.c:	$(SRCDIR)/md5.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/md5.c >$(OBJDIR)/md5_.c

$(OBJDIR)/md5.o:	$(OBJDIR)/md5_.c $(OBJDIR)/md5.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/md5.o -c $(OBJDIR)/md5_.c

md5.h:	$(OBJDIR)/headers
$(OBJDIR)/merge_.c:	$(SRCDIR)/merge.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/merge.c >$(OBJDIR)/merge_.c

$(OBJDIR)/merge.o:	$(OBJDIR)/merge_.c $(OBJDIR)/merge.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/merge.o -c $(OBJDIR)/merge_.c

merge.h:	$(OBJDIR)/headers
$(OBJDIR)/merge3_.c:	$(SRCDIR)/merge3.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/merge3.c >$(OBJDIR)/merge3_.c

$(OBJDIR)/merge3.o:	$(OBJDIR)/merge3_.c $(OBJDIR)/merge3.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/merge3.o -c $(OBJDIR)/merge3_.c

merge3.h:	$(OBJDIR)/headers
$(OBJDIR)/name_.c:	$(SRCDIR)/name.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/name.c >$(OBJDIR)/name_.c

$(OBJDIR)/name.o:	$(OBJDIR)/name_.c $(OBJDIR)/name.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/name.o -c $(OBJDIR)/name_.c

name.h:	$(OBJDIR)/headers
$(OBJDIR)/path_.c:	$(SRCDIR)/path.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/path.c >$(OBJDIR)/path_.c

$(OBJDIR)/path.o:	$(OBJDIR)/path_.c $(OBJDIR)/path.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/path.o -c $(OBJDIR)/path_.c

path.h:	$(OBJDIR)/headers
$(OBJDIR)/pivot_.c:	$(SRCDIR)/pivot.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/pivot.c >$(OBJDIR)/pivot_.c

$(OBJDIR)/pivot.o:	$(OBJDIR)/pivot_.c $(OBJDIR)/pivot.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/pivot.o -c $(OBJDIR)/pivot_.c

pivot.h:	$(OBJDIR)/headers
$(OBJDIR)/popen_.c:	$(SRCDIR)/popen.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/popen.c >$(OBJDIR)/popen_.c

$(OBJDIR)/popen.o:	$(OBJDIR)/popen_.c $(OBJDIR)/popen.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/popen.o -c $(OBJDIR)/popen_.c

popen.h:	$(OBJDIR)/headers
$(OBJDIR)/pqueue_.c:	$(SRCDIR)/pqueue.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/pqueue.c >$(OBJDIR)/pqueue_.c

$(OBJDIR)/pqueue.o:	$(OBJDIR)/pqueue_.c $(OBJDIR)/pqueue.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/pqueue.o -c $(OBJDIR)/pqueue_.c

pqueue.h:	$(OBJDIR)/headers
$(OBJDIR)/printf_.c:	$(SRCDIR)/printf.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/printf.c >$(OBJDIR)/printf_.c

$(OBJDIR)/printf.o:	$(OBJDIR)/printf_.c $(OBJDIR)/printf.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/printf.o -c $(OBJDIR)/printf_.c

printf.h:	$(OBJDIR)/headers
$(OBJDIR)/rebuild_.c:	$(SRCDIR)/rebuild.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/rebuild.c >$(OBJDIR)/rebuild_.c

$(OBJDIR)/rebuild.o:	$(OBJDIR)/rebuild_.c $(OBJDIR)/rebuild.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/rebuild.o -c $(OBJDIR)/rebuild_.c

rebuild.h:	$(OBJDIR)/headers
$(OBJDIR)/report_.c:	$(SRCDIR)/report.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/report.c >$(OBJDIR)/report_.c

$(OBJDIR)/report.o:	$(OBJDIR)/report_.c $(OBJDIR)/report.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/report.o -c $(OBJDIR)/report_.c

report.h:	$(OBJDIR)/headers
$(OBJDIR)/rss_.c:	$(SRCDIR)/rss.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/rss.c >$(OBJDIR)/rss_.c

$(OBJDIR)/rss.o:	$(OBJDIR)/rss_.c $(OBJDIR)/rss.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/rss.o -c $(OBJDIR)/rss_.c

rss.h:	$(OBJDIR)/headers
$(OBJDIR)/schema_.c:	$(SRCDIR)/schema.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/schema.c >$(OBJDIR)/schema_.c

$(OBJDIR)/schema.o:	$(OBJDIR)/schema_.c $(OBJDIR)/schema.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/schema.o -c $(OBJDIR)/schema_.c

schema.h:	$(OBJDIR)/headers
$(OBJDIR)/search_.c:	$(SRCDIR)/search.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/search.c >$(OBJDIR)/search_.c

$(OBJDIR)/search.o:	$(OBJDIR)/search_.c $(OBJDIR)/search.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/search.o -c $(OBJDIR)/search_.c

search.h:	$(OBJDIR)/headers
$(OBJDIR)/setup_.c:	$(SRCDIR)/setup.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/setup.c >$(OBJDIR)/setup_.c

$(OBJDIR)/setup.o:	$(OBJDIR)/setup_.c $(OBJDIR)/setup.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/setup.o -c $(OBJDIR)/setup_.c

setup.h:	$(OBJDIR)/headers
$(OBJDIR)/sha1_.c:	$(SRCDIR)/sha1.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/sha1.c >$(OBJDIR)/sha1_.c

$(OBJDIR)/sha1.o:	$(OBJDIR)/sha1_.c $(OBJDIR)/sha1.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/sha1.o -c $(OBJDIR)/sha1_.c

sha1.h:	$(OBJDIR)/headers
$(OBJDIR)/shun_.c:	$(SRCDIR)/shun.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/shun.c >$(OBJDIR)/shun_.c

$(OBJDIR)/shun.o:	$(OBJDIR)/shun_.c $(OBJDIR)/shun.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/shun.o -c $(OBJDIR)/shun_.c

shun.h:	$(OBJDIR)/headers
$(OBJDIR)/skins_.c:	$(SRCDIR)/skins.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/skins.c >$(OBJDIR)/skins_.c

$(OBJDIR)/skins.o:	$(OBJDIR)/skins_.c $(OBJDIR)/skins.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/skins.o -c $(OBJDIR)/skins_.c

skins.h:	$(OBJDIR)/headers
$(OBJDIR)/sqlcmd_.c:	$(SRCDIR)/sqlcmd.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/sqlcmd.c >$(OBJDIR)/sqlcmd_.c

$(OBJDIR)/sqlcmd.o:	$(OBJDIR)/sqlcmd_.c $(OBJDIR)/sqlcmd.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/sqlcmd.o -c $(OBJDIR)/sqlcmd_.c

sqlcmd.h:	$(OBJDIR)/headers
$(OBJDIR)/stash_.c:	$(SRCDIR)/stash.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/stash.c >$(OBJDIR)/stash_.c

$(OBJDIR)/stash.o:	$(OBJDIR)/stash_.c $(OBJDIR)/stash.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/stash.o -c $(OBJDIR)/stash_.c

stash.h:	$(OBJDIR)/headers
$(OBJDIR)/stat_.c:	$(SRCDIR)/stat.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/stat.c >$(OBJDIR)/stat_.c

$(OBJDIR)/stat.o:	$(OBJDIR)/stat_.c $(OBJDIR)/stat.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/stat.o -c $(OBJDIR)/stat_.c

stat.h:	$(OBJDIR)/headers
$(OBJDIR)/style_.c:	$(SRCDIR)/style.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/style.c >$(OBJDIR)/style_.c

$(OBJDIR)/style.o:	$(OBJDIR)/style_.c $(OBJDIR)/style.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/style.o -c $(OBJDIR)/style_.c

style.h:	$(OBJDIR)/headers
$(OBJDIR)/sync_.c:	$(SRCDIR)/sync.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/sync.c >$(OBJDIR)/sync_.c

$(OBJDIR)/sync.o:	$(OBJDIR)/sync_.c $(OBJDIR)/sync.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/sync.o -c $(OBJDIR)/sync_.c

sync.h:	$(OBJDIR)/headers
$(OBJDIR)/tag_.c:	$(SRCDIR)/tag.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/tag.c >$(OBJDIR)/tag_.c

$(OBJDIR)/tag.o:	$(OBJDIR)/tag_.c $(OBJDIR)/tag.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/tag.o -c $(OBJDIR)/tag_.c

tag.h:	$(OBJDIR)/headers
$(OBJDIR)/tar_.c:	$(SRCDIR)/tar.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/tar.c >$(OBJDIR)/tar_.c

$(OBJDIR)/tar.o:	$(OBJDIR)/tar_.c $(OBJDIR)/tar.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/tar.o -c $(OBJDIR)/tar_.c

tar.h:	$(OBJDIR)/headers
$(OBJDIR)/th_main_.c:	$(SRCDIR)/th_main.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/th_main.c >$(OBJDIR)/th_main_.c

$(OBJDIR)/th_main.o:	$(OBJDIR)/th_main_.c $(OBJDIR)/th_main.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/th_main.o -c $(OBJDIR)/th_main_.c

th_main.h:	$(OBJDIR)/headers
$(OBJDIR)/timeline_.c:	$(SRCDIR)/timeline.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/timeline.c >$(OBJDIR)/timeline_.c

$(OBJDIR)/timeline.o:	$(OBJDIR)/timeline_.c $(OBJDIR)/timeline.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/timeline.o -c $(OBJDIR)/timeline_.c

timeline.h:	$(OBJDIR)/headers
$(OBJDIR)/tkt_.c:	$(SRCDIR)/tkt.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/tkt.c >$(OBJDIR)/tkt_.c

$(OBJDIR)/tkt.o:	$(OBJDIR)/tkt_.c $(OBJDIR)/tkt.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/tkt.o -c $(OBJDIR)/tkt_.c

tkt.h:	$(OBJDIR)/headers
$(OBJDIR)/tktsetup_.c:	$(SRCDIR)/tktsetup.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/tktsetup.c >$(OBJDIR)/tktsetup_.c

$(OBJDIR)/tktsetup.o:	$(OBJDIR)/tktsetup_.c $(OBJDIR)/tktsetup.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/tktsetup.o -c $(OBJDIR)/tktsetup_.c

tktsetup.h:	$(OBJDIR)/headers
$(OBJDIR)/undo_.c:	$(SRCDIR)/undo.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/undo.c >$(OBJDIR)/undo_.c

$(OBJDIR)/undo.o:	$(OBJDIR)/undo_.c $(OBJDIR)/undo.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/undo.o -c $(OBJDIR)/undo_.c

undo.h:	$(OBJDIR)/headers
$(OBJDIR)/update_.c:	$(SRCDIR)/update.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/update.c >$(OBJDIR)/update_.c

$(OBJDIR)/update.o:	$(OBJDIR)/update_.c $(OBJDIR)/update.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/update.o -c $(OBJDIR)/update_.c

update.h:	$(OBJDIR)/headers
$(OBJDIR)/url_.c:	$(SRCDIR)/url.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/url.c >$(OBJDIR)/url_.c

$(OBJDIR)/url.o:	$(OBJDIR)/url_.c $(OBJDIR)/url.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/url.o -c $(OBJDIR)/url_.c

url.h:	$(OBJDIR)/headers
$(OBJDIR)/user_.c:	$(SRCDIR)/user.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/user.c >$(OBJDIR)/user_.c

$(OBJDIR)/user.o:	$(OBJDIR)/user_.c $(OBJDIR)/user.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/user.o -c $(OBJDIR)/user_.c

user.h:	$(OBJDIR)/headers
$(OBJDIR)/verify_.c:	$(SRCDIR)/verify.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/verify.c >$(OBJDIR)/verify_.c

$(OBJDIR)/verify.o:	$(OBJDIR)/verify_.c $(OBJDIR)/verify.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/verify.o -c $(OBJDIR)/verify_.c

verify.h:	$(OBJDIR)/headers
$(OBJDIR)/vfile_.c:	$(SRCDIR)/vfile.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/vfile.c >$(OBJDIR)/vfile_.c

$(OBJDIR)/vfile.o:	$(OBJDIR)/vfile_.c $(OBJDIR)/vfile.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/vfile.o -c $(OBJDIR)/vfile_.c

vfile.h:	$(OBJDIR)/headers
$(OBJDIR)/wiki_.c:	$(SRCDIR)/wiki.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/wiki.c >$(OBJDIR)/wiki_.c

$(OBJDIR)/wiki.o:	$(OBJDIR)/wiki_.c $(OBJDIR)/wiki.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/wiki.o -c $(OBJDIR)/wiki_.c

wiki.h:	$(OBJDIR)/headers
$(OBJDIR)/wikiformat_.c:	$(SRCDIR)/wikiformat.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/wikiformat.c >$(OBJDIR)/wikiformat_.c

$(OBJDIR)/wikiformat.o:	$(OBJDIR)/wikiformat_.c $(OBJDIR)/wikiformat.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/wikiformat.o -c $(OBJDIR)/wikiformat_.c

wikiformat.h:	$(OBJDIR)/headers
$(OBJDIR)/winhttp_.c:	$(SRCDIR)/winhttp.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/winhttp.c >$(OBJDIR)/winhttp_.c

$(OBJDIR)/winhttp.o:	$(OBJDIR)/winhttp_.c $(OBJDIR)/winhttp.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/winhttp.o -c $(OBJDIR)/winhttp_.c

winhttp.h:	$(OBJDIR)/headers
$(OBJDIR)/xfer_.c:	$(SRCDIR)/xfer.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/xfer.c >$(OBJDIR)/xfer_.c

$(OBJDIR)/xfer.o:	$(OBJDIR)/xfer_.c $(OBJDIR)/xfer.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/xfer.o -c $(OBJDIR)/xfer_.c

xfer.h:	$(OBJDIR)/headers
$(OBJDIR)/zip_.c:	$(SRCDIR)/zip.c $(OBJDIR)/translate
	$(TRANSLATE) $(SRCDIR)/zip.c >$(OBJDIR)/zip_.c

$(OBJDIR)/zip.o:	$(OBJDIR)/zip_.c $(OBJDIR)/zip.h  $(SRCDIR)/config.h
	$(XTCC) -o $(OBJDIR)/zip.o -c $(OBJDIR)/zip_.c

zip.h:	$(OBJDIR)/headers
$(OBJDIR)/sqlite3.o:	$(SRCDIR)/sqlite3.c
	$(XTCC) -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_THREADSAFE=0 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_STAT2 -Dlocaltime=fossil_localtime -DSQLITE_ENABLE_LOCKING_STYLE=0 -c $(SRCDIR)/sqlite3.c -o $(OBJDIR)/sqlite3.o

$(OBJDIR)/shell.o:	$(SRCDIR)/shell.c
	$(XTCC) -Dmain=sqlite3_shell -DSQLITE_OMIT_LOAD_EXTENSION=1 -c $(SRCDIR)/shell.c -o $(OBJDIR)/shell.o

$(OBJDIR)/th.o:	$(SRCDIR)/th.c
	$(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th.c -o $(OBJDIR)/th.o

$(OBJDIR)/th_lang.o:	$(SRCDIR)/th_lang.c
	$(XTCC) -I$(SRCDIR) -c $(SRCDIR)/th_lang.c -o $(OBJDIR)/th_lang.o