1 <?xml version="1.0" encoding="UTF-8"?>
\r
2 <!DOCTYPE chapter SYSTEM "../../dtd/dblite.dtd">
\r
3 <chapter id="tsvn-subwcrev">
\r
4 <title>The SubWCRev Program</title>
\r
7 <primary>version extraction</primary>
\r
10 <primary>SubWCRev</primary>
\r
13 <primary>COM</primary>
\r
16 <primary>version number in files</primary>
\r
19 SubWCRev is Windows console program which can be used to read
\r
20 the status of a Git working copy and optionally perform
\r
21 keyword substitution in a template file.
\r
22 This is often used as part of the build process as a means of
\r
23 incorporating working copy information into the object you
\r
24 are building. Typically it might be used to include the
\r
25 revision number in an <quote>About</quote> box.
\r
28 <!-- ================================================================= -->
\r
29 <!-- ======================== SECTION 1 ============================== -->
\r
30 <!-- ================================================================= -->
\r
31 <sect1 id="tsvn-subwcrev-cli">
\r
32 <title>The SubWCRev Command Line</title>
\r
34 SubWCRev reads the Git status of all files in a working
\r
35 copy, excluding externals by default. It records the highest commit
\r
36 revision number found, and the commit timestamp of that revision,
\r
37 It also records whether there are local modifications in the working
\r
38 copy, or mixed update revisions. The revision number, update
\r
39 revision range and modification status are displayed on stdout.
\r
42 SubWCRev.exe is called from the command line or a script, and
\r
43 is controlled using the command line parameters.
\r
45 SubWCRev WorkingCopyPath [SrcVersionFile DstVersionFile] [-nmdfe]
\r
49 <literal>WorkingCopyPath</literal> is the path to the working
\r
50 copy being checked. You can only use SubWCRev on working copies,
\r
51 not directly on the repository. The path may be absolute or
\r
52 relative to the current working directory.
\r
55 If you want SubWCRev to perform keyword substitution, so that
\r
56 fields like repository revision and URL are saved to a text
\r
57 file, you need to supply a template file
\r
58 <literal>SrcVersionFile</literal>
\r
60 <literal>DstVersionFile</literal>
\r
61 which contains the substituted version of the template.
\r
64 There are a number of optional switches which affect the way
\r
65 SubWCRev works. If you use more than one, they must be specified
\r
66 as a single group, eg.
\r
67 <literal>-nm</literal>, not
\r
68 <literal>-n -m</literal>.
\r
69 <table id="tsvn-subwcrev-switch-table">
\r
70 <title>List of available command line switches</title>
\r
72 <colspec colnum="1" colwidth="2*"/>
\r
73 <colspec colnum="2" colwidth="10*"/>
\r
76 <entry>Switch</entry>
\r
77 <entry>Description</entry>
\r
82 <entry condition="pot">-n</entry>
\r
84 If this switch is given, SubWCRev will exit with
\r
85 <literal>ERRORLEVEL 7</literal> if the working copy
\r
86 contains local modifications. This may be used to
\r
87 prevent building with uncommitted changes present.
\r
91 <entry condition="pot">-m</entry>
\r
93 If this switch is given, SubWCRev will exit with
\r
94 <literal>ERRORLEVEL 8</literal> if the working copy
\r
95 contains mixed revisions. This may be used to prevent
\r
96 building with a partially updated working copy.
\r
100 <entry condition="pot">-d</entry>
\r
102 If this switch is given, SubWCRev will exit with
\r
103 <literal>ERRORLEVEL 9</literal> if the destination file
\r
108 <entry condition="pot">-f</entry>
\r
110 If this switch is given, SubWCRev will include
\r
111 the last-changed revision of folders. The default
\r
112 behaviour is to use only files when getting the
\r
117 <entry condition="pot">-e</entry>
\r
119 If this switch is given, SubWCRev will examine
\r
120 directories which are included with
\r
121 <literal>svn:externals</literal>,
\r
122 but only if they are from the same repository.
\r
123 The default behaviour is to ignore externals.
\r
127 <entry condition="pot">-x</entry>
\r
129 If this switch is given, SubWCRev will
\r
130 output the revision numbers in HEX.
\r
134 <entry condition="pot">-X</entry>
\r
136 If this switch is given, SubWCRev will
\r
137 output the revision numbers in HEX, with
\r
146 <!-- ================================================================= -->
\r
147 <!-- ======================== SECTION 2 ============================== -->
\r
148 <!-- ================================================================= -->
\r
149 <sect1 id="tsvn-subwcrev-keywords">
\r
150 <title>Keyword Substitution</title>
\r
152 If a source and destination files are supplied, SubWCRev copies
\r
153 source to destination, performing keyword substitution as follows:
\r
154 <table id="tsvn-subwcrev-switch-table2">
\r
155 <title>List of available command line switches</title>
\r
157 <colspec colnum="1" colwidth="3*"/>
\r
158 <colspec colnum="2" colwidth="7*"/>
\r
161 <entry>Keyword</entry>
\r
162 <entry>Description</entry>
\r
167 <entry condition="pot">$WCREV$</entry>
\r
169 Replaced with the highest commit revision
\r
170 in the working copy.
\r
174 <entry condition="pot">$WCDATE$</entry>
\r
176 Replaced with the commit date/time of the
\r
177 highest commit revision. By default,
\r
178 international format is used:
\r
179 <literal>yyyy-mm-dd hh:mm:ss</literal>.
\r
180 Alternatively, you can specify a custom format which
\r
181 will be used with <literal>strftime()</literal>,
\r
183 <literal>$WCDATE=%a %b %d %I:%M:%S %p$</literal>.
\r
184 For a list of available formatting characters, look at the
\r
185 <ulink url="http://www.cppreference.com/stddate/strftime.html">
\r
186 <citetitle>online reference</citetitle>
\r
191 <entry condition="pot">$WCNOW$</entry>
\r
193 Replaced with the current system date/time.
\r
194 This can be used to indicate the build time.
\r
195 Time formatting can be used as described for
\r
196 <literal>$WCDATE$</literal>.
\r
200 <entry condition="pot">$WCRANGE$</entry>
\r
202 Replaced with the update revision range in
\r
203 the working copy. If the working copy is in a
\r
204 consistent state, this will be a single revision.
\r
205 If the working copy contains mixed revisions,
\r
206 either due to being out of date, or due to a
\r
207 deliberate update-to-revision, then the range
\r
208 will be shown in the form 100:200
\r
212 <entry condition="pot">$WCMIXED$</entry>
\r
214 <literal>$WCMIXED?TText:FText$</literal> is
\r
215 replaced with <literal>TText</literal> if there are mixed update
\r
216 revisions, or <literal>FText</literal> if not.
\r
220 <entry condition="pot">$WCMODS$</entry>
\r
222 <literal>$WCMODS?TText:FText$</literal> is
\r
223 replaced with <literal>TText</literal> if there are local
\r
224 modifications, or <literal>FText</literal> if not.
\r
228 <entry condition="pot">$WCURL$</entry>
\r
230 Replaced with the repository URL of the working
\r
231 copy path passed to SubWCRev.
\r
235 <entry condition="pot">$WCINSVN$</entry>
\r
237 <literal>$WCINSVN?TText:FText$</literal> is
\r
238 replaced with <literal>TText</literal> if the entry is versioned,
\r
239 or <literal>FText</literal> if not.
\r
243 <entry condition="pot">$WCNEEDSLOCK$</entry>
\r
245 <literal>$WCNEEDSLOCK?TText:FText$</literal> is
\r
246 replaced with <literal>TText</literal> if the entry has
\r
247 the <literal>svn:needs-lock</literal> property set,
\r
248 or <literal>FText</literal> if not.
\r
252 <entry condition="pot">$WCISLOCKED$</entry>
\r
254 <literal>$WCISLOCKED?TText:FText$</literal> is
\r
255 replaced with <literal>TText</literal> if the entry is locked,
\r
256 or <literal>FText</literal> if not.
\r
260 <entry condition="pot">$WCLOCKDATE$</entry>
\r
262 Replaced with the lock date.
\r
263 Time formatting can be used as described for
\r
264 <literal>$WCDATE$</literal>.
\r
268 <entry condition="pot">$WCLOCKOWNER$</entry>
\r
270 Replaced with the name of the lock owner.
\r
274 <entry condition="pot">$WCLOCKCOMMENT$</entry>
\r
276 Replaced with the comment of the lock.
\r
284 <!-- ================================================================= -->
\r
285 <!-- ======================== SECTION 3 ============================== -->
\r
286 <!-- ================================================================= -->
\r
287 <sect1 id="tsvn-subwcrev-example">
\r
288 <title>Keyword Example</title>
\r
290 The example below shows how keywords in a template file are
\r
291 substituted in the output file.
\r
294 // Test file for SubWCRev: testfile.tmpl
\r
296 char *Revision = "$WCREV$";
\r
297 char *Modified = "$WCMODS?Modified:Not modified$";
\r
298 char *Date = "$WCDATE$";
\r
299 char *Range = "$WCRANGE$";
\r
300 char *Mixed = "$WCMIXED?Mixed revision WC:Not mixed$";
\r
301 char *URL = "$WCURL$";
\r
304 #error Source is modified
\r
310 After running <literal>SubWCRev.exe path\to\workingcopy testfile.tmpl testfile.txt</literal>,
\r
311 the output file <literal>testfile.txt</literal> would looks like this:
\r
314 // Test file for SubWCRev: testfile.txt
\r
316 char *Revision = "3701";
\r
317 char *Modified = "Modified";
\r
318 char *Date = "2005/06/15 11:15:12";
\r
319 char *Range = "3699:3701";
\r
320 char *Mixed = "Mixed revision WC";
\r
321 char *URL = "http://project.domain.org/svn/trunk/src";
\r
324 #error Source is modified
\r
331 A file like this will be included in the build so you would expect it
\r
332 to be versioned. Be sure to version the template file, not the
\r
333 generated file, otherwise each time you regenerate the version file
\r
334 you need to commit the change, which in turn means the version file
\r
335 needs to be updated.
\r
339 <!-- ================================================================= -->
\r
340 <!-- ======================== SECTION 4 ============================== -->
\r
341 <!-- ================================================================= -->
\r
342 <sect1 id="tsvn-subwcrev-com-interface">
\r
343 <title>COM interface</title>
\r
345 <primary>COM SubWCRev interface</primary>
\r
348 If you need to access Git revision information from other
\r
349 programs, you can use the COM interface of SubWCRev. The object to
\r
350 create is <literal>SubWCRev.object</literal>, and the following
\r
351 methods are supported:
\r
352 <table id="tsvn-subwcrev-COM-table">
\r
353 <title>COM/automation methods supported</title>
\r
355 <colspec colnum="1" colwidth="3*"/>
\r
356 <colspec colnum="2" colwidth="7*"/>
\r
359 <entry>Method</entry>
\r
360 <entry>Description</entry>
\r
365 <entry condition="pot">.GetWCInfo</entry>
\r
367 This method traverses the working copy gathering the
\r
368 revision information. Naturally you must call this before
\r
369 you can access the information using the remaining methods.
\r
370 The first parameter is the path.
\r
371 The second parameter should be true if you want to include
\r
372 folder revisions. Equivalent to the <literal>-f</literal>
\r
373 command line switch.
\r
374 The third parameter should be true if you want to include
\r
375 svn:externals. Equivalent to the <literal>-e</literal>
\r
376 command line switch.
\r
380 <entry condition="pot">.Revision</entry>
\r
382 The highest commit revision in the working copy.
\r
383 Equivalent to <literal>$WCREV$</literal>
\r
387 <entry condition="pot">.Date</entry>
\r
389 The commit date/time of the highest commit revision.
\r
390 Equivalent to <literal>$WCDATE$</literal>
\r
394 <entry condition="pot">.Author</entry>
\r
396 The author of the highest commit revision, that is, the
\r
397 last person to commit changes to the working copy.
\r
401 <entry condition="pot">.MinRev</entry>
\r
402 <entry>The minimum update revision, as shown in <literal>$WCRANGE$</literal></entry>
\r
405 <entry condition="pot">.MaxRev</entry>
\r
406 <entry>The maximum update revision, as shown in <literal>$WCRANGE$</literal></entry>
\r
409 <entry condition="pot">.HasModifications</entry>
\r
410 <entry>True if there are local modifications</entry>
\r
413 <entry condition="pot">.Url</entry>
\r
415 Replaced with the repository URL of the working
\r
416 copy path used in <literal>GetWCInfo</literal>.
\r
417 Equivalent to <literal>$WCURL$</literal>
\r
421 <entry condition="pot">.IsSvnItem</entry>
\r
423 True if the item is versioned.
\r
427 <entry condition="pot">.NeedsLocking</entry>
\r
429 True if the item has the <literal>svn:needs-lock</literal>
\r
434 <entry condition="pot">.IsLocked</entry>
\r
436 True if the item is locked.
\r
440 <entry condition="pot">.LockCreationDate</entry>
\r
442 String representing the date when the lock was
\r
443 created, or an empty string if the item is not locked.
\r
447 <entry condition="pot">.LockOwner</entry>
\r
449 String representing the lock owner, or an empty
\r
450 string if the item is not locked.
\r
454 <entry condition="pot">.LockComment</entry>
\r
456 The message entered when the lock was created.
\r
464 The following example shows how the interface might be used.
\r
466 // testCOM.js - javascript file
\r
467 // test script for the SubWCRev COM/Automation-object
\r
469 filesystem = new ActiveXObject("Scripting.FileSystemObject");
\r
471 revObject1 = new ActiveXObject("SubWCRev.object");
\r
472 revObject2 = new ActiveXObject("SubWCRev.object");
\r
473 revObject3 = new ActiveXObject("SubWCRev.object");
\r
474 revObject4 = new ActiveXObject("SubWCRev.object");
\r
476 revObject1.GetWCInfo(
\r
477 filesystem.GetAbsolutePathName("."), 1, 1);
\r
478 revObject2.GetWCInfo(
\r
479 filesystem.GetAbsolutePathName(".."), 1, 1);
\r
480 revObject3.GetWCInfo(
\r
481 filesystem.GetAbsolutePathName("SubWCRev.cpp"), 1, 1);
\r
482 revObject4.GetWCInfo(
\r
483 filesystem.GetAbsolutePathName("..\\.."), 1, 1);
\r
485 wcInfoString1 = "Revision = " + revObject1.Revision +
\r
486 "\nMin Revision = " + revObject1.MinRev +
\r
487 "\nMax Revision = " + revObject1.MaxRev +
\r
488 "\nDate = " + revObject1.Date +
\r
489 "\nURL = " + revObject1.Url + "\nAuthor = " +
\r
490 revObject1.Author + "\nHasMods = " +
\r
491 revObject1.HasModifications + "\nIsSvnItem = " +
\r
492 revObject1.IsSvnItem + "\nNeedsLocking = " +
\r
493 revObject1.NeedsLocking + "\nIsLocked = " +
\r
494 revObject1.IsLocked + "\nLockCreationDate = " +
\r
495 revObject1.LockCreationDate + "\nLockOwner = " +
\r
496 revObject1.LockOwner + "\nLockComment = " +
\r
497 revObject1.LockComment;
\r
498 wcInfoString2 = "Revision = " + revObject2.Revision +
\r
499 "\nMin Revision = " + revObject2.MinRev +
\r
500 "\nMax Revision = " + revObject2.MaxRev +
\r
501 "\nDate = " + revObject2.Date +
\r
502 "\nURL = " + revObject2.Url + "\nAuthor = " +
\r
503 revObject2.Author + "\nHasMods = " +
\r
504 revObject2.HasModifications + "\nIsSvnItem = " +
\r
505 revObject2.IsSvnItem + "\nNeedsLocking = " +
\r
506 revObject2.NeedsLocking + "\nIsLocked = " +
\r
507 revObject2.IsLocked + "\nLockCreationDate = " +
\r
508 revObject2.LockCreationDate + "\nLockOwner = " +
\r
509 revObject2.LockOwner + "\nLockComment = " +
\r
510 revObject2.LockComment;
\r
511 wcInfoString3 = "Revision = " + revObject3.Revision +
\r
512 "\nMin Revision = " + revObject3.MinRev +
\r
513 "\nMax Revision = " + revObject3.MaxRev +
\r
514 "\nDate = " + revObject3.Date +
\r
515 "\nURL = " + revObject3.Url + "\nAuthor = " +
\r
516 revObject3.Author + "\nHasMods = " +
\r
517 revObject3.HasModifications + "\nIsSvnItem = " +
\r
518 revObject3.IsSvnItem + "\nNeedsLocking = " +
\r
519 revObject3.NeedsLocking + "\nIsLocked = " +
\r
520 revObject3.IsLocked + "\nLockCreationDate = " +
\r
521 revObject3.LockCreationDate + "\nLockOwner = " +
\r
522 revObject3.LockOwner + "\nLockComment = " +
\r
523 revObject3.LockComment;
\r
524 wcInfoString4 = "Revision = " + revObject4.Revision +
\r
525 "\nMin Revision = " + revObject4.MinRev +
\r
526 "\nMax Revision = " + revObject4.MaxRev +
\r
527 "\nDate = " + revObject4.Date +
\r
528 "\nURL = " + revObject4.Url + "\nAuthor = " +
\r
529 revObject4.Author + "\nHasMods = " +
\r
530 revObject4.HasModifications + "\nIsSvnItem = " +
\r
531 revObject4.IsSvnItem + "\nNeedsLocking = " +
\r
532 revObject4.NeedsLocking + "\nIsLocked = " +
\r
533 revObject4.IsLocked + "\nLockCreationDate = " +
\r
534 revObject4.LockCreationDate + "\nLockOwner = " +
\r
535 revObject4.LockOwner + "\nLockComment = " +
\r
536 revObject4.LockComment;
\r
538 WScript.Echo(wcInfoString1);
\r
539 WScript.Echo(wcInfoString2);
\r
540 WScript.Echo(wcInfoString3);
\r
541 WScript.Echo(wcInfoString4);
\r