-rw-r--r-- | development/cvsbook.html | 15663 | ||||
-rw-r--r-- | development/tmake_ref.html | 478 |
2 files changed, 16141 insertions, 0 deletions
diff --git a/development/cvsbook.html b/development/cvsbook.html new file mode 100644 index 0000000..2c869d1 --- a/dev/null +++ b/development/cvsbook.html | |||
@@ -0,0 +1,15663 @@ | |||
1 | <html lang="en"><head> | ||
2 | <title>Open Source Development With CVS</title> | ||
3 | <meta http-equiv="Content-Type" content="text/html"> | ||
4 | <meta name=description content="Open Source Development With CVS"> | ||
5 | <meta name=generator content="makeinfo 4.0"> | ||
6 | <link href="http://texinfo.org/" rel=generator-home> | ||
7 | </head><body> | ||
8 | |||
9 | <body bgcolor="#FFFFFF" fgcolor="#000000"> | ||
10 | |||
11 | <p>Copyright © 1999, 2000 Karl Fogel <kfogel@red-bean.com> | ||
12 | |||
13 | <p>This document is free software; you can redistribute and/or modify | ||
14 | it under the terms of the GNU General Public License as published by | ||
15 | the Free Software Foundation; either version 2, or (at your option) | ||
16 | any later version. | ||
17 | |||
18 | <p>This document is distributed in the hope that it will be useful, | ||
19 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
20 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
21 | GNU General Public License for more details. | ||
22 | |||
23 | <p>This manual describes how to use and administer CVS (Concurrent Versions | ||
24 | System). It is part of a larger work entitled <cite>Open Source | ||
25 | Development With CVS</cite>; please see the introduction for details. | ||
26 | |||
27 | <p>This is version 1.21 of this manual. | ||
28 | |||
29 | |||
30 | <h1>Table of Contents</h1> | ||
31 | <ul> | ||
32 | <li><a href="#Top"></a> | ||
33 | <li><a href="#Top">Top</a> | ||
34 | <li><a href="#Introduction">Introduction</a> | ||
35 | <li><a href="#An_Overview_of_CVS">An Overview of CVS</a> | ||
36 | <ul> | ||
37 | <li><a href="#Basic_Concepts">Basic Concepts</a> | ||
38 | <li><a href="#A_Day_With_CVS">A Day With CVS</a> | ||
39 | <ul> | ||
40 | <li><a href="#Conventions_Used_In_This_Tour">Conventions Used In This Tour</a> | ||
41 | <li><a href="#Invoking_CVS">Invoking CVS</a> | ||
42 | <li><a href="#Accessing_A_Repository">Accessing A Repository</a> | ||
43 | <li><a href="#Starting_A_New_Project">Starting A New Project</a> | ||
44 | <li><a href="#Checking_Out_A_Working_Copy">Checking Out A Working Copy</a> | ||
45 | <li><a href="#Version_Versus_Revision">Version Versus Revision</a> | ||
46 | <li><a href="#Making_A_Change">Making A Change</a> | ||
47 | <li><a href="#Finding_Out_What_You__And_Others__Did_--_update_And_diff">Finding Out What You (And Others) Did - update And diff</a> | ||
48 | <li><a href="#CVS_And_Implied_Arguments">CVS And Implied Arguments</a> | ||
49 | <li><a href="#Committing">Committing</a> | ||
50 | <li><a href="#Revision_Numbers">Revision Numbers</a> | ||
51 | <li><a href="#Detecting_And_Resolving_Conflicts">Detecting And Resolving Conflicts</a> | ||
52 | <li><a href="#Finding_Out_Who_Did_What__Browsing_Log_Messages_">Finding Out Who Did What (Browsing Log Messages)</a> | ||
53 | <li><a href="#Examining_And_Reverting_Changes">Examining And Reverting Changes</a> | ||
54 | <li><a href="#The_Slow_Method_Of_Reverting">The Slow Method Of Reverting</a> | ||
55 | <li><a href="#The_Fast_Method_Of_Reverting">The Fast Method Of Reverting</a> | ||
56 | </ul> | ||
57 | <li><a href="#Other_Useful_CVS_Commands">Other Useful CVS Commands</a> | ||
58 | <ul> | ||
59 | <li><a href="#Adding_Files">Adding Files</a> | ||
60 | <li><a href="#Adding_Directories">Adding Directories</a> | ||
61 | <li><a href="#CVS_And_Binary_Files">CVS And Binary Files</a> | ||
62 | <li><a href="#Removing_Files">Removing Files</a> | ||
63 | <li><a href="#Removing_Directories">Removing Directories</a> | ||
64 | <li><a href="#Renaming_Files_And_Directories">Renaming Files And Directories</a> | ||
65 | <li><a href="#Avoiding_Option_Fatigue">Avoiding Option Fatigue</a> | ||
66 | <li><a href="#Getting_Snapshots__Dates_And_Tagging_">Getting Snapshots (Dates And Tagging)</a> | ||
67 | <li><a href="#Acceptable_Date_Formats">Acceptable Date Formats</a> | ||
68 | <li><a href="#Marking_A_Moment_In_Time__Tags_">Marking A Moment In Time (Tags)</a> | ||
69 | </ul> | ||
70 | <li><a href="#Branches">Branches</a> | ||
71 | <ul> | ||
72 | <li><a href="#Branching_Basics">Branching Basics</a> | ||
73 | <li><a href="#Merging_Changes_From_Branch_To_Trunk">Merging Changes From Branch To Trunk</a> | ||
74 | <li><a href="#Multiple_Merges">Multiple Merges</a> | ||
75 | <li><a href="#Creating_A_Tag_Or_Branch_Without_A_Working_Copy">Creating A Tag Or Branch Without A Working Copy</a> | ||
76 | </ul> | ||
77 | </ul> | ||
78 | <li><a href="#Repository_Administration">Repository Administration</a> | ||
79 | <ul> | ||
80 | <li><a href="#Getting_And_Installing_CVS">Getting And Installing CVS</a> | ||
81 | <ul> | ||
82 | <li><a href="#Getting_And_Building_CVS_Under_Unix">Getting And Building CVS Under Unix</a> | ||
83 | <li><a href="#Getting_And_Installing_CVS_Under_Windows">Getting And Installing CVS Under Windows</a> | ||
84 | <li><a href="#Getting_And_Installing_CVS_On_A_Macintosh">Getting And Installing CVS On A Macintosh</a> | ||
85 | <li><a href="#Limitations_Of_The_Windows_And_Macintosh_Versions">Limitations Of The Windows And Macintosh Versions</a> | ||
86 | </ul> | ||
87 | <li><a href="#Anatomy_Of_A_CVS_Distribution">Anatomy Of A CVS Distribution</a> | ||
88 | <ul> | ||
89 | <li><a href="#Informational_Files">Informational Files</a> | ||
90 | <li><a href="#Subdirectories">Subdirectories</a> | ||
91 | <li><a href="#The_Cederqvist_Manual">The Cederqvist Manual</a> | ||
92 | <li><a href="#Other_Sources_Of_Information">Other Sources Of Information</a> | ||
93 | </ul> | ||
94 | <li><a href="#Starting_A_Repository">Starting A Repository</a> | ||
95 | <li><a href="#The_Password-Authenticating_Server">The Password-Authenticating Server</a> | ||
96 | <li><a href="#Anonymous_Access">Anonymous Access</a> | ||
97 | <li><a href="#Repository_Structure">Repository Structure</a> | ||
98 | <li><a href="#RCS_Format">RCS Format</a> | ||
99 | <li><a href="#What_Happens_When_You_Remove_A_File">What Happens When You Remove A File</a> | ||
100 | <li><a href="#The_CVSROOT__Administrative_Directory">The CVSROOT/ Administrative Directory</a> | ||
101 | <ul> | ||
102 | <li><a href="#The_config_File">The config File</a> | ||
103 | <li><a href="#The_modules_File">The modules File</a> | ||
104 | <li><a href="#The_commitinfo_And_loginfo_And_rcsinfo_Files">The commitinfo And loginfo And rcsinfo Files</a> | ||
105 | <li><a href="#The_verifymsg_And_rcsinfo_Files">The verifymsg And rcsinfo Files</a> | ||
106 | <li><a href="#The_taginfo_File">The taginfo File</a> | ||
107 | <li><a href="#The_cvswrappers_File">The cvswrappers File</a> | ||
108 | <li><a href="#The_editinfo_File">The editinfo File</a> | ||
109 | <li><a href="#The_notify_File">The notify File</a> | ||
110 | <li><a href="#The_checkoutlist_File">The checkoutlist File</a> | ||
111 | </ul> | ||
112 | <li><a href="#Commit_Emails">Commit Emails</a> | ||
113 | <li><a href="#Finding_Out_More">Finding Out More</a> | ||
114 | </ul> | ||
115 | <li><a href="#Advanced_CVS">Advanced CVS</a> | ||
116 | <ul> | ||
117 | <li><a href="#Watches__CVS_As_Telephone_">Watches (CVS As Telephone)</a> | ||
118 | <ul> | ||
119 | <li><a href="#How_Watches_Work">How Watches Work</a> | ||
120 | <li><a href="#Enabling_Watches_In_The_Repository">Enabling Watches In The Repository</a> | ||
121 | <li><a href="#Using_Watches_In_Development">Using Watches In Development</a> | ||
122 | <li><a href="#Ending_An_Editing_Session">Ending An Editing Session</a> | ||
123 | <li><a href="#Controlling_What_Actions_Are_Watched">Controlling What Actions Are Watched</a> | ||
124 | <li><a href="#Finding_Out_Who_Is_Watching_What">Finding Out Who Is Watching What</a> | ||
125 | <li><a href="#Reminding_People_To_Use_Watches">Reminding People To Use Watches</a> | ||
126 | <li><a href="#What_Watches_Look_Like_In_The_Repository">What Watches Look Like In The Repository</a> | ||
127 | </ul> | ||
128 | <li><a href="#Log_Messages_And_Commit_Emails">Log Messages And Commit Emails</a> | ||
129 | <li><a href="#Changing_A_Log_Message_After_Commit">Changing A Log Message After Commit</a> | ||
130 | <li><a href="#Getting_Rid_Of_A_Working_Copy">Getting Rid Of A Working Copy</a> | ||
131 | <li><a href="#History_--_A_Summary_Of_Repository_Activity">History - A Summary Of Repository Activity</a> | ||
132 | <li><a href="#Annotations_--_A_Detailed_View_Of_Project_Activity">Annotations - A Detailed View Of Project Activity</a> | ||
133 | <li><a href="#Annotations_And_Branches">Annotations And Branches</a> | ||
134 | <li><a href="#Using_Keyword_Expansion">Using Keyword Expansion</a> | ||
135 | <li><a href="#Going_Out_On_A_Limb__How_To_Work_With_Branches_And_Survive_">Going Out On A Limb (How To Work With Branches And Survive)</a> | ||
136 | <ul> | ||
137 | <li><a href="#Some_Principles_For_Working_With_Branches">Some Principles For Working With Branches</a> | ||
138 | <li><a href="#Merging_Repeatedly_Into_The_Trunk">Merging Repeatedly Into The Trunk</a> | ||
139 | <li><a href="#The_Dovetail_Approach_--_Merging_In_And_Out_Of_The_Trunk">The Dovetail Approach - Merging In And Out Of The Trunk</a> | ||
140 | <li><a href="#The_Flying_Fish_Approach_--_A_Simpler_Way_To_Do_It">The Flying Fish Approach - A Simpler Way To Do It</a> | ||
141 | <li><a href="#Branches_And_Keyword_Expansion_--_Natural_Enemies">Branches And Keyword Expansion - Natural Enemies</a> | ||
142 | </ul> | ||
143 | <li><a href="#Tracking_Third-Party_Sources__Vendor_Branches_">Tracking Third-Party Sources (Vendor Branches)</a> | ||
144 | <li><a href="#Exporting_For_Public_Distribution">Exporting For Public Distribution</a> | ||
145 | <li><a href="#The_Humble_Guru">The Humble Guru</a> | ||
146 | </ul> | ||
147 | <li><a href="#Tips_And_Troubleshooting">Tips And Troubleshooting</a> | ||
148 | <ul> | ||
149 | <li><a href="#The_Usual_Suspects">The Usual Suspects</a> | ||
150 | <ul> | ||
151 | <li><a href="#The_Working_Copy_Administrative_Area">The Working Copy Administrative Area</a> | ||
152 | <li><a href="#Repository_Permissions">Repository Permissions</a> | ||
153 | </ul> | ||
154 | <li><a href="#General_Troubleshooting_Tips">General Troubleshooting Tips</a> | ||
155 | <li><a href="#Some_Real_Life_Problems__With_Solutions_">Some Real Life Problems (With Solutions)</a> | ||
156 | <ul> | ||
157 | <li><a href="#CVS_says_it_is_waiting_for_a_lock__what_does_that_mean_">CVS says it is waiting for a lock; what does that mean?</a> | ||
158 | <li><a href="#CVS_claims_a_file_is_failing_Up-To-Date_check__what_do_I_do_">CVS claims a file is failing Up-To-Date check; what do I do?</a> | ||
159 | <li><a href="#The_pserver_access_method_is_not_working">The pserver access method is not working</a> | ||
160 | <li><a href="#The_pserver_access_method_is_STILL_not_working">The pserver access method is STILL not working</a> | ||
161 | <li><a href="#My_commits_seem_to_happen_in_pieces_instead_of_atomically">My commits seem to happen in pieces instead of atomically</a> | ||
162 | <li><a href="#CVS_keeps_changing_file_permissions__why_does_it_do_that_">CVS keeps changing file permissions; why does it do that?</a> | ||
163 | <li><a href="#CVS_on_Windows_complains_it_cannot_find_my_.cvspass_file__why_">CVS on Windows complains it cannot find my .cvspass file; why?</a> | ||
164 | <li><a href="#My_working_copy_is_on_several_different_branches__help_">My working copy is on several different branches; help?</a> | ||
165 | <li><a href="#When_I_do_export_-d_I_sometimes_miss_recent_commits">When I do export -d I sometimes miss recent commits</a> | ||
166 | <li><a href="#I_get_an_error_about_val-tags__what_should_I_do_">I get an error about val-tags; what should I do?</a> | ||
167 | <li><a href="#I_am_having_problems_with_sticky_tags__how_do_I_get_rid_of_them_">I am having problems with sticky tags; how do I get rid of them?</a> | ||
168 | <li><a href="#Checkouts_updates_exit_with_error_saying_cannot_expand_modules">Checkouts/updates exit with error saying cannot expand modules</a> | ||
169 | <li><a href="#I_cannot_seem_to_turn_off_watches">I cannot seem to turn off watches</a> | ||
170 | <li><a href="#My_binary_files_are_messed_up">My binary files are messed up</a> | ||
171 | <li><a href="#CVS_is_not_doing_line-end_conversion_correctly">CVS is not doing line-end conversion correctly</a> | ||
172 | <li><a href="#I_need_to_remove_a_subdirectory_in_my_project__how_do_I_do_it_">I need to remove a subdirectory in my project; how do I do it?</a> | ||
173 | <li><a href="#Can_I_copy_.cvspass_files_or_portions_of_them_">Can I copy .cvspass files or portions of them?</a> | ||
174 | <li><a href="#I_just_committed_some_files_with_the_wrong_log_message">I just committed some files with the wrong log message</a> | ||
175 | <li><a href="#I_need_to_move_files_around_without_losing_revision_history">I need to move files around without losing revision history</a> | ||
176 | <li><a href="#How_can_I_get_a_list_of_all_tags_in_a_project_">How can I get a list of all tags in a project?</a> | ||
177 | <li><a href="#How_can_I_get_a_list_of_all_projects_in_a_repository_">How can I get a list of all projects in a repository?</a> | ||
178 | <li><a href="#Some_commands_fail_remotely_but_not_locally__how_should_I_debug_">Some commands fail remotely but not locally; how should I debug?</a> | ||
179 | <li><a href="#I_do_not_see_my_problem_covered_in_this_chapter">I do not see my problem covered in this chapter</a> | ||
180 | <li><a href="#I_think_I_have_discovered_a_bug_in_CVS__what_do_I_do_">I think I have discovered a bug in CVS; what do I do?</a> | ||
181 | <li><a href="#I_have_implemented_a_new_feature_for_CVS__to_whom_do_I_send_it_">I have implemented a new feature for CVS; to whom do I send it?</a> | ||
182 | <li><a href="#How_can_I_keep_up_with_changes_to_CVS_">How can I keep up with changes to CVS?</a> | ||
183 | </ul> | ||
184 | </ul> | ||
185 | <li><a href="#CVS_Reference">CVS Reference</a> | ||
186 | <ul> | ||
187 | <li><a href="#Commands_And_Options">Commands And Options</a> | ||
188 | <ul> | ||
189 | <li><a href="#Organization_And_Conventions">Organization And Conventions</a> | ||
190 | <li><a href="#General_Patterns_In_CVS_Commands">General Patterns In CVS Commands</a> | ||
191 | <li><a href="#Date_Formats">Date Formats</a> | ||
192 | <li><a href="#Global_Options">Global Options</a> | ||
193 | <li><a href="#add">add</a> | ||
194 | <li><a href="#admin">admin</a> | ||
195 | <li><a href="#annotate">annotate</a> | ||
196 | <li><a href="#checkout">checkout</a> | ||
197 | <li><a href="#commit">commit</a> | ||
198 | <li><a href="#diff">diff</a> | ||
199 | <li><a href="#edit">edit</a> | ||
200 | <li><a href="#editors">editors</a> | ||
201 | <li><a href="#export">export</a> | ||
202 | <li><a href="#gserver">gserver</a> | ||
203 | <li><a href="#history">history</a> | ||
204 | <li><a href="#import">import</a> | ||
205 | <li><a href="#init">init</a> | ||
206 | <li><a href="#kserver">kserver</a> | ||
207 | <li><a href="#log">log</a> | ||
208 | <li><a href="#login">login</a> | ||
209 | <li><a href="#logout">logout</a> | ||
210 | <li><a href="#pserver">pserver</a> | ||
211 | <li><a href="#rdiff">rdiff</a> | ||
212 | <li><a href="#release">release</a> | ||
213 | <li><a href="#remove">remove</a> | ||
214 | <li><a href="#rtag">rtag</a> | ||
215 | <li><a href="#server">server</a> | ||
216 | <li><a href="#status">status</a> | ||
217 | <li><a href="#tag">tag</a> | ||
218 | <li><a href="#unedit">unedit</a> | ||
219 | <li><a href="#update">update</a> | ||
220 | <li><a href="#watch">watch</a> | ||
221 | <li><a href="#watchers">watchers</a> | ||
222 | </ul> | ||
223 | <li><a href="#Keyword_Substitution__RCS_Keywords_">Keyword Substitution (RCS Keywords)</a> | ||
224 | <ul> | ||
225 | <li><a href="#Controlling_Keyword_Expansion">Controlling Keyword Expansion</a> | ||
226 | <li><a href="#List_Of_Keywords">List Of Keywords</a> | ||
227 | </ul> | ||
228 | <li><a href="#Repository_Administrative_Files">Repository Administrative Files</a> | ||
229 | <ul> | ||
230 | <li><a href="#Storage_And_Editing">Storage And Editing</a> | ||
231 | <li><a href="#Shared_Syntax">Shared Syntax</a> | ||
232 | <li><a href="#Shared_Variables">Shared Variables</a> | ||
233 | <li><a href="#User_Variables">User Variables</a> | ||
234 | <li><a href="#checkoutlist">checkoutlist</a> | ||
235 | <li><a href="#commitinfo">commitinfo</a> | ||
236 | <li><a href="#config">config</a> | ||
237 | <li><a href="#cvsignore">cvsignore</a> | ||
238 | <li><a href="#cvswrappers">cvswrappers</a> | ||
239 | <li><a href="#editinfo">editinfo</a> | ||
240 | <li><a href="#history_file">history file</a> | ||
241 | <li><a href="#loginfo">loginfo</a> | ||
242 | <li><a href="#modules">modules</a> | ||
243 | <li><a href="#notify">notify</a> | ||
244 | <li><a href="#passwd">passwd</a> | ||
245 | <li><a href="#rcsinfo">rcsinfo</a> | ||
246 | <li><a href="#taginfo">taginfo</a> | ||
247 | <li><a href="#users">users</a> | ||
248 | <li><a href="#val-tags">val-tags</a> | ||
249 | <li><a href="#verifymsg">verifymsg</a> | ||
250 | </ul> | ||
251 | <li><a href="#Run_Control_Files">Run Control Files</a> | ||
252 | <ul> | ||
253 | <li><a href="#Run_Control_Files"><code>.cvsrc</code></a> | ||
254 | <li><a href="#Run_Control_Files"><code>.cvsignore</code></a> | ||
255 | <li><a href="#Run_Control_Files"><code>.cvspass</code></a> | ||
256 | <li><a href="#Run_Control_Files"><code>.cvswrappers</code></a> | ||
257 | </ul> | ||
258 | <li><a href="#Working_Copy_Files">Working Copy Files</a> | ||
259 | <ul> | ||
260 | <li><a href="#Working_Copy_Files"><code>CVS/Base/</code> (directory)</a> | ||
261 | <li><a href="#Working_Copy_Files"><code>CVS/Baserev</code></a> | ||
262 | <li><a href="#Working_Copy_Files"><code>CVS/Baserev.tmp</code></a> | ||
263 | <li><a href="#Working_Copy_Files"><code>CVS/Checkin.prog</code></a> | ||
264 | <li><a href="#Working_Copy_Files"><code>CVS/Entries</code></a> | ||
265 | <li><a href="#Working_Copy_Files"><code>CVS/Entries.Backup</code></a> | ||
266 | <li><a href="#Working_Copy_Files"><code>CVS/Entries.Log</code></a> | ||
267 | <li><a href="#Working_Copy_Files"><code>CVS/Entries.Static</code></a> | ||
268 | <li><a href="#Working_Copy_Files"><code>CVS/Notify</code></a> | ||
269 | <li><a href="#Working_Copy_Files"><code>CVS/Notify.tmp</code></a> | ||
270 | <li><a href="#Working_Copy_Files"><code>CVS/Repository</code></a> | ||
271 | <li><a href="#Working_Copy_Files"><code>CVS/Root</code></a> | ||
272 | <li><a href="#Working_Copy_Files"><code>CVS/Tag</code></a> | ||
273 | <li><a href="#Working_Copy_Files"><code>CVS/Template</code></a> | ||
274 | <li><a href="#Working_Copy_Files"><code>CVS/Update.prog</code></a> | ||
275 | </ul> | ||
276 | <li><a href="#Environment_Variables">Environment Variables</a> | ||
277 | <ul> | ||
278 | <li><a href="#_COMSPEC">$COMSPEC</a> | ||
279 | <li><a href="#_CVS_CLIENT_LOG">$CVS_CLIENT_LOG</a> | ||
280 | <li><a href="#_CVS_CLIENT_PORT">$CVS_CLIENT_PORT</a> | ||
281 | <li><a href="#_CVSEDITOR">$CVSEDITOR</a> | ||
282 | <li><a href="#_CVSIGNORE">$CVSIGNORE</a> | ||
283 | <li><a href="#_CVS_IGNORE_REMOTE_ROOT">$CVS_IGNORE_REMOTE_ROOT</a> | ||
284 | <li><a href="#_CVS_PASSFILE">$CVS_PASSFILE</a> | ||
285 | <li><a href="#_CVS_RCMD_PORT">$CVS_RCMD_PORT</a> | ||
286 | <li><a href="#_CVSREAD">$CVSREAD</a> | ||
287 | <li><a href="#_CVSROOT">$CVSROOT</a> | ||
288 | <li><a href="#_CVS_RSH">$CVS_RSH</a> | ||
289 | <li><a href="#_CVS_SERVER">$CVS_SERVER</a> | ||
290 | <li><a href="#_CVS_SERVER_SLEEP">$CVS_SERVER_SLEEP</a> | ||
291 | <li><a href="#_CVSUMASK">$CVSUMASK</a> | ||
292 | <li><a href="#_CVSWRAPPERS">$CVSWRAPPERS</a> | ||
293 | <li><a href="#_EDITOR">$EDITOR</a> | ||
294 | <li><a href="#_HOME__HOMEDRIVE___HOMEPATH_">$HOME %HOMEDRIVE% %HOMEPATH%</a> | ||
295 | <li><a href="#_PATH">$PATH</a> | ||
296 | <li><a href="#_TEMP__TMP__TMPDIR">$TEMP $TMP $TMPDIR</a> | ||
297 | <li><a href="#_VISUAL">$VISUAL</a> | ||
298 | </ul> | ||
299 | </ul> | ||
300 | <li><a href="#Third-Party_Tools">Third-Party Tools</a> | ||
301 | <ul> | ||
302 | <li><a href="#pcl-cvs_--_An_Emacs_Interface_To_CVS">pcl-cvs - An Emacs Interface To CVS</a> | ||
303 | <ul> | ||
304 | <li><a href="#Installing_pcl-cvs">Installing pcl-cvs</a> | ||
305 | <li><a href="#Using_pcl-cvs">Using pcl-cvs</a> | ||
306 | <li><a href="#Error_Handling_In_pcl-cvs">Error Handling In pcl-cvs</a> | ||
307 | <li><a href="#The_Future_Of_pcl-cvs">The Future Of pcl-cvs</a> | ||
308 | </ul> | ||
309 | <li><a href="#cvsutils_--_General_Utilities_For_Use_With_CVS">cvsutils - General Utilities For Use With CVS</a> | ||
310 | <ul> | ||
311 | <li><a href="#cvsu">cvsu</a> | ||
312 | <li><a href="#cvsdo">cvsdo</a> | ||
313 | <li><a href="#cvschroot">cvschroot</a> | ||
314 | <li><a href="#cvsrmadm">cvsrmadm</a> | ||
315 | <li><a href="#cvspurge">cvspurge</a> | ||
316 | <li><a href="#cvsdiscard">cvsdiscard</a> | ||
317 | <li><a href="#cvsco">cvsco</a> | ||
318 | <li><a href="#cvsdate">cvsdate</a> | ||
319 | </ul> | ||
320 | <li><a href="#cvs2cl_--_Generate_GNU-Style_ChangeLogs">cvs2cl - Generate GNU-Style ChangeLogs</a> | ||
321 | <li><a href="#cvsq_--_Queue_CVS_Commands_For_Later_Connection">cvsq - Queue CVS Commands For Later Connection</a> | ||
322 | <li><a href="#cvslock_--_Lock_Repositories_For_Atomicity">cvslock - Lock Repositories For Atomicity</a> | ||
323 | <li><a href="#Other_Packages">Other Packages</a> | ||
324 | <li><a href="#Writing_Your_Own_Tools">Writing Your Own Tools</a> | ||
325 | </ul> | ||
326 | <li><a href="#Index">Index</a> | ||
327 | <li><a href="#GNU_General_Public_License">GNU General Public License</a> | ||
328 | <li><a href="#GNU_Free_Documentation_License">GNU Free Documentation License</a> | ||
329 | </ul> | ||
330 | |||
331 | <p><hr> | ||
332 | Node:<a name="Top">Top</a>, | ||
333 | Next:<a rel=next href="#Introduction">Introduction</a>, | ||
334 | Up:<a rel=up href="#_top">(dir)</a> | ||
335 | <br> | ||
336 | |||
337 | <h1></h1> | ||
338 | |||
339 | <h1>Top</h1> | ||
340 | |||
341 | <ul> | ||
342 | <li><a href="#Introduction">Introduction</a>: What is this book? | ||
343 | <li><a href="#An_Overview_of_CVS">An Overview of CVS</a>: Basic CVS usage -- a tutorial. | ||
344 | <li><a href="#Repository_Administration">Repository Administration</a>: How to run a CVS repository. | ||
345 | <li><a href="#Advanced_CVS">Advanced CVS</a>: What the gurus know. | ||
346 | <li><a href="#Tips_And_Troubleshooting">Tips And Troubleshooting</a>: FAQs and real-life experiences. | ||
347 | <li><a href="#CVS_Reference">CVS Reference</a>: A reference to CVS commands, variables, etc. | ||
348 | <li><a href="#Third-Party_Tools">Third-Party Tools</a>: Other tools that work with CVS. | ||
349 | <li><a href="#Index">Index</a>: | ||
350 | <li><a href="#GNU_General_Public_License">GNU General Public License</a>: | ||
351 | <li><a href="#GNU_Free_Documentation_License">GNU Free Documentation License</a>: | ||
352 | </ul> | ||
353 | |||
354 | <p><hr> | ||
355 | Node:<a name="Introduction">Introduction</a>, | ||
356 | Next:<a rel=next href="#An_Overview_of_CVS">An Overview of CVS</a>, | ||
357 | Previous:<a rel=previous href="#Top">Top</a>, | ||
358 | Up:<a rel=up href="#Top">Top</a> | ||
359 | <br> | ||
360 | |||
361 | <h1>Introduction</h1> | ||
362 | |||
363 | <p>This is a set of free, online chapters about using CVS (Concurrent | ||
364 | Versions System) for collaboration and version control. It covers | ||
365 | everything from CVS installation and basic concepts all the way to | ||
366 | advanced usage and administration. It is intended for anyone who uses | ||
367 | or plans to use CVS. | ||
368 | |||
369 | <p>These chapters are excerpted from a larger work called <cite>Open Source | ||
370 | Development With CVS</cite> (published by <a href="http://www.coriolis.com/">The Coriolis Group</a>, ISBN 1-57610-490-7). The remainder of that book - | ||
371 | chapters 1, 3, 5, and 7 - deals with the challenges and philosophical | ||
372 | issues of running an Open Source project using CVS. | ||
373 | |||
374 | <p>While the free chapters here constitute a complete CVS book by | ||
375 | themselves, we certainly hope you'll like them enough to purchase a | ||
376 | treeware copy of the entire book! You can order it directly from the | ||
377 | publisher, at | ||
378 | <a href="http://www.coriolis.com/bookstore/bookdetail.cfm?id=1576104907">http://www.coriolis.com/bookstore/bookdetail.cfm?id=1576104907</a>. | ||
379 | |||
380 | <p>These chapters are released under the | ||
381 | <a href="http://www.gnu.org/copyleft/gpl.html">GNU General Public License</a>. | ||
382 | For more information about free software in general, visit | ||
383 | <a href="http://www.gnu.org/">http://www.gnu.org/</a>, and particularly | ||
384 | <a href="http://www.gnu.org/philosophy/free-sw.html">http://www.gnu.org/philosophy/free-sw.html</a>. | ||
385 | |||
386 | <p>To submit comments or errata regarding any of this material, please send | ||
387 | email to <a href="mailto:bug-cvsbook@red-bean.com">bug-cvsbook@red-bean.com</a>. For news and updates, visit | ||
388 | <a href="http://cvsbook.red-bean.com/">http://cvsbook.red-bean.com/</a>. | ||
389 | |||
390 | <p><hr> | ||
391 | Node:<a name="An_Overview_of_CVS">An Overview of CVS</a>, | ||
392 | Next:<a rel=next href="#Repository_Administration">Repository Administration</a>, | ||
393 | Previous:<a rel=previous href="#Introduction">Introduction</a>, | ||
394 | Up:<a rel=up href="#Top">Top</a> | ||
395 | <br> | ||
396 | |||
397 | <h1>An Overview of CVS</h1> | ||
398 | |||
399 | <blockquote> | ||
400 | <em>I can't imagine programming without it... that would be like | ||
401 | parachuting without a parachute!</em> | ||
402 | |||
403 | <p align="center"><em>-Brian Fitzpatrick on CVS</em></p> | ||
404 | |||
405 | </blockquote> | ||
406 | |||
407 | <p>This chapter introduces the fundamentals of CVS, and then provides an | ||
408 | in-depth guided tour of everyday CVS usage. Concepts are presented | ||
409 | sequentially, so if you're new to CVS, the best way to read this is to | ||
410 | start at the beginning and go straight through, without skipping | ||
411 | anything. | ||
412 | |||
413 | <ul> | ||
414 | <li><a href="#Basic_Concepts">Basic Concepts</a>: How to think like CVS. | ||
415 | <li><a href="#A_Day_With_CVS">A Day With CVS</a>: Guided tour through a sample CVS session. | ||
416 | <li><a href="#Other_Useful_CVS_Commands">Other Useful CVS Commands</a>: Random useful things. | ||
417 | <li><a href="#Branches">Branches</a>: Splitting development into parallel streams. | ||
418 | </ul> | ||
419 | |||
420 | <p><hr> | ||
421 | Node:<a name="Basic_Concepts">Basic Concepts</a>, | ||
422 | Next:<a rel=next href="#A_Day_With_CVS">A Day With CVS</a>, | ||
423 | Up:<a rel=up href="#An_Overview_of_CVS">An Overview of CVS</a> | ||
424 | <br> | ||
425 | |||
426 | <h2>Basic Concepts</h2> | ||
427 | |||
428 | <p>If you've never used CVS (or any version control system) before, it's | ||
429 | easy to get tripped up by some of its underlying assumptions. What | ||
430 | seems to cause the most initial confusion about CVS is that it is used | ||
431 | for two apparently unrelated purposes: record keeping and collaboration. | ||
432 | It turns out, however, that these two functions are closely connected. | ||
433 | |||
434 | <p>Record keeping became necessary because people wanted to compare a | ||
435 | program's current state with how it was at some point in the past. For | ||
436 | example, in the normal course of implementing a new feature, a developer | ||
437 | may bring the program into a thoroughly broken state, where it will | ||
438 | probably remain until the feature is mostly finished. Unfortunately, | ||
439 | this is just the time when someone usually calls to report a bug in the | ||
440 | last publicly released version. To debug the problem (which may also | ||
441 | exist in the current version of the sources), the program has to be | ||
442 | brought back to a useable state. | ||
443 | |||
444 | <p>Restoring the state poses no difficulty if the source code history is | ||
445 | kept under CVS. The developer can simply say, in effect, "Give me the | ||
446 | program as it was three weeks ago", or perhaps "Give me the program as | ||
447 | it was at the time of our last public release". If you've never had | ||
448 | this kind of convenient access to historical snapshots before, you may | ||
449 | be surprised at how quickly you come to depend on it. Personally, I | ||
450 | always use revision control on my coding projects now - it's saved me | ||
451 | many times. | ||
452 | |||
453 | <p>To understand what this has to do with facilitating collaboration, we'll | ||
454 | need to take a closer look at the mechanism that CVS provides to help | ||
455 | numerous people work on the same project. But before we do that, let's | ||
456 | take a look at a mechanism that CVS doesn't provide (or at least, | ||
457 | doesn't encourage): file locking. If you've used other version control | ||
458 | systems, you may be familiar with the lock-modify-unlock development | ||
459 | model, wherein a developer first obtains exclusive write access (a lock) | ||
460 | to the file to be edited, makes the changes, and then releases the lock | ||
461 | to allow other developers access to the file. If someone else already | ||
462 | has a lock on the file, they have to "release" it before you can lock it | ||
463 | and start making changes (or, in some implementations, you may "steal" | ||
464 | their lock, but that is often an unpleasant surprise for them and not | ||
465 | good practice!). | ||
466 | |||
467 | <p>This system is workable if the developers know each other, know who's | ||
468 | planning to do what at any given time, and can communicate with each | ||
469 | other quickly if someone cannot work because of access contention. | ||
470 | However, if the developer group becomes too large or too spread out, | ||
471 | dealing with all the locking issues begins to chip away at coding time; | ||
472 | it becomes a constant hassle that can discourage people from getting | ||
473 | real work done. | ||
474 | |||
475 | <p>CVS takes a more mellow approach. Rather than requiring that developers | ||
476 | coordinate with each other to avoid conflicts, CVS enables developers to | ||
477 | edit simultaneously, assumes the burden of integrating all the changes, | ||
478 | and keeps track of any conflicts. This process uses the | ||
479 | copy-modify-merge model, which works as follows: | ||
480 | |||
481 | <ol type=1 start=1> | ||
482 | |||
483 | </p><li>Developer A requests a working copy (a directory tree containing the | ||
484 | files that make up the project) from CVS. This is also known as | ||
485 | "checking out" a working copy, like checking a book out of the library. | ||
486 | |||
487 | <li>Developer A edits freely in her working copy. At the same time, other | ||
488 | developers may be busy in their own working copies. Because these are | ||
489 | all separate copies, there is no interference - it is as though all of | ||
490 | the developers have their own copy of the same library book, and they're | ||
491 | all at work scribbling comments in the margins or rewriting certain | ||
492 | pages independently. | ||
493 | |||
494 | <li>Developer A finishes her changes and commits them into CVS along with a | ||
495 | "log message", which is a comment explaining the nature and purpose of | ||
496 | the changes. This is like informing the library of what changes she | ||
497 | made to the book and why. The library then incorporates these changes | ||
498 | into a "master" copy, where they are recorded for all time. | ||
499 | |||
500 | <li>Meanwhile, other developers can have CVS query the library to see if the | ||
501 | master copy has changed recently. If it has, CVS automatically updates | ||
502 | their working copies. (This part is magical and wonderful, and I hope | ||
503 | you appreciate it. Imagine how different the world would be if real | ||
504 | books worked this way!) | ||
505 | |||
506 | </ol> | ||
507 | |||
508 | <p>As far as CVS is concerned, all developers on a project are equal. | ||
509 | Deciding when to update or when to commit is largely a matter of | ||
510 | personal preference or project policy. One common strategy for coding | ||
511 | projects is to always update before commencing work on a major change | ||
512 | and to commit only when the changes are complete and tested so that the | ||
513 | master copy is always in a "runnable" state. | ||
514 | |||
515 | <p>Perhaps you're wondering what happens when developers A and B, each in | ||
516 | their own working copy, make different changes to the same area of text | ||
517 | and then both commit their changes? This is called a <dfn>conflict</dfn>, and | ||
518 | CVS notices it as soon as developer B tries to commit changes. Instead | ||
519 | of allowing developer B to proceed, CVS announces that it has discovered | ||
520 | a conflict and places conflict markers (easily recognizable textual | ||
521 | flags) at the conflicting location in his copy. That location also | ||
522 | shows both sets of changes, arranged for easy comparison. Developer B | ||
523 | must sort it all out and commit a new revision with the conflict | ||
524 | resolved. Perhaps the two developers will need to talk to each other to | ||
525 | settle the issue. CVS only alerts the developers that there is a | ||
526 | conflict; it's up to human beings to actually resolve it. | ||
527 | |||
528 | <p>What about the master copy? In official CVS terminology, it is called | ||
529 | the project's repository. The repository is simply a file tree kept on | ||
530 | a central server. Without going into too much detail about its | ||
531 | structure (but see <a href="#Repository_Administration">Repository Administration</a>), let's look at what | ||
532 | the repository must do to meet the requirements of the | ||
533 | checkout-commit-update cycle. Consider the following scenario: | ||
534 | |||
535 | <ol type=1 start=1> | ||
536 | |||
537 | </p><li>Two developers, A and B, check out working copies of a project at the | ||
538 | same time. The project is at its starting point - no changes have been | ||
539 | committed by anyone yet, so all the files are in their original, | ||
540 | pristine state. | ||
541 | |||
542 | <li>Developer A gets right to work and soon commits her first batch of | ||
543 | changes. | ||
544 | |||
545 | <li>Meanwhile, developer B watches television. | ||
546 | |||
547 | <li>Developer A, hacking away like there's no tomorrow, commits her second | ||
548 | batch of changes. Now, the repository's history contains the original | ||
549 | files, followed by A's first batch of changes, followed by this set of | ||
550 | changes. | ||
551 | |||
552 | <li>Meanwhile, developer B plays video games. | ||
553 | |||
554 | <li>Suddenly, developer C joins the project and checks out a working copy | ||
555 | from the repository. Developer C's copy reflects A's first two sets of | ||
556 | changes, because they were already in the repository when C checked out | ||
557 | her copy. | ||
558 | |||
559 | <li>Developer A, continuing to code as one possessed by spirits, completes | ||
560 | and commits her third batch of changes. | ||
561 | |||
562 | <li>Finally, blissfully unaware of the recent frenzy of activity, developer | ||
563 | B decides it's time to start work. He doesn't bother to update his | ||
564 | copy; he just commences editing files, some of which may be files that A | ||
565 | has worked in. Shortly thereafter, developer B commits his first | ||
566 | changes. | ||
567 | |||
568 | </ol> | ||
569 | |||
570 | <p>At this point, one of two things can happen. If none of the files | ||
571 | edited by developer B have been edited by A, the commit succeeds. | ||
572 | However, if CVS realizes that some of B's files are out of date with | ||
573 | respect to the repository's latest copies, and those files have also | ||
574 | been changed by B in his working copy, CVS informs B that he must do an | ||
575 | update before committing those files. | ||
576 | |||
577 | <p>When developer B runs the update, CVS merges all of A's changes into B's | ||
578 | local copies of the files. Some of A's work may conflict with B's | ||
579 | uncommitted changes, and some may not. Those parts that don't are | ||
580 | simply applied to B's copies without further complication, but the | ||
581 | conflicting changes must be resolved by B before being committed. | ||
582 | |||
583 | <p>If developer C does an update now, she'll receive various new changes | ||
584 | from the repository: those from A's third commit, and those from B's | ||
585 | first <em>successful</em> commit (which might really come from B's second | ||
586 | attempt to commit, assuming B's first attempt resulted in B being forced | ||
587 | to resolve conflicts). | ||
588 | |||
589 | <p>In order for CVS to serve up changes, in the correct sequence, to | ||
590 | developers whose working copies may be out of sync by varying degrees, | ||
591 | the repository needs to store all commits since the project's beginning. | ||
592 | In practice, the CVS repository stores them all as successive diffs. | ||
593 | Thus, even for a very old working copy, CVS is able to calculate the | ||
594 | difference between the working copy's files and the current state of the | ||
595 | repository, and is thereby able to bring the working copy up to date | ||
596 | efficiently. This makes it easy for developers to view the project's | ||
597 | history at any point and to revive even very old working copies. | ||
598 | |||
599 | <p>Although, strictly speaking, the repository could achieve the same | ||
600 | results by other means, in practice, storing diffs is a simple, | ||
601 | intuitive means of implementing the necessary functionality. The | ||
602 | process has the added benefit that, by using patch appropriately, CVS | ||
603 | can reconstruct any previous state of the file tree and thus bring any | ||
604 | working copy from one state to another. It can allow someone to check | ||
605 | out the project as it looked at any particular time. It can also show | ||
606 | the differences, in diff format, between two states of the tree without | ||
607 | affecting someone's working copy. | ||
608 | |||
609 | <p>Thus, the very features necessary to give convenient access to a | ||
610 | project's history are also useful for providing a decentralized, | ||
611 | uncoordinated developer team with the ability to collaborate on the | ||
612 | project. | ||
613 | |||
614 | <p>For now, you can ignore the details of setting up a repository, | ||
615 | administering user access, and navigating CVS-specific file formats | ||
616 | (those will be covered in <a href="#Repository_Administration">Repository Administration</a>). For the | ||
617 | moment, we'll concentrate on how to make changes in a working copy. | ||
618 | |||
619 | <p>But first, here is a quick review of terms: | ||
620 | |||
621 | <ul> | ||
622 | |||
623 | <li><dfn>Revision</dfn> A committed change in the history of a file or set of | ||
624 | files. A revision is one "snapshot" in a constantly changing project. | ||
625 | |||
626 | <li><dfn>Repository</dfn> The master copy where CVS stores a project's full | ||
627 | revision history. Each project has exactly one repository. | ||
628 | |||
629 | <li><dfn>Working copy</dfn> The copy in which you actually make changes to a | ||
630 | project. There can be many working copies of a given project; generally | ||
631 | each developer has his or her own copy. | ||
632 | |||
633 | <li><dfn>Check out</dfn> To request a working copy from the repository. Your | ||
634 | working copy reflects the state of the project as of the moment you | ||
635 | checked it out; when you and other developers make changes, you must use | ||
636 | commit and update to "publish" your changes and view others' changes. | ||
637 | |||
638 | <li><dfn>Commit</dfn> To send changes from your working copy into the central | ||
639 | repository. Also known as <dfn>check-in</dfn>. | ||
640 | |||
641 | <li><dfn>Log message</dfn> A comment you attach to a revision when you commit it, | ||
642 | describing the changes. Others can page through the log messages to get | ||
643 | a summary of what's been going on in a project. | ||
644 | |||
645 | <li><dfn>Update</dfn> To bring others' changes from the repository into your | ||
646 | working copy and to show if your working copy has any uncommitted | ||
647 | changes. Be careful not to confuse this with commit; they are | ||
648 | complementary operations. Mnemonic: update brings your working copy up | ||
649 | to date with the repository copy. | ||
650 | |||
651 | <li><dfn>Conflict</dfn> The situation when two developers try to commit changes | ||
652 | to the same region of the same file. CVS notices and points out | ||
653 | conflicts, but the developers must resolve them. | ||
654 | |||
655 | </ul> | ||
656 | |||
657 | <p><hr> | ||
658 | Node:<a name="A_Day_With_CVS">A Day With CVS</a>, | ||
659 | Next:<a rel=next href="#Other_Useful_CVS_Commands">Other Useful CVS Commands</a>, | ||
660 | Previous:<a rel=previous href="#Basic_Concepts">Basic Concepts</a>, | ||
661 | Up:<a rel=up href="#An_Overview_of_CVS">An Overview of CVS</a> | ||
662 | <br> | ||
663 | |||
664 | <h2>A Day With CVS</h2> | ||
665 | |||
666 | <p>This section describes some basic CVS operations, then follows with a | ||
667 | sample session covering typical CVS usage. As the guided tour | ||
668 | progresses, we'll also start to look at how CVS works internally. | ||
669 | |||
670 | <p>Although you don't need to understand every last detail of CVS's | ||
671 | implementation to use it, a basic knowledge of how it works is | ||
672 | invaluable in choosing the best way to achieve a given result. CVS is | ||
673 | more like a bicycle than an automobile, in the sense that its mechanisms | ||
674 | are entirely transparent to anyone who cares to look. As with a | ||
675 | bicycle, you can just hop on and start riding immediately. However, if | ||
676 | you take a few moments to study how the gears work, you'll be able to | ||
677 | ride it much more efficiently. (In the case of CVS, I'm not sure | ||
678 | whether transparency was a deliberate design decision or an accident, | ||
679 | but it does seem to be a property shared by many free programs. | ||
680 | Externally visible implementations have the advantage of encouraging the | ||
681 | users to become contributing developers by exposing them to the system's | ||
682 | inner workings right from the start.) | ||
683 | |||
684 | <p>Each part of the tour may make use of knowledge introduced in previous | ||
685 | parts. Therefore, if this is your first time, I recommend that you | ||
686 | simply start at the beginning and take the tour sequentially, without | ||
687 | skipping over anything. The menu below is merely meant as a convenience | ||
688 | for repeat visitors - you shouldn't use it to jump directly to a | ||
689 | section that interests you unless you're already familiar with the | ||
690 | material in the previous sections. | ||
691 | |||
692 | <ul> | ||
693 | <li><a href="#Conventions_Used_In_This_Tour">Conventions Used In This Tour</a>: | ||
694 | <li><a href="#Invoking_CVS">Invoking CVS</a>: | ||
695 | <li><a href="#Accessing_A_Repository">Accessing A Repository</a>: | ||
696 | <li><a href="#Starting_A_New_Project">Starting A New Project</a>: | ||
697 | <li><a href="#Checking_Out_A_Working_Copy">Checking Out A Working Copy</a>: | ||
698 | <li><a href="#Version_Versus_Revision">Version Versus Revision</a>: | ||
699 | <li><a href="#Making_A_Change">Making A Change</a>: | ||
700 | <li><a href="#Finding_Out_What_You__And_Others__Did_--_update_And_diff">Finding Out What You (And Others) Did -- update And diff</a>: | ||
701 | <li><a href="#CVS_And_Implied_Arguments">CVS And Implied Arguments</a>: | ||
702 | <li><a href="#Committing">Committing</a>: | ||
703 | <li><a href="#Revision_Numbers">Revision Numbers</a>: | ||
704 | <li><a href="#Detecting_And_Resolving_Conflicts">Detecting And Resolving Conflicts</a>: | ||
705 | <li><a href="#Finding_Out_Who_Did_What__Browsing_Log_Messages_">Finding Out Who Did What (Browsing Log Messages)</a>: | ||
706 | <li><a href="#Examining_And_Reverting_Changes">Examining And Reverting Changes</a>: | ||
707 | <li><a href="#The_Slow_Method_Of_Reverting">The Slow Method Of Reverting</a>: | ||
708 | <li><a href="#The_Fast_Method_Of_Reverting">The Fast Method Of Reverting</a>: | ||
709 | </ul> | ||
710 | |||
711 | <p><hr> | ||
712 | Node:<a name="Conventions_Used_In_This_Tour">Conventions Used In This Tour</a>, | ||
713 | Next:<a rel=next href="#Invoking_CVS">Invoking CVS</a>, | ||
714 | Up:<a rel=up href="#A_Day_With_CVS">A Day With CVS</a> | ||
715 | <br> | ||
716 | |||
717 | <h3>Conventions Used In This Tour</h3> | ||
718 | |||
719 | <p>The tour takes place in a Unix environment. CVS also runs on Windows | ||
720 | and Macintosh operating systems, and Tim Endres of Ice Engineering has | ||
721 | even written a Java client (see http://www.trustice.com/java/jcvs/), | ||
722 | which can be | ||
723 | run anywhere Java runs. However, I'm going to take a wild guess and | ||
724 | assume that the majority of CVS users - present and potential - are | ||
725 | most likely working in a Unix command-line environment. If you aren't | ||
726 | one of these, the examples in the tour should be easy to translate to | ||
727 | other interfaces. Once you understand the concepts, you can sit down at | ||
728 | any CVS front end and work with it (trust me, I've done it many times). | ||
729 | |||
730 | <p>The examples in the tour are oriented toward people who will be using | ||
731 | CVS to keep track of programming projects. However, CVS operations are | ||
732 | applicable to all text documents, not just source code. | ||
733 | |||
734 | <p>The tour also assumes that you already have CVS installed (it's present | ||
735 | by default on many of the popular free Unix systems, so you might | ||
736 | already have it without knowing it) and that you have access to a | ||
737 | repository. Even if you are not set up, you can still benefit from | ||
738 | reading the tour. In <a href="#Repository_Administration">Repository Administration</a>, you'll learn how | ||
739 | to install CVS and set up repositories. | ||
740 | |||
741 | <p>Assuming CVS is installed, you should take a moment to find the online | ||
742 | CVS manual. Known familiarly as the "Cederqvist" (after Per Cederqvist, | ||
743 | its original author), it comes with the CVS source distribution and is | ||
744 | usually the most up-to-date reference available. It's written in | ||
745 | Texinfo format and should be available on Unix systems in the "Info" | ||
746 | documentation hierarchy. You can read it either with the command line | ||
747 | info program | ||
748 | |||
749 | <pre>floss$ info cvs | ||
750 | </pre> | ||
751 | |||
752 | <p>or by pressing Ctrl+H and then typing "i" inside Emacs. If neither of | ||
753 | these works for you, consult your local Unix guru (or see | ||
754 | <a href="#Repository_Administration">Repository Administration</a> regarding installation issues). You'll | ||
755 | definitely want to have the Cederqvist at your fingertips if you're | ||
756 | going to be using CVS regularly. | ||
757 | |||
758 | <p><hr> | ||
759 | Node:<a name="Invoking_CVS">Invoking CVS</a>, | ||
760 | Next:<a rel=next href="#Accessing_A_Repository">Accessing A Repository</a>, | ||
761 | Previous:<a rel=previous href="#Conventions_Used_In_This_Tour">Conventions Used In This Tour</a>, | ||
762 | Up:<a rel=up href="#A_Day_With_CVS">A Day With CVS</a> | ||
763 | <br> | ||
764 | |||
765 | <h3>Invoking CVS</h3> | ||
766 | |||
767 | <p>CVS is one program, but it can perform many different actions: updating, | ||
768 | committing, branching, diffing, and so on. When you invoke CVS, you | ||
769 | must specify which action you want to perform. Thus, the format of a | ||
770 | CVS invocation is: | ||
771 | |||
772 | <pre>floss$ cvs command | ||
773 | </pre> | ||
774 | |||
775 | <p>For example, you can use | ||
776 | |||
777 | <pre>floss$ cvs update | ||
778 | floss$ cvs diff | ||
779 | floss$ cvs commit | ||
780 | </pre> | ||
781 | |||
782 | <p>and so on. (Don't bother to try running any of those particular | ||
783 | commands yet, though; they won't do anything until you're in a working | ||
784 | copy, which we'll get to shortly.) | ||
785 | |||
786 | <p>Both CVS and the command can take options. Options that affect the | ||
787 | behavior of CVS, independently of the command being run, are called | ||
788 | global options; command-specific options are just called command | ||
789 | options. Global options always go to the left of the command; command | ||
790 | options, to its right. So in | ||
791 | |||
792 | <pre>floss$ cvs -Q update -p | ||
793 | </pre> | ||
794 | |||
795 | <p>-Q is a global option, and -p is a command option. (If you're curious, | ||
796 | -Q means "quietly"-that is, suppress all diagnostic output, and print | ||
797 | error messages only if the command absolutely cannot be completed for | ||
798 | some reason; -p means to send the results of update to standard output | ||
799 | instead of to files.) | ||
800 | |||
801 | <p><hr> | ||
802 | Node:<a name="Accessing_A_Repository">Accessing A Repository</a>, | ||
803 | Next:<a rel=next href="#Starting_A_New_Project">Starting A New Project</a>, | ||
804 | Previous:<a rel=previous href="#Invoking_CVS">Invoking CVS</a>, | ||
805 | Up:<a rel=up href="#A_Day_With_CVS">A Day With CVS</a> | ||
806 | <br> | ||
807 | |||
808 | <h3>Accessing A Repository</h3> | ||
809 | |||
810 | <p>Before you can do anything, you must tell CVS the location of the | ||
811 | repository you'll be accessing. This isn't a concern if you already | ||
812 | have a working copy checked out - any working copy knows what | ||
813 | repository it came from, so CVS can automatically deduce the repository | ||
814 | for a given working copy. However, let's assume you don't have a | ||
815 | working copy yet, so you need to tell CVS explicitly where to go. This | ||
816 | is done with the -d global option (the -d stands for "directory", an | ||
817 | abbreviation for which there is a historical justification, although -r | ||
818 | for "repository" might have been better), followed by the path to the | ||
819 | repository. For example, assuming the repository is on the local | ||
820 | machine in /usr/local/cvs (a fairly standard location): | ||
821 | |||
822 | <pre>floss$ cvs -d /usr/local/cvs command | ||
823 | </pre> | ||
824 | |||
825 | <p>In many cases, however, the repository is on another machine and must | ||
826 | therefore be reached over the network. CVS provides a choice of network | ||
827 | access methods; which one you'll use depends mostly on the security | ||
828 | needs of the repository machine (hereinafter referred to as "the | ||
829 | server"). Setting up the server to allow various remote access methods | ||
830 | is covered in <a href="#Repository_Administration">Repository Administration</a>; here we'll deal only with | ||
831 | the client side. | ||
832 | |||
833 | <p>Fortunately, all the remote access methods share a common invocation | ||
834 | syntax. In general, to specify a remote repository as opposed to a | ||
835 | local one, you just use a longer repository path. You first name the | ||
836 | access method, delimited on each side by colons, followed by the | ||
837 | username and the server name (joined with an @ sign), another separator | ||
838 | colon, and finally the path to the repository directory on the server. | ||
839 | |||
840 | <p>Let's look at the <dfn>pserver</dfn> access method, which stands for | ||
841 | "password-authenticated server": | ||
842 | |||
843 | <pre>floss$ cvs -d :pserver:jrandom@cvs.foobar.com:/usr/local/cvs login | ||
844 | (Logging in to jrandom@cvs.foobar.com) | ||
845 | CVS password: (enter your CVS password here) | ||
846 | floss$ | ||
847 | </pre> | ||
848 | |||
849 | <p>The long repository path following -d told CVS to use the pserver access | ||
850 | method, with the username jrandom, on the server cvs.foobar.com, which | ||
851 | has a CVS repository in /usr/local/cvs. There's no requirement that the | ||
852 | hostname be "cvs.something.com" by the way; that's a common convention, | ||
853 | but it could just as easily have been: | ||
854 | |||
855 | <pre>floss$ cvs -d :pserver:jrandom@fish.foobar.org:/usr/local/cvs command | ||
856 | </pre> | ||
857 | |||
858 | <p>The command actually run was login, which verifies that you are | ||
859 | authorized to work with this repository. It prompts for a password, | ||
860 | then contacts the server to verify the password. Following Unix custom, | ||
861 | cvs login returns silently if the login succeeds; it shows an error | ||
862 | message if it fails (for instance, because the password is incorrect). | ||
863 | |||
864 | <p>You only have to log in once from your local machine to a given CVS | ||
865 | server. After a successful login, CVS stores the password in your home | ||
866 | directory, in a file called .cvspass. It consults that file every time | ||
867 | a repository is contacted via the pserver method, so you only have to | ||
868 | run login the first time you access a given CVS server from a particular | ||
869 | client machine. Of course, you can rerun cvs login anytime if the | ||
870 | password changes. | ||
871 | |||
872 | <p>Note: pserver is currently the only access method requiring an initial | ||
873 | login like this; with the others, you can start running regular CVS | ||
874 | commands immediately. | ||
875 | |||
876 | <p>Once you've stored the authentication information in your .cvspass file, | ||
877 | you can run other CVS commands using the same command-line syntax: | ||
878 | |||
879 | <pre>floss$ cvs -d :pserver:jrandom@cvs.foobar.com:/usr/local/cvs command | ||
880 | </pre> | ||
881 | |||
882 | <p>Getting pserver to work in Windows may require an extra step. Windows | ||
883 | doesn't have the Unix concept of a home directory, so CVS doesn't know | ||
884 | where to put the .cvspass file. You'll have to specify a location. | ||
885 | It's normal to designate the root of the C: drive as the home directory: | ||
886 | |||
887 | <pre>C:\WINDOWS> set HOME=C: | ||
888 | C:\WINDOWS> cvs -d :pserver:jrandom@cvs.foobar.com:/usr/local/cvs login | ||
889 | (Logging in to jrandom@cvs.foobar.com) | ||
890 | CVS password: (enter password here) | ||
891 | C:\WINDOWS> | ||
892 | </pre> | ||
893 | |||
894 | <p>Any folder in the file system will suffice. You may want to avoid | ||
895 | network drives, though, because the contents of your .cvspass file would | ||
896 | then be visible to anyone with access to the drive. | ||
897 | |||
898 | <p>In addition to pserver, CVS supports the ext method (which uses an | ||
899 | external connection program, such as rsh or ssh), kserver (for the | ||
900 | Kerberos security system version 4), and gserver (which uses the GSSAPI, | ||
901 | or Generic Security Services API, and also handles Kerberos versions 5 | ||
902 | and higher). These methods are similar to pserver, but each has its own | ||
903 | idiosyncrasies. | ||
904 | |||
905 | <p>Of these, the <code>ext</code> method is probably the most commonly used. If | ||
906 | you can log into the server with rsh or ssh, you can use the <code>ext</code> | ||
907 | method. You can test it like this: | ||
908 | |||
909 | <pre>floss$ rsh -l jrandom cvs.foobar.com | ||
910 | Password: enter your login password here | ||
911 | </pre> | ||
912 | |||
913 | <p>Okay, let's assume you successfully logged in and logged out of the | ||
914 | server with rsh, so now you're back on the original client machine: | ||
915 | |||
916 | <pre>floss$ CVS_RSH=rsh; export CVS_RSH | ||
917 | floss$ cvs -d :ext:jrandom@cvs.foobar.com:/usr/local/cvs command | ||
918 | </pre> | ||
919 | |||
920 | <p>The first line sets (in Unix Bourne shell syntax) the CVS_RSH | ||
921 | environment variable to rsh, which tells CVS to use the rsh program to | ||
922 | connect. The second line can be any CVS command; you will be prompted | ||
923 | for your password so CVS can log into the server. | ||
924 | |||
925 | <p>If you're in C shell rather than in Bourne shell, try this: | ||
926 | |||
927 | <pre>floss% setenv CVS_RSH rsh | ||
928 | </pre> | ||
929 | |||
930 | <p>and for Windows, try this: | ||
931 | |||
932 | <pre>C:\WINDOWS> set CVS_RSH=rsh | ||
933 | </pre> | ||
934 | |||
935 | <p>The rest of the tour will use the Bourne syntax; translate for your | ||
936 | environment as necessary. | ||
937 | |||
938 | <p>To use ssh (the Secure Shell) instead of rsh, just set the CVS_RSH | ||
939 | variable appropriately: | ||
940 | |||
941 | <pre>floss$ CVS_RSH=ssh; export CVS_RSH | ||
942 | </pre> | ||
943 | |||
944 | <p>Don't get thrown by the fact that the variable's name is CVS_RSH but | ||
945 | you're setting its value to ssh. There are historical reasons for this | ||
946 | (the catch-all Unix excuse, I know). CVS_RSH can point to the name of | ||
947 | any program capable of logging you into the remote server, running | ||
948 | commands, and receiving their output. After rsh, ssh is probably the | ||
949 | most common such program, although there are probably others. Note that | ||
950 | this program must not modify its data stream in any way. This | ||
951 | disqualifies the Windows NT rsh, because it converts (or attempts to | ||
952 | convert) between the DOS and Unix line-ending conventions. You'd have | ||
953 | to get some other rsh for Windows or use a different access method. | ||
954 | |||
955 | <p>The gserver and kserver methods are not used as often as the others and | ||
956 | are not covered here. They're quite similar to what we've covered so | ||
957 | far; see the Cederqvist for details. | ||
958 | |||
959 | <p>If you only use one repository and don't want to type -d repos each | ||
960 | time, just set the CVSROOT environment variable (which perhaps should | ||
961 | have been named CVSREPOS, but it's too late to change that now): | ||
962 | |||
963 | <pre>floss$ CVSROOT=/usr/local/cvs | ||
964 | floss$ export CVSROOT | ||
965 | floss$ echo $CVSROOT | ||
966 | /usr/local/cvs | ||
967 | floss$ | ||
968 | </pre> | ||
969 | |||
970 | <p>or maybe | ||
971 | |||
972 | <pre>floss$ CVSROOT=:pserver:jrandom@cvs.foobar.com:/usr/local/cvs | ||
973 | floss$ export CVSROOT | ||
974 | floss$ echo $CVSROOT | ||
975 | :pserver:jrandom@cvs.foobar.com:/usr/local/cvs | ||
976 | floss$ | ||
977 | </pre> | ||
978 | |||
979 | <p>The rest of this tour assumes that you've set CVSROOT to point to your | ||
980 | repository, so the examples will not show the -d option. If you need to | ||
981 | access many different repositories, you should not set CVSROOT and | ||
982 | should just use -d repos when you need to specify the repository. | ||
983 | |||
984 | <p><hr> | ||
985 | Node:<a name="Starting_A_New_Project">Starting A New Project</a>, | ||
986 | Next:<a rel=next href="#Checking_Out_A_Working_Copy">Checking Out A Working Copy</a>, | ||
987 | Previous:<a rel=previous href="#Accessing_A_Repository">Accessing A Repository</a>, | ||
988 | Up:<a rel=up href="#A_Day_With_CVS">A Day With CVS</a> | ||
989 | <br> | ||
990 | |||
991 | <h3>Starting A New Project</h3> | ||
992 | |||
993 | <p>If you're learning CVS in order to work on a project that's already | ||
994 | under CVS control (that is, it is kept in a repository somewhere), | ||
995 | you'll probably want to skip down to the next section, "Checking Out A | ||
996 | Working Copy." On the other hand, if you want to take existing source | ||
997 | code and put it into CVS, this is the section for you. Note that it | ||
998 | still assumes you have access to an existing repository; see | ||
999 | <a href="#Repository_Administration">Repository Administration</a> if you need to set up a repository | ||
1000 | first. | ||
1001 | |||
1002 | <p>Putting a new project into a CVS repository is known as <dfn>importing</dfn>. | ||
1003 | The CVS command, as you may have guessed, is | ||
1004 | |||
1005 | <pre>floss$ cvs import | ||
1006 | </pre> | ||
1007 | |||
1008 | <p>except that it needs some more options (and needs to be in the right | ||
1009 | location) to succeed. First, go into the top-level directory of your | ||
1010 | project tree: | ||
1011 | |||
1012 | <pre>floss$ cd myproj | ||
1013 | floss$ ls | ||
1014 | README.txt a-subdir/ b-subdir/ hello.c | ||
1015 | floss$ | ||
1016 | </pre> | ||
1017 | |||
1018 | <p>This project has two files - README.txt and hello.c - in the top | ||
1019 | level, plus two subdirectories - a-subdir and b-subdir - plus some | ||
1020 | more files (not shown in the example) inside those subdirectories. When | ||
1021 | you import a project, CVS imports everything in the tree, starting from | ||
1022 | the current directory and working its way down. Therefore, you should | ||
1023 | make sure that the only files in the tree are ones you want to be | ||
1024 | permanent parts of the project. Any old backup files, scratch files, | ||
1025 | and so on should all be cleaned out. | ||
1026 | |||
1027 | <p>The general syntax of an import command is | ||
1028 | |||
1029 | <pre>floss$ cvs import -m "log msg" projname vendortag releasetag | ||
1030 | </pre> | ||
1031 | |||
1032 | <p>The -m flag (for message) is for specifying a short message describing | ||
1033 | the import. This will be the first log message for the entire project; | ||
1034 | every commit thereafter will also have its own log message. These | ||
1035 | messages are mandatory; if you don't give the -m flag, CVS automatically | ||
1036 | starts up an editor (by consulting the EDITOR environment variable) for | ||
1037 | you to type a log message in. After you save the log message and exit | ||
1038 | the editor, the import then continues. | ||
1039 | |||
1040 | <p>The next argument is the project's name (we'll use "myproj"). This is | ||
1041 | the name under which you'll check out the project from the repository. | ||
1042 | (What actually happens is that a directory of that name gets created in | ||
1043 | the repository, but more on that in <a href="#Repository_Administration">Repository Administration</a>.) | ||
1044 | The name you choose now does not need to be the same as the name of the | ||
1045 | current directory, although in most cases it usually is. | ||
1046 | |||
1047 | <p>The vendortag and releasetag arguments are a bit of bookkeeping for CVS. | ||
1048 | Don't worry about them now; it hardly matters what you use. In | ||
1049 | <a href="#Advanced_CVS">Advanced CVS</a> you'll learn about the rare circumstances where | ||
1050 | they're significant. For now, we'll use a username and "start" for | ||
1051 | those arguments. | ||
1052 | |||
1053 | <p>We're ready to run import: | ||
1054 | |||
1055 | <pre>floss$ cvs import -m "initial import into CVS" myproj jrandom start | ||
1056 | N myproj/hello.c | ||
1057 | N myproj/README.txt | ||
1058 | cvs import: Importing /usr/local/cvs/myproj/a-subdir | ||
1059 | N myproj/a-subdir/whatever.c | ||
1060 | cvs import: Importing /usr/local/cvs/myproj/a-subdir/subsubdir | ||
1061 | N myproj/a-subdir/subsubdir/fish.c | ||
1062 | cvs import: Importing /usr/local/cvs/myproj/b-subdir | ||
1063 | N myproj/b-subdir/random.c | ||
1064 | |||
1065 | No conflicts created by this import | ||
1066 | floss$ | ||
1067 | </pre> | ||
1068 | |||
1069 | <p>Congratulations! If you ran that command (or something similar), you've | ||
1070 | finally done something that affects the repository. | ||
1071 | |||
1072 | <p>Reading over the output of the import command, you'll notice that CVS | ||
1073 | precedes each filename with a single letter - in this case, "N" for | ||
1074 | "new file". The use of a single letter on the left to indicate the | ||
1075 | status of a file is a general pattern in CVS command output. We'll see | ||
1076 | it later in checkout and update as well. | ||
1077 | |||
1078 | <p>You might think that, having just imported the project, you can start | ||
1079 | working in the tree immediately. This is not the case, however. The | ||
1080 | current directory tree is still not a CVS working copy. It was the | ||
1081 | source for the import command, true, but it wasn't magically changed | ||
1082 | into a CVS working copy merely by virtue of having been imported. To | ||
1083 | get a working copy, you need to check one out from the repository. | ||
1084 | |||
1085 | <p>First, though, you might want to archive the current project tree. The | ||
1086 | reason is that once the sources are in CVS, you don't want to confuse | ||
1087 | yourself by accidentally editing copies that aren't in version control | ||
1088 | (because those changes won't become part of the project's history). You | ||
1089 | want to do all of your editing in a working copy from now on. However, | ||
1090 | you also don't want to remove the imported tree entirely, because you | ||
1091 | haven't yet verified that the repository actually has the files. Of | ||
1092 | course, you can be 99.999 percent certain that it does because the | ||
1093 | import command returned with no error, but why take chances? Paranoia | ||
1094 | pays, as every programmer knows. Therefore, do something like this: | ||
1095 | |||
1096 | <pre>floss$ ls | ||
1097 | README.txt a-subdir/ b-subdir/ hello.c | ||
1098 | floss$ cd .. | ||
1099 | floss$ ls | ||
1100 | myproj/ | ||
1101 | floss$ mv myproj was_myproj | ||
1102 | floss$ ls | ||
1103 | was_myproj/ | ||
1104 | floss$ | ||
1105 | </pre> | ||
1106 | |||
1107 | <p>There. You still have the original files, but they're clearly named as | ||
1108 | an obsolete version, so they won't be in the way when you get a real | ||
1109 | working copy. Now you're ready to check out. | ||
1110 | |||
1111 | <p><hr> | ||
1112 | Node:<a name="Checking_Out_A_Working_Copy">Checking Out A Working Copy</a>, | ||
1113 | Next:<a rel=next href="#Version_Versus_Revision">Version Versus Revision</a>, | ||
1114 | Previous:<a rel=previous href="#Starting_A_New_Project">Starting A New Project</a>, | ||
1115 | Up:<a rel=up href="#A_Day_With_CVS">A Day With CVS</a> | ||
1116 | <br> | ||
1117 | |||
1118 | <h3>Checking Out A Working Copy</h3> | ||
1119 | |||
1120 | <p>The command to check out a project is exactly what you think it is: | ||
1121 | |||
1122 | <pre>floss$ cvs checkout myproj | ||
1123 | cvs checkout: Updating myproj | ||
1124 | U myproj/README.txt | ||
1125 | U myproj/hello.c | ||
1126 | cvs checkout: Updating myproj/a-subdir | ||
1127 | U myproj/a-subdir/whatever.c | ||
1128 | cvs checkout: Updating myproj/a-subdir/subsubdir | ||
1129 | U myproj/a-subdir/subsubdir/fish.c | ||
1130 | cvs checkout: Updating myproj/b-subdir | ||
1131 | U myproj/b-subdir/random.c | ||
1132 | |||
1133 | floss$ ls | ||
1134 | myproj/ was_myproj/ | ||
1135 | floss$ cd myproj | ||
1136 | floss$ ls | ||
1137 | CVS/ README.txt a-subdir/ b-subdir/ hello.c | ||
1138 | floss$ | ||
1139 | </pre> | ||
1140 | |||
1141 | <p>Behold - your first working copy! Its contents are exactly the same as | ||
1142 | what you imported, with the addition of a subdirectory named "CVS". | ||
1143 | That's where CVS stores version control information. Actually, each | ||
1144 | directory in the project has a CVS subdirectory: | ||
1145 | |||
1146 | <pre>floss$ ls a-subdir | ||
1147 | CVS/ subsubdir/ whatever.c | ||
1148 | floss$ ls a-subdir/subsubdir/ | ||
1149 | CVS/ fish.c | ||
1150 | floss$ ls b-subdir | ||
1151 | CVS/ random.c | ||
1152 | </pre> | ||
1153 | |||
1154 | <p>The fact that CVS keeps its revision information in subdirectories named | ||
1155 | CVS means that your project can never contain subdirectories of its own | ||
1156 | named CVS. In practice, I've never heard of this being a problem. | ||
1157 | |||
1158 | <p>Before editing any files, let's take a peek inside the black box: | ||
1159 | |||
1160 | <pre>floss$ cd CVS | ||
1161 | floss$ ls | ||
1162 | Entries Repository Root | ||
1163 | floss$ cat Root | ||
1164 | /usr/local/cvs | ||
1165 | floss$ cat Repository | ||
1166 | myproj | ||
1167 | floss$ | ||
1168 | </pre> | ||
1169 | |||
1170 | <p>Nothing too mysterious there. The Root file points to repository, and | ||
1171 | the Repository file points to a project inside the repository. If | ||
1172 | that's a little confusing, let me explain. | ||
1173 | |||
1174 | <p>There is a longstanding confusion about terminology in CVS. The word | ||
1175 | "repository" is used to refer to two different things. Sometimes, it | ||
1176 | means the root directory of a repository (for example, /usr/local/cvs), | ||
1177 | which can contain many projects; this is what the Root file refers to. | ||
1178 | But other times, it means one particular project-specific subdirectory | ||
1179 | within a repository root (for example, /usr/local/cvs/myproj, | ||
1180 | /usr/local/cvs/yourproj, or /usr/local/cvs/fish). The Repository file | ||
1181 | inside a CVS subdirectory takes the latter meaning. | ||
1182 | |||
1183 | <p>In this book, "repository" generally means Root (that is, the top-level | ||
1184 | repository), although it may occasionally be used to mean a | ||
1185 | project-specific subdirectory. If the intended sense can't be figured | ||
1186 | out from the context, there will be clarifying text. Note that the | ||
1187 | Repository file may sometimes contain an absolute path to the project | ||
1188 | name instead of a relative path. This can make it slightly redundant | ||
1189 | with the Root file: | ||
1190 | |||
1191 | <pre>floss$ cd CVS | ||
1192 | floss$ cat Root | ||
1193 | :pserver:jrandom@cvs.foobar.com:/usr/local/cvs | ||
1194 | floss$ cat Repository | ||
1195 | /usr/local/cvs/myproj | ||
1196 | floss$ | ||
1197 | </pre> | ||
1198 | |||
1199 | <p>The Entries file stores information about the individual files in the | ||
1200 | project. Each line deals with one file, and there are only lines for | ||
1201 | files or subdirectories in the immediate parent directory. Here's the | ||
1202 | top-level CVS/Entries file in myproj: | ||
1203 | |||
1204 | <pre>floss$ cat Entries | ||
1205 | /README.txt/1.1.1.1/Sun Apr 18 18:18:22 1999// | ||
1206 | /hello.c/1.1.1.1/Sun Apr 18 18:18:22 1999// | ||
1207 | D/a-subdir//// | ||
1208 | D/b-subdir//// | ||
1209 | </pre> | ||
1210 | |||
1211 | <p>The format of each line is | ||
1212 | |||
1213 | <pre>/filename/revision number/last modification date// | ||
1214 | </pre> | ||
1215 | |||
1216 | <p>and the directory lines are prefixed with "D". (CVS doesn't really keep | ||
1217 | a change history for directories, so the fields for revision number and | ||
1218 | datestamp are empty.) | ||
1219 | |||
1220 | <p>The datestamps record the date and time of the last update (in Universal | ||
1221 | Time, not local time) of the files in the working copy. That way, CVS | ||
1222 | can easily tell whether a file has been modified since the last | ||
1223 | checkout, update, or commit. If the file system timestamp differs from | ||
1224 | the timestamp in the CVS/Entries file, CVS knows (without even having to | ||
1225 | consult the repository) that the file was probably modified. | ||
1226 | |||
1227 | <p>If you take a look at the CVS/* files in one of the subdirectories | ||
1228 | |||
1229 | <pre>floss$ cd a-subdir/CVS | ||
1230 | floss$ cat Root | ||
1231 | /usr/local/cvs | ||
1232 | floss$ cat Repository | ||
1233 | myproj/a-subdir | ||
1234 | floss$ cat Entries | ||
1235 | /whatever.c/1.1.1.1/Sun Apr 18 18:18:22 1999// | ||
1236 | D/subsubdir//// | ||
1237 | floss$ | ||
1238 | </pre> | ||
1239 | |||
1240 | <p>you can see that the root repository has not changed, but the Repository | ||
1241 | file spells out the location of this subdirectory of the project, and | ||
1242 | the Entries file contains different lines. | ||
1243 | |||
1244 | <p>Immediately after import, the revision number of every file in the | ||
1245 | project is shown as 1.1.1.1. This initial revision number is a bit of a | ||
1246 | special case, so we won't examine it in detail just yet; we'll take a | ||
1247 | closer look at revision numbers after we've committed some changes. | ||
1248 | |||
1249 | <p><hr> | ||
1250 | Node:<a name="Version_Versus_Revision">Version Versus Revision</a>, | ||
1251 | Next:<a rel=next href="#Making_A_Change">Making A Change</a>, | ||
1252 | Previous:<a rel=previous href="#Checking_Out_A_Working_Copy">Checking Out A Working Copy</a>, | ||
1253 | Up:<a rel=up href="#A_Day_With_CVS">A Day With CVS</a> | ||
1254 | <br> | ||
1255 | |||
1256 | <h3>Version Versus Revision</h3> | ||
1257 | |||
1258 | <p>The internal revision number that CVS keeps for each file is unrelated | ||
1259 | to the version number of the software product of which the files are | ||
1260 | part. For example, you may have a project composed of three files, | ||
1261 | whose internal revision numbers on May 3, 1999, were 1.2, 1.7, and 2.48. | ||
1262 | On that day, you package up a new release of the software and release it | ||
1263 | as SlickoSoft Version 3. This is purely a marketing decision and | ||
1264 | doesn't affect the CVS revisions at all. The CVS revision numbers are | ||
1265 | invisible to your customers (unless you give them repository access); | ||
1266 | the only publicly visible number is the "3" in Version 3. You could | ||
1267 | have called it Version 1729 as far as CVS is concerned - the version | ||
1268 | number (or "release" number) has nothing to do with CVS's internal | ||
1269 | change tracking. | ||
1270 | |||
1271 | <p>To avoid confusion, I'll use the word "revision" to refer exclusively to | ||
1272 | the internal revision numbers of files under CVS control. I may still | ||
1273 | call CVS a "version control system", however, because "revision control | ||
1274 | system" just sounds too awkward. | ||
1275 | |||
1276 | <p><hr> | ||
1277 | Node:<a name="Making_A_Change">Making A Change</a>, | ||
1278 | Next:<a rel=next href="#Finding_Out_What_You__And_Others__Did_--_update_And_diff">Finding Out What You (And Others) Did -- update And diff</a>, | ||
1279 | Previous:<a rel=previous href="#Version_Versus_Revision">Version Versus Revision</a>, | ||
1280 | Up:<a rel=up href="#A_Day_With_CVS">A Day With CVS</a> | ||
1281 | <br> | ||
1282 | |||
1283 | <h3>Making A Change</h3> | ||
1284 | |||
1285 | <p>The project as it stands doesn't do much. Here are the contents of | ||
1286 | hello.c: | ||
1287 | |||
1288 | <pre>floss$ cat hello.c | ||
1289 | #include <stdio.h> | ||
1290 | |||
1291 | void | ||
1292 | main () | ||
1293 | { | ||
1294 | printf ("Hello, world!\n"); | ||
1295 | } | ||
1296 | </pre> | ||
1297 | |||
1298 | <p>Let's make the first change to the project since importing it; we'll add | ||
1299 | the line | ||
1300 | |||
1301 | <pre>printf ("Goodbye, world!\n"); | ||
1302 | </pre> | ||
1303 | |||
1304 | <p>right after the Hello, world!. Invoke your favorite editor and make the | ||
1305 | change: | ||
1306 | |||
1307 | <pre>floss$ emacs hello.c | ||
1308 | ... | ||
1309 | </pre> | ||
1310 | |||
1311 | <p>This was a fairly simple change, one where you're not likely to forget | ||
1312 | what you did. But in a larger, more complex project, it's quite | ||
1313 | possible you may edit a file, be interrupted by something else, and | ||
1314 | return several days later and be unable to remember exactly what you | ||
1315 | did, or even to remember if you changed anything at all. Which brings | ||
1316 | us to our first "CVS Saves Your Life" situation: comparing your working | ||
1317 | copy against the repository. | ||
1318 | |||
1319 | <p><hr> | ||
1320 | Node:<a name="Finding_Out_What_You__And_Others__Did_--_update_And_diff">Finding Out What You (And Others) Did -- update And diff</a>, | ||
1321 | Next:<a rel=next href="#CVS_And_Implied_Arguments">CVS And Implied Arguments</a>, | ||
1322 | Previous:<a rel=previous href="#Making_A_Change">Making A Change</a>, | ||
1323 | Up:<a rel=up href="#A_Day_With_CVS">A Day With CVS</a> | ||
1324 | <br> | ||
1325 | |||
1326 | <h3>Finding Out What You (And Others) Did - update And diff</h3> | ||
1327 | |||
1328 | <p>Previously, I've talked about updating as a way of bringing changes down | ||
1329 | from the repository into your working copy - that is, as a way of | ||
1330 | getting other people's changes. However, update is really a bit more | ||
1331 | complex; it compares the overall state of the working copy with the | ||
1332 | state of the project in the repository. Even if nothing in the | ||
1333 | repository has changed since checkout, something in the working copy may | ||
1334 | have, and update will show that, too: | ||
1335 | |||
1336 | <pre>floss$ cvs update | ||
1337 | cvs update: Updating . | ||
1338 | M hello.c | ||
1339 | cvs update: Updating a-subdir | ||
1340 | cvs update: Updating a-subdir/subsubdir | ||
1341 | cvs update: Updating b-subdir | ||
1342 | </pre> | ||
1343 | |||
1344 | <p>The M next to hello.c means the file has been modified since it was last | ||
1345 | checked out, and the modifications have not yet been committed to the | ||
1346 | repository. | ||
1347 | |||
1348 | <p>Sometimes, merely knowing which files you've edited is all you need. | ||
1349 | However, if you want a more detailed look at the changes, you can get a | ||
1350 | full report in diff format. The diff command compares the possibly | ||
1351 | modified files in the working copy to their counterparts in the | ||
1352 | repository and displays any differences: | ||
1353 | |||
1354 | <pre>floss$ cvs diff | ||
1355 | cvs diff: Diffing . | ||
1356 | Index: hello.c | ||
1357 | =================================================================== | ||
1358 | RCS file: /usr/local/cvs/myproj/hello.c,v | ||
1359 | retrieving revision 1.1.1.1 | ||
1360 | diff -r1.1.1.1 hello.c | ||
1361 | 6a7 | ||
1362 | > printf ("Goodbye, world!\n"); | ||
1363 | cvs diff: Diffing a-subdir | ||
1364 | cvs diff: Diffing a-subdir/subsubdir | ||
1365 | cvs diff: Diffing b-subdir | ||
1366 | </pre> | ||
1367 | |||
1368 | <p>That's helpful, if a bit obscure, but there's still a lot of cruft in | ||
1369 | the output. For starters, you can ignore most of the first few lines. | ||
1370 | They just name the repository file and give the number of the last | ||
1371 | checked-in revision. These are useful pieces of information under other | ||
1372 | circumstances (we'll look more closely at them later), but you don't | ||
1373 | need them when you're just trying to get a sense of what changes have | ||
1374 | been made in the working copy. | ||
1375 | |||
1376 | <p>A more serious impediment to reading the diff is that CVS is announcing | ||
1377 | its entry as it goes into each directory during the update. This can be | ||
1378 | useful during long updates on large projects, as it gives you a sense of | ||
1379 | how much longer the command will take, but right now it's just getting | ||
1380 | in the way of reading the diff. Let's tell CVS to be quiet about where | ||
1381 | it's working, with the -Q global option: | ||
1382 | |||
1383 | <pre>floss$ cvs -Q diff | ||
1384 | Index: hello.c | ||
1385 | =================================================================== | ||
1386 | RCS file: /usr/local/cvs/myproj/hello.c,v | ||
1387 | retrieving revision 1.1.1.1 | ||
1388 | diff -r1.1.1.1 hello.c | ||
1389 | 6a7 | ||
1390 | > printf ("Goodbye, world!\n"); | ||
1391 | </pre> | ||
1392 | |||
1393 | <p>Better - at least some of the cruft is gone. However, the diff is | ||
1394 | still hard to read. It's telling you that at line 6, a new line was | ||
1395 | added (that is, what became line 7), whose contents were: | ||
1396 | |||
1397 | <pre>printf ("Goodbye, world!\n"); | ||
1398 | </pre> | ||
1399 | |||
1400 | <p>The preceding ">" in the diff tells you that this line is present in the | ||
1401 | newer version of the file but not in the older one. | ||
1402 | |||
1403 | <p>The format could be made even more readable, however. Most people find | ||
1404 | "context" diff format easier to read because it displays a few lines of | ||
1405 | context on either side of a change. Context diffs are generated by | ||
1406 | passing the -c flag to diff: | ||
1407 | |||
1408 | <pre>floss$ cvs -Q diff -c | ||
1409 | Index: hello.c | ||
1410 | =================================================================== | ||
1411 | RCS file: /usr/local/cvs/myproj/hello.c,v | ||
1412 | retrieving revision 1.1.1.1 | ||
1413 | diff -c -r1.1.1.1 hello.c | ||
1414 | *** hello.c 1999/04/18 18:18:22 1.1.1.1 | ||
1415 | --- hello.c 1999/04/19 02:17:07 | ||
1416 | *************** | ||
1417 | *** 4,7 **** | ||
1418 | ---4,8 -- | ||
1419 | main () | ||
1420 | { | ||
1421 | printf ("Hello, world!\n"); | ||
1422 | + printf ("Goodbye, world!\n"); | ||
1423 | } | ||
1424 | </pre> | ||
1425 | |||
1426 | <p>Now that's clarity! Even if you're not used to reading context diffs, a | ||
1427 | glance at the preceding output will probably make it obvious what | ||
1428 | happened: a new line was added (the + in the first column signifies an | ||
1429 | added line) between the line that prints Hello, world! and the final | ||
1430 | curly brace. | ||
1431 | |||
1432 | <p>We don't need to be able to read context diffs perfectly (that's patch's | ||
1433 | job), but it's worth taking the time to acquire at least a passing | ||
1434 | familiarity with the format. The first two lines (after the | ||
1435 | introductory cruft) are | ||
1436 | |||
1437 | <pre>*** hello.c 1999/04/18 18:18:22 1.1.1.1 | ||
1438 | --- hello.c 1999/04/19 02:17:07 | ||
1439 | </pre> | ||
1440 | |||
1441 | <p>and they tell you what is being diffed against what. In this case, | ||
1442 | revision 1.1.1.1 of hello.c is being compared against a modified version | ||
1443 | of the same file (thus, there's no revision number for the second line, | ||
1444 | because only the working copy's changes haven't been committed to the | ||
1445 | repository yet). The lines of asterisks and dashes identify sections | ||
1446 | farther down in the diff. Later on, a line of asterisks, with a line | ||
1447 | number range embedded, precedes a section from the original file. Then | ||
1448 | a line of dashes, with a new and potentially different line number range | ||
1449 | embedded, precedes a section from the modified file. These sections are | ||
1450 | organized into contrasting pairs (known as "hunks"), one side from the | ||
1451 | old file and the other side from the new. | ||
1452 | |||
1453 | <p>Our diff has one hunk: | ||
1454 | |||
1455 | <pre>*************** | ||
1456 | *** 4,7 **** | ||
1457 | --- 4,8 -- | ||
1458 | main () | ||
1459 | { | ||
1460 | printf ("Hello, world!\n"); | ||
1461 | + printf ("Goodbye, world!\n"); | ||
1462 | } | ||
1463 | </pre> | ||
1464 | |||
1465 | <p>The first section of the hunk is empty, meaning that no material was | ||
1466 | removed from the original file. The second section shows that, in the | ||
1467 | corresponding place in the new file, one line has been added; it's | ||
1468 | marked with a "+". (When diff quotes excerpts from files, it reserves | ||
1469 | the first two columns on the left for special codes, such as "+" so the | ||
1470 | entire excerpt appears to be indented by two spaces. This extra | ||
1471 | indentation is stripped off when the diff is applied, of course.) | ||
1472 | |||
1473 | <p>The line number ranges show the hunk's coverage, including context | ||
1474 | lines. In the original file, the hunk was in lines 4 through 7; in the | ||
1475 | new file, it's lines 4 through 8 (because a line has been added). Note | ||
1476 | that the diff didn't need to show any material from the original file | ||
1477 | because nothing was removed; it just showed the range and moved on to | ||
1478 | the second half of the hunk. | ||
1479 | |||
1480 | <p>Here's another context diff, from an actual project of mine: | ||
1481 | |||
1482 | <pre>floss$ cvs -Q diff -c | ||
1483 | Index: cvs2cl.pl | ||
1484 | =================================================================== | ||
1485 | RCS file: /usr/local/cvs/kfogel/code/cvs2cl/cvs2cl.pl,v | ||
1486 | retrieving revision 1.76 | ||
1487 | diff -c -r1.76 cvs2cl.pl | ||
1488 | *** cvs2cl.pl 1999/04/13 22:29:44 1.76 | ||
1489 | --- cvs2cl.pl 1999/04/19 05:41:37 | ||
1490 | *************** | ||
1491 | *** 212,218 **** | ||
1492 | # can contain uppercase and lowercase letters, digits, '-', | ||
1493 | # and '_'. However, it's not our place to enforce that, so | ||
1494 | # we'll allow anything CVS hands us to be a tag: | ||
1495 | ! /^\s([^:]+): ([0-9.]+)$/; | ||
1496 | push (@{$symbolic_names{$2}}, $1); | ||
1497 | } | ||
1498 | } | ||
1499 | -- 212,218 -- | ||
1500 | # can contain uppercase and lowercase letters, digits, '-', | ||
1501 | # and '_'. However, it's not our place to enforce that, so | ||
1502 | # we'll allow anything CVS hands us to be a tag: | ||
1503 | ! /^\s([^:]+): ([\d.]+)$/; | ||
1504 | push (@{$symbolic_names{$2}}, $1); | ||
1505 | } | ||
1506 | } | ||
1507 | </pre> | ||
1508 | |||
1509 | <p>The exclamation point shows that the marked line differs between the old | ||
1510 | and new files. Since there are no "+" or "-" signs, we know that the | ||
1511 | total number of lines in the file has remained the same. | ||
1512 | |||
1513 | <p>Here's one more context diff from the same project, slightly more | ||
1514 | complex this time: | ||
1515 | |||
1516 | <pre>floss$ cvs -Q diff -c | ||
1517 | Index: cvs2cl.pl | ||
1518 | =================================================================== | ||
1519 | RCS file: /usr/local/cvs/kfogel/code/cvs2cl/cvs2cl.pl,v | ||
1520 | retrieving revision 1.76 | ||
1521 | diff -c -r1.76 cvs2cl.pl | ||
1522 | *** cvs2cl.pl 1999/04/13 22:29:44 1.76 | ||
1523 | --- cvs2cl.pl 1999/04/19 05:58:51 | ||
1524 | *************** | ||
1525 | *** 207,217 **** | ||
1526 | } | ||
1527 | else # we're looking at a tag name, so parse & store it | ||
1528 | { | ||
1529 | - # According to the Cederqvist manual, in node "Tags", "Tag | ||
1530 | - # names must start with an uppercase or lowercase letter and | ||
1531 | - # can contain uppercase and lowercase letters, digits, '-', | ||
1532 | - # and '_'. However, it's not our place to enforce that, so | ||
1533 | - # we'll allow anything CVS hands us to be a tag: | ||
1534 | /^\s([^:]+): ([0-9.]+)$/; | ||
1535 | push (@{$symbolic_names{$2}}, $1); | ||
1536 | } | ||
1537 | - 207,212 -- | ||
1538 | *************** | ||
1539 | *** 223,228 **** | ||
1540 | --- 218,225 -- | ||
1541 | if (/^revision (\d\.[0-9.]+)$/) { | ||
1542 | $revision = "$1"; | ||
1543 | } | ||
1544 | + | ||
1545 | + # This line was added, I admit, solely for the sake of a diff example. | ||
1546 | |||
1547 | # If have file name but not time and author, and see date or | ||
1548 | # author, then grab them: | ||
1549 | </pre> | ||
1550 | |||
1551 | <p>This diff has two hunks. In the first, five lines were removed (these | ||
1552 | lines are only shown in the first section of the hunk, and the second | ||
1553 | section's line count shows that it has five fewer lines). An unbroken | ||
1554 | line of asterisks forms the boundary between hunks, and in the second | ||
1555 | hunk we see that two lines have been added: a blank line and a pointless | ||
1556 | comment. Note how the line numbers compensate for the effect of the | ||
1557 | previous hunk. In the original file, the second hunk's range of the | ||
1558 | area was lines 223 through 228; in the new file, because of the deletion | ||
1559 | that took place in the first hunk, the range is in lines 218 through | ||
1560 | 225. | ||
1561 | |||
1562 | <p>Congratulations, you are probably now as expert as you'll ever need to | ||
1563 | be at reading diffs. | ||
1564 | |||
1565 | <p><hr> | ||
1566 | Node:<a name="CVS_And_Implied_Arguments">CVS And Implied Arguments</a>, | ||
1567 | Next:<a rel=next href="#Committing">Committing</a>, | ||
1568 | Previous:<a rel=previous href="#Finding_Out_What_You__And_Others__Did_--_update_And_diff">Finding Out What You (And Others) Did -- update And diff</a>, | ||
1569 | Up:<a rel=up href="#A_Day_With_CVS">A Day With CVS</a> | ||
1570 | <br> | ||
1571 | |||
1572 | <h3>CVS And Implied Arguments</h3> | ||
1573 | |||
1574 | <p>In each of the CVS commands so far, you may have noticed that no files | ||
1575 | were specified on the command line. We ran | ||
1576 | |||
1577 | <pre>floss$ cvs diff | ||
1578 | </pre> | ||
1579 | |||
1580 | <p>instead of | ||
1581 | |||
1582 | <pre>floss$ cvs diff hello.c | ||
1583 | </pre> | ||
1584 | |||
1585 | <p>and | ||
1586 | |||
1587 | <pre>floss$ cvs update | ||
1588 | </pre> | ||
1589 | |||
1590 | <p>instead of | ||
1591 | |||
1592 | <pre>floss$ cvs update hello.c | ||
1593 | </pre> | ||
1594 | |||
1595 | <p>The principle at work here is that if you don't name any files, CVS acts | ||
1596 | on all files for which the command could possibly be appropriate. This | ||
1597 | even includes files in subdirectories beneath the current directory; CVS | ||
1598 | automatically descends from the current directory through every | ||
1599 | subdirectory in the tree. For example, if you modified | ||
1600 | b-subdir/random.c and a-subdir/subsubdir/fish.c, running update may | ||
1601 | result in this: | ||
1602 | |||
1603 | <pre>floss$ cvs update | ||
1604 | cvs update: Updating . | ||
1605 | M hello.c | ||
1606 | cvs update: Updating a-subdir | ||
1607 | cvs update: Updating a-subdir/subsubdir | ||
1608 | M a-subdir/subsubdir/fish.c | ||
1609 | cvs update: Updating b-subdir | ||
1610 | M b-subdir/random.c | ||
1611 | floss$ | ||
1612 | </pre> | ||
1613 | |||
1614 | <p>or better yet: | ||
1615 | |||
1616 | <pre>floss$ cvs -q update | ||
1617 | M hello.c | ||
1618 | M a-subdir/subsubdir/fish.c | ||
1619 | M b-subdir/random.c | ||
1620 | floss$ | ||
1621 | </pre> | ||
1622 | |||
1623 | <p>Note: The -q flag is a less emphatic version of -Q. Had we used -Q, the | ||
1624 | command would have printed out nothing at all, because the modification | ||
1625 | notices are considered nonessential informational messages. Using the | ||
1626 | lowercase -q is less strict; it suppresses the messages we probably | ||
1627 | don't want, while allowing certain, more useful messages to pass | ||
1628 | through. | ||
1629 | |||
1630 | <p>You can also name specific files for the update: | ||
1631 | |||
1632 | <pre>floss$ cvs update hello.c b-subdir/random.c | ||
1633 | M hello.c | ||
1634 | M b-subdir/random.c | ||
1635 | floss$ | ||
1636 | </pre> | ||
1637 | |||
1638 | <p>and CVS will only examine those files, ignoring all others. | ||
1639 | |||
1640 | <p>In truth, it's more common to run update without restricting it to | ||
1641 | certain files. In most situations, you'll want to update the entire | ||
1642 | directory tree at once. Remember, the updates we're doing here only | ||
1643 | show that some files have been locally modified, because nothing has | ||
1644 | changed yet in the repository. When other people are working on the | ||
1645 | project with you, there's always the chance that running update will | ||
1646 | pull some new changes down from the repository and incorporate them into | ||
1647 | your local files. In that case, you may find it slightly more useful to | ||
1648 | name which files you want updated. | ||
1649 | |||
1650 | <p>The same principle can be applied to other CVS commands. For example, | ||
1651 | with diff, you can choose to view the changes one file at a time | ||
1652 | |||
1653 | <pre>floss$ cvs diff -c b-subdir/random.c | ||
1654 | Index: b-subdir/random.c | ||
1655 | =================================================================== | ||
1656 | RCS file: /usr/local/cvs/myproj/b-subdir/random.c,v | ||
1657 | retrieving revision 1.1.1.1 | ||
1658 | diff -c -r1.1.1.1 random.c | ||
1659 | *** b-subdir/random.c 1999/04/18 18:18:22 1.1.1.1 | ||
1660 | --- b-subdir/random.c 1999/04/19 06:09:48 | ||
1661 | *************** | ||
1662 | *** 1 **** | ||
1663 | ! /* A completely empty C file. */ | ||
1664 | --- 1,8 -- | ||
1665 | ! /* Print out a random number. */ | ||
1666 | ! | ||
1667 | ! #include <stdio.h> | ||
1668 | ! | ||
1669 | ! void main () | ||
1670 | ! { | ||
1671 | ! printf ("a random number\n"); | ||
1672 | ! } | ||
1673 | </pre> | ||
1674 | |||
1675 | <p>or see all the changes at once (hang on to your seat, this is going to | ||
1676 | be a big diff): | ||
1677 | |||
1678 | <pre>floss$ cvs -Q diff -c | ||
1679 | Index: hello.c | ||
1680 | =================================================================== | ||
1681 | RCS file: /usr/local/cvs/myproj/hello.c,v | ||
1682 | retrieving revision 1.1.1.1 | ||
1683 | diff -c -r1.1.1.1 hello.c | ||
1684 | *** hello.c 1999/04/18 18:18:22 1.1.1.1 | ||
1685 | --- hello.c 1999/04/19 02:17:07 | ||
1686 | *************** | ||
1687 | *** 4,7 **** | ||
1688 | --- 4,8 -- | ||
1689 | main () | ||
1690 | { | ||
1691 | printf ("Hello, world!\n"); | ||
1692 | + printf ("Goodbye, world!\n"); | ||
1693 | } | ||
1694 | Index: a-subdir/subsubdir/fish.c | ||
1695 | =================================================================== | ||
1696 | RCS file: /usr/local/cvs/myproj/a-subdir/subsubdir/fish.c,v | ||
1697 | retrieving revision 1.1.1.1 | ||
1698 | diff -c -r1.1.1.1 fish.c | ||
1699 | *** a-subdir/subsubdir/fish.c 1999/04/18 18:18:22 1.1.1.1 | ||
1700 | --- a-subdir/subsubdir/fish.c 1999/04/19 06:08:50 | ||
1701 | *************** | ||
1702 | *** 1 **** | ||
1703 | ! /* A completely empty C file. */ | ||
1704 | --- 1,8 -- | ||
1705 | ! #include <stdio.h> | ||
1706 | ! | ||
1707 | ! void main () | ||
1708 | ! { | ||
1709 | ! while (1) { | ||
1710 | ! printf ("fish\n"); | ||
1711 | ! } | ||
1712 | ! } | ||
1713 | Index: b-subdir/random.c | ||
1714 | =================================================================== | ||
1715 | RCS file: /usr/local/cvs/myproj/b-subdir/random.c,v | ||
1716 | retrieving revision 1.1.1.1 | ||
1717 | diff -c -r1.1.1.1 random.c | ||
1718 | *** b-subdir/random.c 1999/04/18 18:18:22 1.1.1.1 | ||
1719 | --- b-subdir/random.c 1999/04/19 06:09:48 | ||
1720 | *************** | ||
1721 | *** 1 **** | ||
1722 | ! /* A completely empty C file. */ | ||
1723 | --- 1,8 -- | ||
1724 | ! /* Print out a random number. */ | ||
1725 | ! | ||
1726 | ! #include <stdio.h> | ||
1727 | ! | ||
1728 | ! void main () | ||
1729 | ! { | ||
1730 | ! printf ("a random number\n"); | ||
1731 | ! } | ||
1732 | </pre> | ||
1733 | |||
1734 | <p>Anyway, as you can see from these diffs, this project is clearly ready | ||
1735 | for prime time. Let's commit the changes to the repository. | ||
1736 | |||
1737 | <p><hr> | ||
1738 | Node:<a name="Committing">Committing</a>, | ||
1739 | Next:<a rel=next href="#Revision_Numbers">Revision Numbers</a>, | ||
1740 | Previous:<a rel=previous href="#CVS_And_Implied_Arguments">CVS And Implied Arguments</a>, | ||
1741 | Up:<a rel=up href="#A_Day_With_CVS">A Day With CVS</a> | ||
1742 | <br> | ||
1743 | |||
1744 | <h3>Committing</h3> | ||
1745 | |||
1746 | <p>The <dfn>commit</dfn> command sends modifications to the repository. If you | ||
1747 | don't name any files, a commit will send all changes to the repository; | ||
1748 | otherwise, you can pass the names of one or more files to be committed | ||
1749 | (other files would be ignored, in that case). | ||
1750 | |||
1751 | <p>Here, we commit one file by name and two by inference: | ||
1752 | |||
1753 | <pre>floss$ cvs commit -m "print goodbye too" hello.c | ||
1754 | Checking in hello.c; | ||
1755 | /usr/local/cvs/myproj/hello.c,v <-- hello.c | ||
1756 | new revision: 1.2; previous revision: 1.1 | ||
1757 | done | ||
1758 | floss$ cvs commit -m "filled out C code" | ||
1759 | cvs commit: Examining . | ||
1760 | cvs commit: Examining a-subdir | ||
1761 | cvs commit: Examining a-subdir/subsubdir | ||
1762 | cvs commit: Examining b-subdir | ||
1763 | Checking in a-subdir/subsubdir/fish.c; | ||
1764 | /usr/local/cvs/myproj/a-subdir/subsubdir/fish.c,v <-- fish.c | ||
1765 | new revision: 1.2; previous revision: 1.1 | ||
1766 | done | ||
1767 | Checking in b-subdir/random.c; | ||
1768 | /usr/local/cvs/myproj/b-subdir/random.c,v <-- random.c | ||
1769 | new revision: 1.2; previous revision: 1.1 | ||
1770 | done | ||
1771 | floss$ | ||
1772 | </pre> | ||
1773 | |||
1774 | <p>Take a moment to read over the output carefully. Most of what it says | ||
1775 | is pretty self-explanatory. One thing you may notice is that revision | ||
1776 | numbers have been incremented (as expected), but the original revisions | ||
1777 | are listed as 1.1 instead of 1.1.1.1 as we saw in the Entries file | ||
1778 | earlier. | ||
1779 | |||
1780 | <p>There is an explanation for this discrepancy, but it's not very | ||
1781 | important. It concerns a special meaning that CVS attaches to revision | ||
1782 | 1.1.1.1. For most purposes, we can just say that files receive a | ||
1783 | revision number of 1.1 when imported, but the number is displayed - for | ||
1784 | reasons known only to CVS - as 1.1.1.1 in the Entries file, until the | ||
1785 | first commit. | ||
1786 | |||
1787 | <p><hr> | ||
1788 | Node:<a name="Revision_Numbers">Revision Numbers</a>, | ||
1789 | Next:<a rel=next href="#Detecting_And_Resolving_Conflicts">Detecting And Resolving Conflicts</a>, | ||
1790 | Previous:<a rel=previous href="#Committing">Committing</a>, | ||
1791 | Up:<a rel=up href="#A_Day_With_CVS">A Day With CVS</a> | ||
1792 | <br> | ||
1793 | |||
1794 | <h3>Revision Numbers</h3> | ||
1795 | |||
1796 | <p>Each file in a project has its own revision number. When a file is | ||
1797 | committed, the last portion of the revision number is incremented by | ||
1798 | one. Thus, at any given time, the various files comprising a project | ||
1799 | may have very different revision numbers. This just means that some | ||
1800 | files have been changed (committed) more often than others. | ||
1801 | |||
1802 | <p>(You may be wondering, what's the point of the part to the left of the | ||
1803 | decimal point, if only the part on the right ever changes? Actually, | ||
1804 | although CVS never automatically increments the number on the left, that | ||
1805 | number can be incremented on request by a user. This is a rarely used | ||
1806 | feature, and we won't cover it in this tour.) | ||
1807 | |||
1808 | <p>In the example project that we've been using, we just committed changes | ||
1809 | to three files. Each of those files is now revision 1.2, but the | ||
1810 | remaining files in the project are still revision 1.1. When you check | ||
1811 | out a project, you get each file at its highest revision so far. Here | ||
1812 | is what qsmith would see if he checked out myproj right now and looked | ||
1813 | at the revision numbers for the top-level directory: | ||
1814 | |||
1815 | <pre>paste$ cvs -q -d :pserver:qsmith@cvs.foobar.com:/usr/local/cvs co myproj | ||
1816 | U myproj/README.txt | ||
1817 | U myproj/hello.c | ||
1818 | U myproj/a-subdir/whatever.c | ||
1819 | U myproj/a-subdir/subsubdir/fish.c | ||
1820 | U myproj/b-subdir/random.c | ||
1821 | paste$ cd myproj/CVS | ||
1822 | paste$ cat Entries | ||
1823 | /README.txt/1.1.1.1/Sun Apr 18 18:18:22 1999// | ||
1824 | /hello.c/1.2/Mon Apr 19 06:35:15 1999// | ||
1825 | D/a-subdir//// | ||
1826 | D/b-subdir//// | ||
1827 | paste$ | ||
1828 | </pre> | ||
1829 | |||
1830 | <p>The file hello.c (among others) is now at revision 1.2, while README.txt | ||
1831 | is still at the initial revision (revision 1.1.1.1, also known as 1.1). | ||
1832 | |||
1833 | <p>If he adds the line | ||
1834 | |||
1835 | <pre>printf ("between hello and goodbye\n"); | ||
1836 | </pre> | ||
1837 | |||
1838 | <p>to hello.c and commit it, the file's revision number will be incremented | ||
1839 | once more: | ||
1840 | |||
1841 | <pre>paste$ cvs ci -m "added new middle line" | ||
1842 | cvs commit: Examining . | ||
1843 | cvs commit: Examining a-subdir | ||
1844 | cvs commit: Examining a-subdir/subsubdir | ||
1845 | cvs commit: Examining b-subdir | ||
1846 | Checking in hello.c; | ||
1847 | /usr/local/cvs/myproj/hello.c,v <-- hello.c | ||
1848 | new revision: 1.3; previous revision: 1.2 | ||
1849 | done | ||
1850 | paste$ | ||
1851 | </pre> | ||
1852 | |||
1853 | <p>Now hello.c is revision 1.3, fish.c and random.c still are revision 1.2, | ||
1854 | and every other file is revision 1.1. | ||
1855 | |||
1856 | <p>Note: that the command was given as cvs ci instead of cvs commit. Most | ||
1857 | CVS commands have short forms, to make typing easier. For checkout, | ||
1858 | update, and commit, the abbreviated versions are co, up, and ci, | ||
1859 | respectively. You can get a list of all of the short forms by running | ||
1860 | the command <code>cvs --help-synonyms</code>. | ||
1861 | |||
1862 | <p>You can usually ignore a file's revision number. In most situations, | ||
1863 | the numbers are just internal bookkeeping that CVS handles | ||
1864 | automatically. However, being able to find and compare revision numbers | ||
1865 | is extremely handy when you have to retrieve (or diff against) an | ||
1866 | earlier copy of a file. | ||
1867 | |||
1868 | <p>Examining the Entries file isn't the only way to discover a revision | ||
1869 | number. You can also use the status command | ||
1870 | |||
1871 | <pre>paste$ cvs status hello.c | ||
1872 | =================================================================== | ||
1873 | File: hello.c Status: Up-to-date | ||
1874 | |||
1875 | Working revision: 1.3 Tue Apr 20 02:34:42 1999 | ||
1876 | Repository revision: 1.3 /usr/local/cvs/myproj/hello.c,v | ||
1877 | Sticky Tag: (none) | ||
1878 | Sticky Date: (none) | ||
1879 | Sticky Options: (none) | ||
1880 | </pre> | ||
1881 | |||
1882 | <p>which, if invoked without any files being named, shows the status of | ||
1883 | every file in the project: | ||
1884 | |||
1885 | <pre>paste$ cvs status | ||
1886 | cvs status: Examining. | ||
1887 | =================================================================== | ||
1888 | File: README.txt Status: Up-to-date | ||
1889 | |||
1890 | Working revision: 1.1.1.1 Sun Apr 18 18:18:22 1999 | ||
1891 | Repository revision: 1.1.1.1 /usr/local/cvs/myproj/README.txt,v | ||
1892 | Sticky Tag: (none) | ||
1893 | Sticky Date: (none) | ||
1894 | Sticky Options: (none) | ||
1895 | |||
1896 | =================================================================== | ||
1897 | File: hello.c Status: Up-to-date | ||
1898 | |||
1899 | Working revision: 1.3 Tue Apr 20 02:34:42 1999 | ||
1900 | Repository revision: 1.3 /usr/local/cvs/myproj/hello.c,v | ||
1901 | Sticky Tag: (none) | ||
1902 | Sticky Date: (none) | ||
1903 | Sticky Options: (none) | ||
1904 | |||
1905 | cvs status: Examining a-subdir | ||
1906 | =================================================================== | ||
1907 | File: whatever.c Status: Up-to-date | ||
1908 | |||
1909 | Working revision: 1.1.1.1 Sun Apr 18 18:18:22 1999 | ||
1910 | Repository revision: 1.1.1.1 /usr/local/cvs/myproj/a-subdir/whatever.c,v | ||
1911 | Sticky Tag: (none) | ||
1912 | Sticky Date: (none) | ||
1913 | Sticky Options: (none) | ||
1914 | |||
1915 | cvs status: Examining a-subdir/subsubdir | ||
1916 | =================================================================== | ||
1917 | File: fish.c Status: Up-to-date | ||
1918 | |||
1919 | Working revision: 1.2 Mon Apr 19 06:35:27 1999 | ||
1920 | Repository revision: 1.2 /usr/local/cvs/myproj/ | ||
1921 | a-subdir/subsubdir/fish.c,v | ||
1922 | Sticky Tag: (none) | ||
1923 | Sticky Date: (none) | ||
1924 | Sticky Options: (none) | ||
1925 | |||
1926 | cvs status: Examining b-subdir | ||
1927 | =================================================================== | ||
1928 | File: random.c Status: Up-to-date | ||
1929 | |||
1930 | Working revision: 1.2 Mon Apr 19 06:35:27 1999 | ||
1931 | Repository revision: 1.2 /usr/local/cvs/myproj/b-subdir/random.c,v | ||
1932 | Sticky Tag: (none) | ||
1933 | Sticky Date: (none) | ||
1934 | Sticky Options: (none) | ||
1935 | |||
1936 | paste$ | ||
1937 | </pre> | ||
1938 | |||
1939 | <p>Just ignore the parts of that output that you don't understand. In | ||
1940 | fact, that's generally good advice with CVS. Often, the one little bit | ||
1941 | of information you're looking for will be accompanied by reams of | ||
1942 | information that you don't care about at all, and maybe don't even | ||
1943 | understand. This situation is normal. Just pick out what you need, and | ||
1944 | don't worry about the rest. | ||
1945 | |||
1946 | <p>In the previous example, the parts we care about are the first three | ||
1947 | lines (not counting the blank line) of each file's status output. The | ||
1948 | first line is the most important; it tells you the file's name, and its | ||
1949 | status in the working copy. All of the files are currently in sync with | ||
1950 | the repository, so they all say <code>Up-to-date</code>. However, if random.c | ||
1951 | has been modified but not committed, it might read like this: | ||
1952 | |||
1953 | <pre>=================================================================== | ||
1954 | File: random.c Status: Locally Modified | ||
1955 | |||
1956 | Working revision: 1.2 Mon Apr 19 06:35:27 1999 | ||
1957 | Repository revision: 1.2 /usr/local/cvs/myproj/b-subdir/random.c,v | ||
1958 | Sticky Tag: (none) | ||
1959 | Sticky Date: (none) | ||
1960 | Sticky Options: (none) | ||
1961 | </pre> | ||
1962 | |||
1963 | <p>The Working revision and Repository revision tell you whether the file | ||
1964 | is out of sync with the repository. Returning to our original working | ||
1965 | copy (jrandom's copy, which hasn't seen the new change to hello.c yet), | ||
1966 | we see: | ||
1967 | |||
1968 | <pre>floss$ cvs status hello.c | ||
1969 | =================================================================== | ||
1970 | File: hello.c Status: Needs Patch | ||
1971 | |||
1972 | Working revision: 1.2 Mon Apr 19 02:17:07 1999 | ||
1973 | Repository revision: 1.3 /usr/local/cvs/myproj/hello.c,v | ||
1974 | Sticky Tag: (none) | ||
1975 | Sticky Date: (none) | ||
1976 | Sticky Options: (none) | ||
1977 | |||
1978 | floss$ | ||
1979 | </pre> | ||
1980 | |||
1981 | <p>This tells us that someone has committed a change to hello.c, bringing | ||
1982 | the repository copy to revision 1.3, but that this working copy is still | ||
1983 | on revision 1.2. The line Status: Needs Patch means that the next update | ||
1984 | will retrieve those changes from the repository and "patch" them into | ||
1985 | the working copy's file. | ||
1986 | |||
1987 | <p>Let's pretend for the moment that we don't know anything about qsmith's | ||
1988 | change to hello.c, so we don't run status or update. Instead, we just | ||
1989 | start editing the file, making a slightly different change at the same | ||
1990 | location. This brings us to our first conflict. | ||
1991 | |||
1992 | <p><hr> | ||
1993 | Node:<a name="Detecting_And_Resolving_Conflicts">Detecting And Resolving Conflicts</a>, | ||
1994 | Next:<a rel=next href="#Finding_Out_Who_Did_What__Browsing_Log_Messages_">Finding Out Who Did What (Browsing Log Messages)</a>, | ||
1995 | Previous:<a rel=previous href="#Revision_Numbers">Revision Numbers</a>, | ||
1996 | Up:<a rel=up href="#A_Day_With_CVS">A Day With CVS</a> | ||
1997 | <br> | ||
1998 | |||
1999 | <h3>Detecting And Resolving Conflicts</h3> | ||
2000 | |||
2001 | <p>Detecting a conflict is easy enough. When you run update, CVS tells | ||
2002 | you, in no uncertain terms, that there's a conflict. But first, let's | ||
2003 | create the conflict. We edit hello.c to insert the line | ||
2004 | |||
2005 | <pre>printf ("this change will conflict\n"); | ||
2006 | </pre> | ||
2007 | |||
2008 | <p>right where qsmith committed this: | ||
2009 | |||
2010 | <pre>printf ("between hello and goodbye\n"); | ||
2011 | </pre> | ||
2012 | |||
2013 | <p>At this point, the status of our copy of hello.c is | ||
2014 | |||
2015 | <pre>floss$ cvs status hello.c | ||
2016 | =================================================================== | ||
2017 | File: hello.c Status: Needs Merge | ||
2018 | |||
2019 | Working revision: 1.2 Mon Apr 19 02:17:07 1999 | ||
2020 | Repository revision: 1.3 /usr/local/cvs/myproj/hello.c,v | ||
2021 | Sticky Tag: (none) | ||
2022 | Sticky Date: (none) | ||
2023 | Sticky Options: (none) | ||
2024 | |||
2025 | floss$ | ||
2026 | </pre> | ||
2027 | |||
2028 | <p>meaning that there are changes both in the repository and the working | ||
2029 | copy, and these changes need to be merged. (CVS isn't aware that the | ||
2030 | changes will conflict, because we haven't run update yet.) When we do | ||
2031 | the update, we see this: | ||
2032 | |||
2033 | <pre>floss$ cvs update hello.c | ||
2034 | RCS file: /usr/local/cvs/myproj/hello.c,v | ||
2035 | retrieving revision 1.2 | ||
2036 | retrieving revision 1.3 | ||
2037 | Merging differences between 1.2 and 1.3 into hello.c | ||
2038 | rcsmerge: warning: conflicts during merge | ||
2039 | cvs update: conflicts found in hello.c | ||
2040 | C hello.c | ||
2041 | floss$ | ||
2042 | </pre> | ||
2043 | |||
2044 | <p>The last line of output is the giveaway. The C in the left margin next | ||
2045 | to the filename indicates that changes have been merged, but that they | ||
2046 | conflict. The contents of hello.c now shows both changes: | ||
2047 | |||
2048 | <pre>#include <stdio.h> | ||
2049 | |||
2050 | void | ||
2051 | main () | ||
2052 | { | ||
2053 | printf ("Hello, world!\n"); | ||
2054 | <<<<<<< hello.c | ||
2055 | printf ("this change will conflict\n"); | ||
2056 | ======= | ||
2057 | printf ("between hello and goodbye\n"); | ||
2058 | >>>>>>> 1.3 | ||
2059 | printf ("Goodbye, world!\n"); | ||
2060 | } | ||
2061 | </pre> | ||
2062 | |||
2063 | <p>Conflicts are always shown delimited by conflict markers, in the | ||
2064 | following format: | ||
2065 | |||
2066 | <pre><<<<<<< (filename) | ||
2067 | the uncommitted changes in the working copy | ||
2068 | blah blah blah | ||
2069 | ======= | ||
2070 | the new changes that came from the repository | ||
2071 | blah blah blah | ||
2072 | and so on | ||
2073 | >>>>>>> (latest revision number in the repository) | ||
2074 | </pre> | ||
2075 | |||
2076 | <p>The Entries file also shows that the file is in a halfway state at the | ||
2077 | moment: | ||
2078 | |||
2079 | <pre>floss$ cat CVS/Entries | ||
2080 | /README.txt/1.1.1.1/Sun Apr 18 18:18:22 1999// | ||
2081 | D/a-subdir//// | ||
2082 | D/b-subdir//// | ||
2083 | /hello.c/1.3/Result of merge+Tue Apr 20 03:59:09 1999// | ||
2084 | floss$ | ||
2085 | </pre> | ||
2086 | |||
2087 | <p>The way to resolve the conflict is to edit the file so that it contains | ||
2088 | whatever text is appropriate, removing the conflict markers in the | ||
2089 | process, and then to commit. This doesn't necessarily mean choosing one | ||
2090 | change over another; you could decide neither change is sufficient and | ||
2091 | rewrite the conflicting section (or indeed the whole file) completely. | ||
2092 | In this case, we'll adjust in favor of the first change, but with | ||
2093 | capitalization and punctuation slightly different from qsmith's: | ||
2094 | |||
2095 | <pre>floss$ emacs hello.c | ||
2096 | (make the edits...) | ||
2097 | floss$ cat hello.c | ||
2098 | #include <stdio.h> | ||
2099 | |||
2100 | void | ||
2101 | main () | ||
2102 | { | ||
2103 | printf ("Hello, world!\n"); | ||
2104 | printf ("BETWEEN HELLO AND GOODBYE.\n"); | ||
2105 | printf ("Goodbye, world!\n"); | ||
2106 | } | ||
2107 | floss$ cvs ci -m "adjusted middle line" | ||
2108 | cvs commit: Examining . | ||
2109 | cvs commit: Examining a-subdir | ||
2110 | cvs commit: Examining a-subdir/subsubdir | ||
2111 | cvs commit: Examining b-subdir | ||
2112 | Checking in hello.c; | ||
2113 | /usr/local/cvs/myproj/hello.c,v <- hello.c | ||
2114 | new revision: 1.4; previous revision: 1.3 | ||
2115 | done | ||
2116 | floss$ | ||
2117 | </pre> | ||
2118 | |||
2119 | <p><hr> | ||
2120 | Node:<a name="Finding_Out_Who_Did_What__Browsing_Log_Messages_">Finding Out Who Did What (Browsing Log Messages)</a>, | ||
2121 | Next:<a rel=next href="#Examining_And_Reverting_Changes">Examining And Reverting Changes</a>, | ||
2122 | Previous:<a rel=previous href="#Detecting_And_Resolving_Conflicts">Detecting And Resolving Conflicts</a>, | ||
2123 | Up:<a rel=up href="#A_Day_With_CVS">A Day With CVS</a> | ||
2124 | <br> | ||
2125 | |||
2126 | <h3>Finding Out Who Did What (Browsing Log Messages)</h3> | ||
2127 | |||
2128 | <p>By now, the project has undergone several changes. If you're trying to | ||
2129 | get an overview of what has happened so far, you don't necessarily want | ||
2130 | to examine every diff in detail. Browsing the log messages would be | ||
2131 | ideal, and you can accomplish this with the log command: | ||
2132 | |||
2133 | <pre>floss$ cvs log | ||
2134 | (pages upon pages of output omitted) | ||
2135 | </pre> | ||
2136 | |||
2137 | <p>The log output tends to be a bit verbose. Let's look at the log | ||
2138 | messages for just one file: | ||
2139 | |||
2140 | <pre>floss$ cvs log hello.c | ||
2141 | RCS file: /usr/local/cvs/myproj/hello.c,v | ||
2142 | Working file: hello.c | ||
2143 | head: 1.4 | ||
2144 | branch: | ||
2145 | locks: strict | ||
2146 | access list: | ||
2147 | symbolic names: | ||
2148 | start: 1.1.1.1 | ||
2149 | jrandom: 1.1.1 | ||
2150 | keyword substitution: kv | ||
2151 | total revisions: 5; selected revisions: 5 | ||
2152 | description: | ||
2153 | -------------- | ||
2154 | revision 1.4 | ||
2155 | date: 1999/04/20 04:14:37; author: jrandom; state: Exp; lines: +1 -1 | ||
2156 | adjusted middle line | ||
2157 | -------------- | ||
2158 | revision 1.3 | ||
2159 | date: 1999/04/20 02:30:05; author: qsmith; state: Exp; lines: +1 -0 | ||
2160 | added new middle line | ||
2161 | -------------- | ||
2162 | revision 1.2 | ||
2163 | date: 1999/04/19 06:35:15; author: jrandom; state: Exp; lines: +1 -0 | ||
2164 | print goodbye too | ||
2165 | -------------- | ||
2166 | revision 1.1 | ||
2167 | date: 1999/04/18 18:18:22; author: jrandom; state: Exp; | ||
2168 | branches: 1.1.1; | ||
2169 | Initial revision | ||
2170 | -------------- | ||
2171 | revision 1.1.1.1 | ||
2172 | date: 1999/04/18 18:18:22; author: jrandom; state: Exp; lines: +0 -0 | ||
2173 | initial import into CVS | ||
2174 | ========================================================================= | ||
2175 | floss$ | ||
2176 | </pre> | ||
2177 | |||
2178 | <p>As usual, there's a lot of information at the top that you can just | ||
2179 | ignore. The good stuff comes after each line of dashes, in a format that | ||
2180 | is self-explanatory. | ||
2181 | |||
2182 | <p>When many files are sent in the same commit, they all share the same log | ||
2183 | message; a fact that can be useful in tracing changes. For example, | ||
2184 | remember back when we committed fish.c and random.c simultaneously? It | ||
2185 | was done like this: | ||
2186 | |||
2187 | <pre>floss$ cvs commit -m "filled out C code" | ||
2188 | Checking in a-subdir/subsubdir/fish.c; | ||
2189 | /usr/local/cvs/myproj/a-subdir/subsubdir/fish.c,v <- fish.c | ||
2190 | new revision: 1.2; previous revision: 1.1 | ||
2191 | done | ||
2192 | Checking in b-subdir/random.c; | ||
2193 | /usr/local/cvs/myproj/b-subdir/random.c,v <- random.c | ||
2194 | new revision: 1.2; previous revision: 1.1 | ||
2195 | done | ||
2196 | floss$ | ||
2197 | </pre> | ||
2198 | |||
2199 | <p>The effect of this was to commit both files with the same log message: | ||
2200 | "Filled out C code." (As it happened, both files started at revision | ||
2201 | 1.1 and went to 1.2, but that's just a coincidence. If random.c had | ||
2202 | been at revision 1.29, it would have moved to 1.30 with this commit, and | ||
2203 | its revision 1.30 would have had the same log message as fish.c's | ||
2204 | revision 1.2.) | ||
2205 | |||
2206 | <p>When you run cvs log on them, you'll see the shared message: | ||
2207 | |||
2208 | <pre>floss$ cvs log a-subdir/subsubdir/fish.c b-subdir/random.c | ||
2209 | |||
2210 | RCS file: /usr/local/cvs/myproj/a-subdir/subsubdir/fish.c,v | ||
2211 | Working file: a-subdir/subsubdir/fish.c | ||
2212 | head: 1.2 | ||
2213 | branch: | ||
2214 | locks: strict | ||
2215 | access list: | ||
2216 | symbolic names: | ||
2217 | start: 1.1.1.1 | ||
2218 | jrandom: 1.1.1 | ||
2219 | keyword substitution: kv | ||
2220 | total revisions: 3; selected revisions: 3 | ||
2221 | description: | ||
2222 | -------------- | ||
2223 | revision 1.2 | ||
2224 | date: 1999/04/19 06:35:27; author: jrandom; state: Exp; lines: +8 -1 | ||
2225 | filled out C code | ||
2226 | -------------- | ||
2227 | revision 1.1 | ||
2228 | date: 1999/04/18 18:18:22; author: jrandom; state: Exp; | ||
2229 | branches: 1.1.1; | ||
2230 | Initial revision | ||
2231 | -------------- | ||
2232 | revision 1.1.1.1 | ||
2233 | date: 1999/04/18 18:18:22; author: jrandom; state: Exp; lines: +0 -0 | ||
2234 | initial import into CVS | ||
2235 | ========================================================================= | ||
2236 | RCS file: /usr/local/cvs/myproj/b-subdir/random.c,v | ||
2237 | Working file: b-subdir/random.c | ||
2238 | head: 1.2 | ||
2239 | branch: | ||
2240 | locks: strict | ||
2241 | access list: | ||
2242 | symbolic names: | ||
2243 | start: 1.1.1.1 | ||
2244 | jrandom: 1.1.1 | ||
2245 | keyword substitution: kv | ||
2246 | total revisions: 3; selected revisions: 3 | ||
2247 | description: | ||
2248 | -------------- | ||
2249 | revision 1.2 | ||
2250 | date: 1999/04/19 06:35:27; author: jrandom; state: Exp; lines: +8 -1 | ||
2251 | filled out C code | ||
2252 | -------------- | ||
2253 | revision 1.1 | ||
2254 | date: 1999/04/18 18:18:22; author: jrandom; state: Exp; | ||
2255 | branches: 1.1.1; | ||
2256 | Initial revision | ||
2257 | -------------- | ||
2258 | revision 1.1.1.1 | ||
2259 | date: 1999/04/18 18:18:22; author: jrandom; state: Exp; lines: +0 -0 | ||
2260 | initial import into CVS | ||
2261 | ========================================================================= | ||
2262 | floss$ | ||
2263 | </pre> | ||
2264 | |||
2265 | <p>From this output, you'll know that the two revisions were part of the | ||
2266 | same commit (the fact that the timestamps on the two revisions are the | ||
2267 | same, or very close, is further evidence). | ||
2268 | |||
2269 | <p>Browsing log messages is a good way to get a quick overview of what's | ||
2270 | been going on in a project or to find out what happened to a specific | ||
2271 | file at a certain time. There are also free tools available to convert | ||
2272 | raw cvs log output to more concise and readable formats (such as GNU | ||
2273 | ChangeLog style); we won't cover those tools in this tour, but they'll | ||
2274 | be introduced in <a href="#Third-Party_Tools">Third-Party Tools</a>. | ||
2275 | |||
2276 | <p><hr> | ||
2277 | Node:<a name="Examining_And_Reverting_Changes">Examining And Reverting Changes</a>, | ||
2278 | Next:<a rel=next href="#The_Slow_Method_Of_Reverting">The Slow Method Of Reverting</a>, | ||
2279 | Previous:<a rel=previous href="#Finding_Out_Who_Did_What__Browsing_Log_Messages_">Finding Out Who Did What (Browsing Log Messages)</a>, | ||
2280 | Up:<a rel=up href="#A_Day_With_CVS">A Day With CVS</a> | ||
2281 | <br> | ||
2282 | |||
2283 | <h3>Examining And Reverting Changes</h3> | ||
2284 | |||
2285 | <p>Suppose that, in the course of browsing the logs, qsmith sees that | ||
2286 | jrandom made the most recent change to hello.c: | ||
2287 | |||
2288 | <pre>revision 1.4 | ||
2289 | date: 1999/04/20 04:14:37; author: jrandom; state: Exp; lines: +1 -1 | ||
2290 | adjusted middle line | ||
2291 | </pre> | ||
2292 | |||
2293 | <p>and wonders what jrandom did? In formal terms, the question that qsmith | ||
2294 | is asking is, "What's the difference between my revision (1.3) of | ||
2295 | hello.c, and jrandom's revision right after it (1.4)?" The way to find | ||
2296 | out is with the diff command, but this time by comparing two past | ||
2297 | revisions using the -r command option to specify both of them: | ||
2298 | |||
2299 | <pre>paste$ cvs diff -c -r 1.3 -r 1.4 hello.c | ||
2300 | Index: hello.c | ||
2301 | =========================================================== | ||
2302 | RCS file: /usr/local/cvs/myproj/hello.c,v | ||
2303 | retrieving revision 1.3 | ||
2304 | retrieving revision 1.4 | ||
2305 | diff -c -r1.3 -r1.4 | ||
2306 | *** hello.c 1999/04/20 02:30:05 1.3 | ||
2307 | --- hello.c 1999/04/20 04:14:37 1.4 | ||
2308 | *************** | ||
2309 | *** 4,9 **** | ||
2310 | main () | ||
2311 | { | ||
2312 | printf ("Hello, world!\n"); | ||
2313 | ! printf ("between hello and goodbye\n"); | ||
2314 | printf ("Goodbye, world!\n"); | ||
2315 | } | ||
2316 | --- 4,9 -- | ||
2317 | main () | ||
2318 | { | ||
2319 | printf ("Hello, world!\n"); | ||
2320 | ! printf ("BETWEEN HELLO AND GOODBYE.\n"); | ||
2321 | printf ("Goodbye, world!\n"); | ||
2322 | } | ||
2323 | paste$ | ||
2324 | </pre> | ||
2325 | |||
2326 | <p>The change is pretty clear, when viewed this way. Because the revision | ||
2327 | numbers are given in chronological order (usually a good idea), the diff | ||
2328 | shows them in order. If only one revision number is given, CVS uses the | ||
2329 | revision of the current working copy for the other. | ||
2330 | |||
2331 | <p>When qsmith sees this change, he instantly decides he likes his way | ||
2332 | better and resolves to "undo"-that is, to step back by one revision. | ||
2333 | |||
2334 | <p>However, this doesn't mean that he wants to lose his revision 1.4. | ||
2335 | Although, in an absolute technical sense, it's probably possible to | ||
2336 | achieve that effect in CVS, there's almost never any reason to do so. | ||
2337 | It's much preferable to keep revision 1.4 in the history and make a new | ||
2338 | revision 1.5 that looks exactly like 1.3. That way the undo event | ||
2339 | itself is part of the file's history. | ||
2340 | |||
2341 | <p>The only question is, how can you retrieve the contents of revision 1.3 | ||
2342 | and put them into 1.5? | ||
2343 | |||
2344 | <p>In this particular case, because the change is a very simple one, qsmith | ||
2345 | can probably just edit the file by hand to mirror revision 1.3 and then | ||
2346 | commit. However, if the changes are more complex (as they usually are | ||
2347 | in a real-life project), trying to re-create the old revision manually | ||
2348 | will be hopelessly error-prone. Therefore, we'll have qsmith use CVS to | ||
2349 | retrieve and recommit the older revision's contents. | ||
2350 | |||
2351 | <p>There are two equally good ways to do this: the slow, plodding way and | ||
2352 | the fast, fancy way. We'll examine the slow, plodding way first. | ||
2353 | |||
2354 | <p><hr> | ||
2355 | Node:<a name="The_Slow_Method_Of_Reverting">The Slow Method Of Reverting</a>, | ||
2356 | Next:<a rel=next href="#The_Fast_Method_Of_Reverting">The Fast Method Of Reverting</a>, | ||
2357 | Previous:<a rel=previous href="#Examining_And_Reverting_Changes">Examining And Reverting Changes</a>, | ||
2358 | Up:<a rel=up href="#A_Day_With_CVS">A Day With CVS</a> | ||
2359 | <br> | ||
2360 | |||
2361 | <h3>The Slow Method Of Reverting</h3> | ||
2362 | |||
2363 | <p>This method involves passing the -p flag to update, in conjunction with | ||
2364 | -r. The -p option sends the contents of the named revision to standard | ||
2365 | output. By itself, this isn't terribly helpful; the contents of the | ||
2366 | file fly by on the display, leaving the working copy unchanged. | ||
2367 | However, by redirecting the standard output into the file, the file will | ||
2368 | now hold the contents of the older revision. It's just as though the | ||
2369 | file had been hand-edited into that state. | ||
2370 | |||
2371 | <p>First, though, qsmith needs to get up to date with respect to the | ||
2372 | repository: | ||
2373 | |||
2374 | <pre>paste$ cvs update | ||
2375 | cvs update: Updating . | ||
2376 | U hello.c | ||
2377 | cvs update: Updating a-subdir | ||
2378 | cvs update: Updating a-subdir/subsubdir | ||
2379 | cvs update: Updating b-subdir | ||
2380 | paste$ cat hello.c | ||
2381 | #include <stdio.h> | ||
2382 | |||
2383 | void | ||
2384 | main () | ||
2385 | { | ||
2386 | printf ("Hello, world!\n"); | ||
2387 | printf ("BETWEEN HELLO AND GOODBYE.\n"); | ||
2388 | printf ("Goodbye, world!\n"); | ||
2389 | } | ||
2390 | paste$ | ||
2391 | </pre> | ||
2392 | |||
2393 | <p>Next, he runs update -p to make sure that the revision 1.3 is the one he | ||
2394 | wants: | ||
2395 | |||
2396 | <pre>paste$ cvs update -p -r 1.3 hello.c | ||
2397 | =================================================================== | ||
2398 | Checking out hello.c | ||
2399 | RCS: /usr/local/cvs/myproj/hello.c,v | ||
2400 | VERS: 1.3 | ||
2401 | *************** | ||
2402 | #include <stdio.h> | ||
2403 | |||
2404 | void | ||
2405 | main () | ||
2406 | { | ||
2407 | printf ("Hello, world!\n"); | ||
2408 | printf ("between hello and goodbye\n"); | ||
2409 | printf ("Goodbye, world!\n"); | ||
2410 | } | ||
2411 | </pre> | ||
2412 | |||
2413 | <p>Oops, there are a few lines of cruft at the beginning. They aren't | ||
2414 | actually being sent to standard output, but rather to standard error, so | ||
2415 | they're harmless. Nevertheless, they make reading the output more | ||
2416 | difficult and can be suppressed with -Q: | ||
2417 | |||
2418 | <pre>paste$ cvs -Q update -p -r 1.3 hello.c | ||
2419 | #include <stdio.h> | ||
2420 | |||
2421 | void | ||
2422 | main () | ||
2423 | { | ||
2424 | printf ("Hello, world!\n"); | ||
2425 | printf ("between hello and goodbye\n"); | ||
2426 | printf ("Goodbye, world!\n"); | ||
2427 | } | ||
2428 | paste$ | ||
2429 | </pre> | ||
2430 | |||
2431 | <p>There - that's exactly what qsmith was hoping to retrieve. The next | ||
2432 | step is to put that content into the working copy's file, using a Unix | ||
2433 | redirect (that's what the ">" does): | ||
2434 | |||
2435 | <pre>paste$ cvs -Q update -p -r 1.3 hello.c > hello.c | ||
2436 | paste$ cvs update | ||
2437 | cvs update: Updating . | ||
2438 | M hello.c | ||
2439 | cvs update: Updating a-subdir | ||
2440 | cvs update: Updating a-subdir/subsubdir | ||
2441 | cvs update: Updating b-subdir | ||
2442 | paste$ | ||
2443 | </pre> | ||
2444 | |||
2445 | <p>Now when update is run, the file is listed as modified, which makes | ||
2446 | sense because its contents have changed. Specifically, it has the same | ||
2447 | content as the old revision 1.3 (not that CVS is aware of its being | ||
2448 | identical to a previous revision - it just knows the file has been | ||
2449 | modified). If qsmith wants to make extra sure, he can do a diff to | ||
2450 | check: | ||
2451 | |||
2452 | <pre>paste$ cvs -Q diff -c | ||
2453 | Index: hello.c | ||
2454 | =================================================================== | ||
2455 | RCS file: /usr/local/cvs/myproj/hello.c,v | ||
2456 | retrieving revision 1.4 | ||
2457 | diff -c -r1.4 hello.c | ||
2458 | *** hello.c 1999/04/20 04:14:37 1.4 | ||
2459 | --- hello.c 1999/04/20 06:02:25 | ||
2460 | *************** | ||
2461 | *** 4,9 **** | ||
2462 | main () | ||
2463 | { | ||
2464 | printf ("Hello, world!\n"); | ||
2465 | ! printf ("BETWEEN HELLO AND GOODBYE.\n"); | ||
2466 | printf ("Goodbye, world!\n"); | ||
2467 | } | ||
2468 | --- 4,9 -- | ||
2469 | main () | ||
2470 | { | ||
2471 | printf ("Hello, world!\n"); | ||
2472 | ! printf ("between hello and goodbye\n"); | ||
2473 | printf ("Goodbye, world!\n"); | ||
2474 | } | ||
2475 | paste$ | ||
2476 | </pre> | ||
2477 | |||
2478 | <p>Yes, that's exactly what he wanted: a pure reversion - in fact, it is | ||
2479 | the reverse of the diff he previously obtained. Satisfied, he commits: | ||
2480 | |||
2481 | <pre>paste$ cvs ci -m "reverted to 1.3 code" | ||
2482 | cvs commit: Examining . | ||
2483 | cvs commit: Examining a-subdir | ||
2484 | cvs commit: Examining a-subdir/subsubdir | ||
2485 | cvs commit: Examining b-subdir | ||
2486 | Checking in hello.c; | ||
2487 | /usr/local/cvs/myproj/hello.c,v <- hello.c | ||
2488 | new revision: 1.5; previous revision: 1.4 | ||
2489 | done | ||
2490 | paste$ | ||
2491 | </pre> | ||
2492 | |||
2493 | <p><hr> | ||
2494 | Node:<a name="The_Fast_Method_Of_Reverting">The Fast Method Of Reverting</a>, | ||
2495 | Previous:<a rel=previous href="#The_Slow_Method_Of_Reverting">The Slow Method Of Reverting</a>, | ||
2496 | Up:<a rel=up href="#A_Day_With_CVS">A Day With CVS</a> | ||
2497 | <br> | ||
2498 | |||
2499 | <h3>The Fast Method Of Reverting</h3> | ||
2500 | |||
2501 | <p>The fast, fancy way of reverting is to use the -j (for "join") flag to | ||
2502 | the update command. This flag is like -r in that it takes a revision | ||
2503 | number, and you can use up to two -j's at once. CVS calculates the | ||
2504 | difference between the two named revisions and applies that difference | ||
2505 | as a patch to the file in question (so the order in which you give the | ||
2506 | revisions is important). | ||
2507 | |||
2508 | <p>Thus, assuming qsmith's copy is up to date, he can just do this: | ||
2509 | |||
2510 | <pre>paste$ cvs update -j 1.4 -j 1.3 hello.c | ||
2511 | RCS file: /usr/local/cvs/myproj/hello.c,v | ||
2512 | retrieving revision 1.4 | ||
2513 | retrieving revision 1.3 | ||
2514 | Merging differences between 1.4 and 1.3 into hello.c | ||
2515 | paste$ cvs update | ||
2516 | cvs update: Updating . | ||
2517 | M hello.c | ||
2518 | cvs update: Updating a-subdir | ||
2519 | cvs update: Updating a-subdir/subsubdir | ||
2520 | cvs update: Updating b-subdir | ||
2521 | paste$ cvs ci -m "reverted to 1.3 code" hello.c | ||
2522 | Checking in hello.c; | ||
2523 | /usr/local/cvs/myproj/hello.c,v <-- hello.c | ||
2524 | new revision: 1.5; previous revision: 1.4 | ||
2525 | done | ||
2526 | paste$ | ||
2527 | </pre> | ||
2528 | |||
2529 | <p>When you only need to revert one file, there's not really much | ||
2530 | difference between the plodding and fast methods. Later in the book, | ||
2531 | you'll see how the fast method is much better for reverting multiple | ||
2532 | files at once. In the meantime, use whichever way you're more | ||
2533 | comfortable with. | ||
2534 | |||
2535 | <h2>Reverting Is Not A Substitute For Communication</h2> | ||
2536 | |||
2537 | <p>In all likelihood, what qsmith did in our example was quite rude. When | ||
2538 | you're working on a real project with other people and you think that | ||
2539 | someone has committed a bad change, the first thing you should do is | ||
2540 | talk to him or her about it. Maybe there's a good reason for the change, | ||
2541 | or maybe he or she just didn't think things through. Either way, there's | ||
2542 | no reason to rush and revert. A full record of everything that happens | ||
2543 | is stored permanently in CVS, so you can always revert to a previous | ||
2544 | revision after consulting with whoever made the changes. | ||
2545 | |||
2546 | <p>If you're a project maintainer facing a deadline or you feel you have | ||
2547 | the right and the need to revert the change unconditionally, then do so | ||
2548 | - but follow it immediately with an email to the author whose change | ||
2549 | was reverted, explaining why you did it and what needs to be fixed to | ||
2550 | recommit the change. | ||
2551 | |||
2552 | <p><hr> | ||
2553 | Node:<a name="Other_Useful_CVS_Commands">Other Useful CVS Commands</a>, | ||
2554 | Next:<a rel=next href="#Branches">Branches</a>, | ||
2555 | Previous:<a rel=previous href="#A_Day_With_CVS">A Day With CVS</a>, | ||
2556 | Up:<a rel=up href="#An_Overview_of_CVS">An Overview of CVS</a> | ||
2557 | <br> | ||
2558 | |||
2559 | <h2>Other Useful CVS Commands</h2> | ||
2560 | |||
2561 | <p>At this point, you should be pretty comfortable with basic CVS usage. | ||
2562 | I'll abandon the tour narrative and introduce a few more useful commands | ||
2563 | in summarized form. | ||
2564 | |||
2565 | <ul> | ||
2566 | <li><a href="#Adding_Files">Adding Files</a>: | ||
2567 | <li><a href="#Adding_Directories">Adding Directories</a>: | ||
2568 | <li><a href="#CVS_And_Binary_Files">CVS And Binary Files</a>: | ||
2569 | <li><a href="#Removing_Files">Removing Files</a>: | ||
2570 | <li><a href="#Removing_Directories">Removing Directories</a>: | ||
2571 | <li><a href="#Renaming_Files_And_Directories">Renaming Files And Directories</a>: | ||
2572 | <li><a href="#Avoiding_Option_Fatigue">Avoiding Option Fatigue</a>: | ||
2573 | <li><a href="#Getting_Snapshots__Dates_And_Tagging_">Getting Snapshots (Dates And Tagging)</a>: | ||
2574 | <li><a href="#Acceptable_Date_Formats">Acceptable Date Formats</a>: | ||
2575 | <li><a href="#Marking_A_Moment_In_Time__Tags_">Marking A Moment In Time (Tags)</a>: | ||
2576 | </ul> | ||
2577 | |||
2578 | <p><hr> | ||
2579 | Node:<a name="Adding_Files">Adding Files</a>, | ||
2580 | Next:<a rel=next href="#Adding_Directories">Adding Directories</a>, | ||
2581 | Up:<a rel=up href="#Other_Useful_CVS_Commands">Other Useful CVS Commands</a> | ||
2582 | <br> | ||
2583 | |||
2584 | <h3>Adding Files</h3> | ||
2585 | |||
2586 | <p>Adding a file is a two-step process: First you run the add command on | ||
2587 | it, then commit. The file won't actually appear in the repository until | ||
2588 | commit is run: | ||
2589 | |||
2590 | <pre>floss$ cvs add newfile.c | ||
2591 | cvs add: scheduling file 'newfile.c' for addition | ||
2592 | cvs add: use 'cvs commit' to add this file permanently | ||
2593 | floss$ cvs ci -m "added newfile.c" newfile.c | ||
2594 | RCS file: /usr/local/cvs/myproj/newfile.c,v | ||
2595 | done | ||
2596 | Checking in newfile.c; | ||
2597 | /usr/local/cvs/myproj/newfile.c,v <- newfile.c | ||
2598 | initial revision: 1.1 | ||
2599 | done | ||
2600 | floss$ | ||
2601 | </pre> | ||
2602 | |||
2603 | <p><hr> | ||
2604 | Node:<a name="Adding_Directories">Adding Directories</a>, | ||
2605 | Next:<a rel=next href="#CVS_And_Binary_Files">CVS And Binary Files</a>, | ||
2606 | Previous:<a rel=previous href="#Adding_Files">Adding Files</a>, | ||
2607 | Up:<a rel=up href="#Other_Useful_CVS_Commands">Other Useful CVS Commands</a> | ||
2608 | <br> | ||
2609 | |||
2610 | <h3>Adding Directories</h3> | ||
2611 | |||
2612 | <p>Unlike adding a file, adding a new directory is done in one step; | ||
2613 | there's no need to do a commit afterwards: | ||
2614 | |||
2615 | <pre>floss$ mkdir c-subdir | ||
2616 | floss$ cvs add c-subdir | ||
2617 | Directory /usr/local/cvs/myproj/c-subdir added to the repository | ||
2618 | floss$ | ||
2619 | </pre> | ||
2620 | |||
2621 | <p>If you look inside the new directory in the working copy, you'll see | ||
2622 | that a CVS subdirectory was created automatically by add: | ||
2623 | |||
2624 | <pre>floss$ ls c-subdir | ||
2625 | CVS/ | ||
2626 | floss$ ls c-subdir/CVS | ||
2627 | Entries Repository Root | ||
2628 | floss$ | ||
2629 | </pre> | ||
2630 | |||
2631 | <p>Now you can add files (or new directories) inside it, as with any other | ||
2632 | working copy directory. | ||
2633 | |||
2634 | <p><hr> | ||
2635 | Node:<a name="CVS_And_Binary_Files">CVS And Binary Files</a>, | ||
2636 | Next:<a rel=next href="#Removing_Files">Removing Files</a>, | ||
2637 | Previous:<a rel=previous href="#Adding_Directories">Adding Directories</a>, | ||
2638 | Up:<a rel=up href="#Other_Useful_CVS_Commands">Other Useful CVS Commands</a> | ||
2639 | <br> | ||
2640 | |||
2641 | <h3>CVS And Binary Files</h3> | ||
2642 | |||
2643 | <p>Until now, I've left unsaid the dirty little secret of CVS, which is | ||
2644 | that it doesn't handle binary files very well (well, there are other | ||
2645 | dirty little secrets, but this definitely counts as one of the | ||
2646 | dirtiest). It's not that CVS doesn't handle binaries at all; it does, | ||
2647 | just not with any great panache. | ||
2648 | |||
2649 | <p>All the files we've been working with until now have been plain text | ||
2650 | files. CVS has some special tricks for text files. For example, when | ||
2651 | it's working between a Unix repository and a Windows or Macintosh | ||
2652 | working copy, it converts file line endings appropriately for each | ||
2653 | platform. For example, Unix convention is to use a linefeed (LF) only, | ||
2654 | whereas Windows expects a carriage return/linefeed (CRLF) sequence at | ||
2655 | the end of each line. Thus, the files in a working copy on a Windows | ||
2656 | machine will have CRLF endings, but a working copy of the same project | ||
2657 | on a Unix machine will have LF endings (the repository itself is always | ||
2658 | stored in LF format). | ||
2659 | |||
2660 | <p>Another trick is that CVS detects special strings, known as RCS keyword | ||
2661 | strings, in text files and replaces them with revision information and | ||
2662 | other useful things. For example, if your file contains this string | ||
2663 | |||
2664 | <pre>$Revision$ | ||
2665 | </pre> | ||
2666 | |||
2667 | <p>CVS will expand on each commit to include the revision number. For | ||
2668 | example, it may get expanded to | ||
2669 | |||
2670 | <pre>$Revision$ | ||
2671 | </pre> | ||
2672 | |||
2673 | <p>CVS will keep that string up to date as the file is developed. (The | ||
2674 | various keyword strings are documented in <a href="#Advanced_CVS">Advanced CVS</a> and | ||
2675 | <a href="#Third-Party_Tools">Third-Party Tools</a>.) | ||
2676 | |||
2677 | <p>This string expansion is a very useful feature in text files, as it | ||
2678 | allows you to see the revision number or other information about a file | ||
2679 | while you're editing it. But what if the file is a JPG image? Or a | ||
2680 | compiled executable program? In those kinds of files, CVS could do some | ||
2681 | serious damage if it blundered around expanding any keyword string that | ||
2682 | it encountered. In a binary, such strings may even appear by | ||
2683 | coincidence. | ||
2684 | |||
2685 | <p>Therefore, when you add a binary file, you have to tell CVS to turn off | ||
2686 | both keyword expansion and line-ending conversion. To do so, use -kb: | ||
2687 | |||
2688 | <pre>floss$ cvs add -kb filename | ||
2689 | floss$ cvs ci -m "added blah" filename | ||
2690 | (etc) | ||
2691 | </pre> | ||
2692 | |||
2693 | <p>Also, in some cases (such as text files that are likely to contain | ||
2694 | spurious keyword strings), you may wish to disable just the keyword | ||
2695 | expansion. That's done with -ko: | ||
2696 | |||
2697 | <pre>floss$ cvs add -ko filename | ||
2698 | floss$ cvs ci -m "added blah" filename | ||
2699 | (etc) | ||
2700 | </pre> | ||
2701 | |||
2702 | <p>(In fact, this chapter is one such document, because of the | ||
2703 | <code>$Revision$</code> example shown here.) | ||
2704 | |||
2705 | <p>Note that you can't meaningfully run <code>cvs diff</code> on two | ||
2706 | revisions of a binary file. Diff uses a text-based algorithm that can | ||
2707 | only report whether two binary files differ, but not how they differ. | ||
2708 | Future versions of CVS may provide a way to diff binary files. | ||
2709 | |||
2710 | <p><hr> | ||
2711 | Node:<a name="Removing_Files">Removing Files</a>, | ||
2712 | Next:<a rel=next href="#Removing_Directories">Removing Directories</a>, | ||
2713 | Previous:<a rel=previous href="#CVS_And_Binary_Files">CVS And Binary Files</a>, | ||
2714 | Up:<a rel=up href="#Other_Useful_CVS_Commands">Other Useful CVS Commands</a> | ||
2715 | <br> | ||
2716 | |||
2717 | <h3>Removing Files</h3> | ||
2718 | |||
2719 | <p>Removing a file is similar to adding one, except there's an extra step: | ||
2720 | You have to remove the file from the working copy first: | ||
2721 | |||
2722 | <pre>floss$ rm newfile.c | ||
2723 | floss$ cvs remove newfile.c | ||
2724 | cvs remove: scheduling 'newfile.c' for removal | ||
2725 | cvs remove: use 'cvs commit' to remove this file permanently | ||
2726 | floss$ cvs ci -m "removed newfile.c" newfile.c | ||
2727 | Removing newfile.c; | ||
2728 | /usr/local/cvs/myproj/newfile.c,v <- newfile.c | ||
2729 | new revision: delete; previous revision: 1.1 | ||
2730 | done | ||
2731 | floss$ | ||
2732 | </pre> | ||
2733 | |||
2734 | <p>Notice how, in the second and third commands, we name newfile.c | ||
2735 | explicitly even though it doesn't exist in the working copy anymore. Of | ||
2736 | course, in the commit, you don't absolutely need to name the file, as | ||
2737 | long as you don't mind the commit encompassing any other modifications | ||
2738 | that may have taken place in the working copy. | ||
2739 | |||
2740 | <p><hr> | ||
2741 | Node:<a name="Removing_Directories">Removing Directories</a>, | ||
2742 | Next:<a rel=next href="#Renaming_Files_And_Directories">Renaming Files And Directories</a>, | ||
2743 | Previous:<a rel=previous href="#Removing_Files">Removing Files</a>, | ||
2744 | Up:<a rel=up href="#Other_Useful_CVS_Commands">Other Useful CVS Commands</a> | ||
2745 | <br> | ||
2746 | |||
2747 | <h3>Removing Directories</h3> | ||
2748 | |||
2749 | <p>As I said before, CVS doesn't really keep directories under version | ||
2750 | control. Instead, as a kind of cheap substitute, it offers certain odd | ||
2751 | behaviors that in most cases do the "right thing". One of these odd | ||
2752 | behaviors is that empty directories can be treated specially. If you | ||
2753 | want to remove a directory from a project, you first remove all the | ||
2754 | files in it | ||
2755 | |||
2756 | <pre>floss$ cd dir | ||
2757 | floss$ rm file1 file2 file3 | ||
2758 | floss$ cvs remove file1 file2 file3 | ||
2759 | (output omitted) | ||
2760 | floss$ cvs ci -m "removed all files" file1 file2 file3 | ||
2761 | (output omitted) | ||
2762 | </pre> | ||
2763 | |||
2764 | <p>and then run update in the directory above it with the -P flag: | ||
2765 | |||
2766 | <pre>floss$ cd .. | ||
2767 | floss$ cvs update -P | ||
2768 | (output omitted) | ||
2769 | </pre> | ||
2770 | |||
2771 | <p>The -P option tells update to "prune" any empty directories - that is, | ||
2772 | to remove them from the working copy. Once that's done, the directory | ||
2773 | can be said to have been removed; all of its files are gone, and the | ||
2774 | directory itself is gone (from the working copy, at least, although | ||
2775 | there is actually still an empty directory in the repository). | ||
2776 | |||
2777 | <p>An interesting counterpart to this behavior is that when you run a plain | ||
2778 | update, CVS does not automatically bring new directories from the | ||
2779 | repository into your working copy. There are a couple of different | ||
2780 | justifications for this, none really worth going into here. The short | ||
2781 | answer is that from time to time you should run update with the -d flag, | ||
2782 | telling it to bring down any new directories from the repository. | ||
2783 | |||
2784 | <p><hr> | ||
2785 | Node:<a name="Renaming_Files_And_Directories">Renaming Files And Directories</a>, | ||
2786 | Next:<a rel=next href="#Avoiding_Option_Fatigue">Avoiding Option Fatigue</a>, | ||
2787 | Previous:<a rel=previous href="#Removing_Directories">Removing Directories</a>, | ||
2788 | Up:<a rel=up href="#Other_Useful_CVS_Commands">Other Useful CVS Commands</a> | ||
2789 | <br> | ||
2790 | |||
2791 | <h3>Renaming Files And Directories</h3> | ||
2792 | |||
2793 | <p>Renaming a file is equivalent to creating it under the new name and | ||
2794 | removing it under the old. In Unix, the commands are: | ||
2795 | |||
2796 | <pre>floss$ cp oldname newname | ||
2797 | floss$ rm oldname | ||
2798 | </pre> | ||
2799 | |||
2800 | <p>Here's the equivalent in CVS: | ||
2801 | |||
2802 | <pre>floss$ mv oldname newname | ||
2803 | floss$ cvs remove oldname | ||
2804 | (output omitted) | ||
2805 | floss$ cvs add newname | ||
2806 | (output omitted) | ||
2807 | floss$ cvs ci -m "renamed oldname to newname" oldname newname | ||
2808 | (output omitted) | ||
2809 | floss$ | ||
2810 | </pre> | ||
2811 | |||
2812 | <p>For files, that's all there is to it. Renaming directories is not done | ||
2813 | very differently: create the new directory, cvs add it, move all the | ||
2814 | files from the old directory to the new one, cvs remove them from the | ||
2815 | old directory, cvs add them in the new one, cvs commit so everything | ||
2816 | takes effect, and then do cvs update -P to make the now-empty directory | ||
2817 | disappear from the working copy. That is to say: | ||
2818 | |||
2819 | <pre>floss$ mkdir newdir | ||
2820 | floss$ cvs add newdir | ||
2821 | floss$ mv olddir/* newdir | ||
2822 | mv: newdir/CVS: cannot overwrite directory | ||
2823 | floss$ cd olddir | ||
2824 | floss$ cvs rm foo.c bar.txt | ||
2825 | floss$ cd ../newdir | ||
2826 | floss$ cvs add foo.c bar.txt | ||
2827 | floss$ cd .. | ||
2828 | floss$ cvs commit -m "moved foo.c and bar.txt from olddir to newdir" | ||
2829 | floss$ cvs update -P | ||
2830 | </pre> | ||
2831 | |||
2832 | <p>Note: the warning message after the third command. It's telling you | ||
2833 | that it can't copy olddir's CVS/ subdirectory into newdir because newdir | ||
2834 | already has a directory of that name. This is fine, because you want | ||
2835 | olddir to keep its CVS/ subdirectory anyway. | ||
2836 | |||
2837 | <p>Obviously, moving directories around can get a bit cumbersome. The best | ||
2838 | policy is to try to come up with a good layout when you initially import | ||
2839 | your project so you won't have to move directories around very often. | ||
2840 | Later, you'll learn about a more drastic method of moving directories | ||
2841 | that involves making the change directly in the repository. However, | ||
2842 | that method is best saved for emergencies; whenever possible, it's best | ||
2843 | to handle everything with CVS operations inside working copies. | ||
2844 | |||
2845 | <p><hr> | ||
2846 | Node:<a name="Avoiding_Option_Fatigue">Avoiding Option Fatigue</a>, | ||
2847 | Next:<a rel=next href="#Getting_Snapshots__Dates_And_Tagging_">Getting Snapshots (Dates And Tagging)</a>, | ||
2848 | Previous:<a rel=previous href="#Renaming_Files_And_Directories">Renaming Files And Directories</a>, | ||
2849 | Up:<a rel=up href="#Other_Useful_CVS_Commands">Other Useful CVS Commands</a> | ||
2850 | <br> | ||
2851 | |||
2852 | <h3>Avoiding Option Fatigue</h3> | ||
2853 | |||
2854 | <p>Most people tire pretty quickly of typing the same option flags with | ||
2855 | every command. If you know that you always want to pass the -Q global | ||
2856 | option or you always want to use -c with diff, why should you have to | ||
2857 | type it out each time? | ||
2858 | |||
2859 | <p>There is help, fortunately. CVS looks for a .cvsrc file in your home | ||
2860 | directory. In that file, you can specify default options to apply to | ||
2861 | every invocation of CVS. Here's an example .cvsrc: | ||
2862 | |||
2863 | <pre>diff -c | ||
2864 | update -P | ||
2865 | cvs -q | ||
2866 | </pre> | ||
2867 | |||
2868 | <p>If the leftmost word on a line matches a CVS command (in its | ||
2869 | unabbreviated form), the corresponding options are used for that command | ||
2870 | every time. For global options, you just use cvs. So, for example, | ||
2871 | every time that user runs cvs diff, the -c flag is automatically | ||
2872 | included. | ||
2873 | |||
2874 | <p><hr> | ||
2875 | Node:<a name="Getting_Snapshots__Dates_And_Tagging_">Getting Snapshots (Dates And Tagging)</a>, | ||
2876 | Next:<a rel=next href="#Acceptable_Date_Formats">Acceptable Date Formats</a>, | ||
2877 | Previous:<a rel=previous href="#Avoiding_Option_Fatigue">Avoiding Option Fatigue</a>, | ||
2878 | Up:<a rel=up href="#Other_Useful_CVS_Commands">Other Useful CVS Commands</a> | ||
2879 | <br> | ||
2880 | |||
2881 | <h3>Getting Snapshots (Dates And Tagging)</h3> | ||
2882 | |||
2883 | <p>Let's return to the example of the program that's in a broken state when | ||
2884 | a bug report comes in. The developer suddenly needs access to the | ||
2885 | entire project as it was at the time of the last release, even though | ||
2886 | many files may have been changed since then, and each file's revision | ||
2887 | number differs from the others. It would be far too time-consuming to | ||
2888 | look over the log messages, figure out what each file's individual | ||
2889 | revision number was at the time of release, and then run update | ||
2890 | (specifying a revision number with -r) on each one of them. In medium- | ||
2891 | to large-sized projects (tens to hundreds of files), such a process | ||
2892 | would be too unwieldy to attempt. | ||
2893 | |||
2894 | <p>CVS, therefore, provides a way to retrieve previous revisions of the | ||
2895 | files in a project en masse. In fact, it provides two ways: by date, | ||
2896 | which selects the revisions based on the time that they were committed, | ||
2897 | and by tag, which retrieves a previously marked "snapshot" of the | ||
2898 | project. | ||
2899 | |||
2900 | <p>Which method you use depends on the situation. The date-based | ||
2901 | retrievals are done by passing update the -D flag, which is similar to | ||
2902 | -r but takes dates instead of revision numbers: | ||
2903 | |||
2904 | <pre>floss$ cvs -q update -D "1999-04-19" | ||
2905 | U hello.c | ||
2906 | U a-subdir/subsubdir/fish.c | ||
2907 | U b-subdir/random.c | ||
2908 | floss$ | ||
2909 | </pre> | ||
2910 | |||
2911 | <p>With the -D option, update retrieves the highest revision of each file | ||
2912 | as of the given date, and it will revert the files in the working copy | ||
2913 | to prior revisions if necessary. | ||
2914 | |||
2915 | <p>When you give the date, you can, and often should, include the time. | ||
2916 | For example, the previous command ended up retrieving revision 1.1 of | ||
2917 | everything (only three files showed changes, because all of the others | ||
2918 | are still at revision 1.1 anyway). Here's the status of hello.c to | ||
2919 | prove it: | ||
2920 | |||
2921 | <pre>floss$ cvs -Q status hello.c | ||
2922 | =================================================================== | ||
2923 | File: hello.c Status: Up-to-date | ||
2924 | Working revision: 1.1.1.1 Sat Apr 24 22:45:03 1999 | ||
2925 | Repository revision: 1.1.1.1 /usr/local/cvs/myproj/hello.c,v | ||
2926 | Sticky Date: 99.04.19.05.00.00 | ||
2927 | floss$ | ||
2928 | </pre> | ||
2929 | |||
2930 | <p>But a glance back at the log messages from earlier in this chapter shows | ||
2931 | that revision 1.2 of hello.c was definitely committed on April 19, | ||
2932 | 1999. So why did we now get revision 1.1 instead of 1.2? | ||
2933 | |||
2934 | <p>The problem is that the date "1999-04-19" was interpreted as meaning | ||
2935 | "the midnight that begins 1999-04-19" - that is, the very first instant | ||
2936 | on that date. This is probably not what you want. The 1.2 commit took | ||
2937 | place later in the day. By qualifying the date more precisely, we can | ||
2938 | retrieve revision 1.2: | ||
2939 | |||
2940 | <pre>floss$ cvs -q update -D "1999-04-19 23:59:59" | ||
2941 | U hello.c | ||
2942 | U a-subdir/subsubdir/fish.c | ||
2943 | U b-subdir/random.c | ||
2944 | floss$ cvs status hello.c | ||
2945 | =================================================================== | ||
2946 | File: hello.c Status: Locally Modified | ||
2947 | Working revision: 1.2 Sat Apr 24 22:45:22 1999 | ||
2948 | Repository revision: 1.2 /usr/local/cvs/myproj/hello.c,v | ||
2949 | Sticky Tag: (none) | ||
2950 | Sticky Date: 99.04.20.04.59.59 | ||
2951 | Sticky Options: (none) | ||
2952 | floss$ | ||
2953 | </pre> | ||
2954 | |||
2955 | <p>We're almost there. If you look closely at the date/time on the Sticky | ||
2956 | Date line, it seems to indicate 4:59:59 A.M., not 11:59 as the command | ||
2957 | requested (later we'll get to what the "sticky" means). As you may have | ||
2958 | guessed, the discrepancy is due to the difference between local time and | ||
2959 | Universal Coordinated Time (also known as "Greenwich mean time"). The | ||
2960 | repository always stores dates in Universal Time, but CVS on the client | ||
2961 | side usually assumes the local system time zone. In the case of -D, | ||
2962 | this is rather unfortunate because you're probably most interested in | ||
2963 | comparing against the repository time and don't care about the local | ||
2964 | system's idea of time. You can get around this by specifying the GMT | ||
2965 | zone in the command: | ||
2966 | |||
2967 | <pre>floss$ cvs -q update -D "1999-04-19 23:59:59 GMT" | ||
2968 | U hello.c | ||
2969 | floss$ cvs -q status hello.c | ||
2970 | =================================================================== | ||
2971 | File: hello.c Status: Up-to-date | ||
2972 | Working revision: 1.2 Sun Apr 25 22:38:53 1999 | ||
2973 | Repository revision: 1.2 /usr/local/cvs/myproj/hello.c,v | ||
2974 | Sticky Tag: (none) | ||
2975 | Sticky Date: 99.04.19.23.59.59 | ||
2976 | Sticky Options: (none) | ||
2977 | floss$ | ||
2978 | </pre> | ||
2979 | |||
2980 | <p>There - that brought the working copy back to the final commits from | ||
2981 | April 19 (unless there were any commits during the last second of the | ||
2982 | day, which there weren't). | ||
2983 | |||
2984 | <p>What happens now if you run update? | ||
2985 | |||
2986 | <pre>floss$ cvs update | ||
2987 | cvs update: Updating . | ||
2988 | cvs update: Updating a-subdir | ||
2989 | cvs update: Updating a-subdir/subsubdir | ||
2990 | cvs update: Updating b-subdir | ||
2991 | floss$ | ||
2992 | </pre> | ||
2993 | |||
2994 | <p>Nothing happens at all. But you know that there are more recent | ||
2995 | versions of at least three files. Why aren't these included in your | ||
2996 | working copy? | ||
2997 | |||
2998 | <p>That's where the "sticky" comes in. Updating ("downdating"?) with the | ||
2999 | -D flag causes the working copy to be restricted permanently to that | ||
3000 | date or before. In CVS terminology, the working copy has a "sticky | ||
3001 | date" set. Once a working copy has acquired a sticky property, it stays | ||
3002 | sticky until told otherwise. Therefore, subsequent updates will not | ||
3003 | automatically retrieve the most recent revision. Instead, they'll stay | ||
3004 | restricted to the sticky date. Stickiness can be revealed by running | ||
3005 | cvs status or by directly examining the CVS/Entries file: | ||
3006 | |||
3007 | <pre>floss$ cvs -q update -D "1999-04-19 23:59:59 GMT" | ||
3008 | U hello.c | ||
3009 | floss$ cat CVS/Entries | ||
3010 | D/a-subdir//// | ||
3011 | D/b-subdir//// | ||
3012 | D/c-subdir//// | ||
3013 | /README.txt/1.1.1.1/Sun Apr 18 18:18:22 1999//D99.04.19.23.59.59 | ||
3014 | /hello.c/1.2/Sun Apr 25 23:07:29 1999//D99.04.19.23.59.59 | ||
3015 | floss$ | ||
3016 | </pre> | ||
3017 | |||
3018 | <p>If you were to modify hello.c and then try to commit | ||
3019 | |||
3020 | <pre>floss$ cvs update | ||
3021 | M hello.c | ||
3022 | floss$ cvs ci -m "trying to change the past" | ||
3023 | cvs commit: cannot commit with sticky date for file 'hello.c' | ||
3024 | cvs [commit aborted]: correct above errors first! | ||
3025 | floss$ | ||
3026 | </pre> | ||
3027 | |||
3028 | <p>CVS would not permit the commit to happen because that would be like | ||
3029 | allowing you to go back and change the past. CVS is all about record | ||
3030 | keeping and, therefore, will not allow you to do that. | ||
3031 | |||
3032 | <p>This does not mean CVS is unaware of all the revisions that have been | ||
3033 | committed since that date, however. You can still compare the | ||
3034 | sticky-dated working copy against other revisions, including future | ||
3035 | ones: | ||
3036 | |||
3037 | <pre>floss$ cvs -q diff -c -r 1.5 hello.c | ||
3038 | Index: hello.c | ||
3039 | =================================================================== | ||
3040 | RCS file: /usr/local/cvs/myproj/hello.c,v | ||
3041 | retrieving revision 1.5 | ||
3042 | diff -c -r1.5 hello.c | ||
3043 | *** hello.c 1999/04/24 22:09:27 1.5 | ||
3044 | --- hello.c 1999/04/25 00:08:44 | ||
3045 | *************** | ||
3046 | *** 3,9 **** | ||
3047 | void | ||
3048 | main () | ||
3049 | { | ||
3050 | printf ("Hello, world!\n"); | ||
3051 | - printf ("between hello and goodbye\n"); | ||
3052 | printf ("Goodbye, world!\n"); | ||
3053 | } | ||
3054 | --- 3,9 -- | ||
3055 | void | ||
3056 | main () | ||
3057 | { | ||
3058 | + /* this line was added to a downdated working copy */ | ||
3059 | printf ("Hello, world!\n"); | ||
3060 | printf ("Goodbye, world!\n"); | ||
3061 | } | ||
3062 | </pre> | ||
3063 | |||
3064 | <p>This diff reveals that, as of April 19, 1999, the between hello and | ||
3065 | goodbye line had not yet been added. It also shows the modification | ||
3066 | that we made to the working copy (adding the comment shown in the | ||
3067 | preceding code snippet). | ||
3068 | |||
3069 | <p>You can remove a sticky date (or any sticky property) by updating with | ||
3070 | the -A flag (-A stands for "reset", don't ask me why), which brings the | ||
3071 | working copy back to the most recent revisions: | ||
3072 | |||
3073 | <pre>floss$ cvs -q update -A | ||
3074 | U hello.c | ||
3075 | floss$ cvs status hello.c | ||
3076 | =================================================================== | ||
3077 | File: hello.c Status: Up-to-date | ||
3078 | Working revision: 1.5 Sun Apr 25 22:50:27 1999 | ||
3079 | Repository revision: 1.5 /usr/local/cvs/myproj/hello.c,v | ||
3080 | Sticky Tag: (none) | ||
3081 | Sticky Date: (none) | ||
3082 | Sticky Options: (none) | ||
3083 | floss$ | ||
3084 | </pre> | ||
3085 | |||
3086 | <p><hr> | ||
3087 | Node:<a name="Acceptable_Date_Formats">Acceptable Date Formats</a>, | ||
3088 | Next:<a rel=next href="#Marking_A_Moment_In_Time__Tags_">Marking A Moment In Time (Tags)</a>, | ||
3089 | Previous:<a rel=previous href="#Getting_Snapshots__Dates_And_Tagging_">Getting Snapshots (Dates And Tagging)</a>, | ||
3090 | Up:<a rel=up href="#Other_Useful_CVS_Commands">Other Useful CVS Commands</a> | ||
3091 | <br> | ||
3092 | |||
3093 | <h3>Acceptable Date Formats</h3> | ||
3094 | |||
3095 | <p>CVS accepts a wide range of syntaxes to specify dates. You'll never go | ||
3096 | wrong if you use ISO 8601 format (that is, the International Standards | ||
3097 | Organization standard #8601, see also | ||
3098 | www.saqqara.demon.co.uk/datefmt.htm), which is the format used in the | ||
3099 | preceding examples. You can also use Internet email dates as described | ||
3100 | in RFC 822 and RFC 1123 (see www.rfc-editor.org/rfc/). Finally, you can | ||
3101 | use certain unambiguous English constructs to specify dates relative to | ||
3102 | the current date. | ||
3103 | |||
3104 | <p>You will probably never need all of the formats available, but here are | ||
3105 | some more examples to give you an idea of what CVS accepts: | ||
3106 | |||
3107 | <pre>floss$ cvs update -D "19 Apr 1999" | ||
3108 | floss$ cvs update -D "19 Apr 1999 20:05" | ||
3109 | floss$ cvs update -D "19/04/1999" | ||
3110 | floss$ cvs update -D "3 days ago" | ||
3111 | floss$ cvs update -D "5 years ago" | ||
3112 | floss$ cvs update -D "19 Apr 1999 23:59:59 GMT" | ||
3113 | floss$ cvs update -D "19 Apr" | ||
3114 | </pre> | ||
3115 | |||
3116 | <p>The double quotes around the dates are there to ensure that the Unix | ||
3117 | shell treats the date as one argument even if it contains spaces. The | ||
3118 | quotes will do no harm if the date doesn't contain spaces, so it's | ||
3119 | probably best to always use them. | ||
3120 | |||
3121 | <p><hr> | ||
3122 | Node:<a name="Marking_A_Moment_In_Time__Tags_">Marking A Moment In Time (Tags)</a>, | ||
3123 | Previous:<a rel=previous href="#Acceptable_Date_Formats">Acceptable Date Formats</a>, | ||
3124 | Up:<a rel=up href="#Other_Useful_CVS_Commands">Other Useful CVS Commands</a> | ||
3125 | <br> | ||
3126 | |||
3127 | <h3>Marking A Moment In Time (Tags)</h3> | ||
3128 | |||
3129 | <p>Retrieving by date is useful when the mere passage of time is your main | ||
3130 | concern. But more often what you really want to do is retrieve the | ||
3131 | project as it was at the time of a specific event - perhaps a public | ||
3132 | release, a known stable point in the software's development, or the | ||
3133 | addition or removal of some major feature. | ||
3134 | |||
3135 | <p>Trying to remember the date when that event took place or deducing the | ||
3136 | date from log messages would be a tedious process. Presumably, the | ||
3137 | event, because it was important, was marked as such in the formal | ||
3138 | revision history. The method CVS offers for making such marks is known | ||
3139 | as <dfn>tagging</dfn>. | ||
3140 | |||
3141 | <p>Tags differ from commits in that they don't record any particular | ||
3142 | textual change to files, but rather a change in the developers' attitude | ||
3143 | about the files. A tag gives a label to the collection of revisions | ||
3144 | represented by one developer's working copy (usually, that working copy | ||
3145 | is completely up to date so the tag name is attached to the "latest and | ||
3146 | greatest" revisions in the repository). | ||
3147 | |||
3148 | <p>Setting a tag is as simple as this: | ||
3149 | |||
3150 | <pre>floss$ cvs -q tag Release-1999_05_01 | ||
3151 | T README.txt | ||
3152 | T hello.c | ||
3153 | T a-subdir/whatever.c | ||
3154 | T a-subdir/subsubdir/fish.c | ||
3155 | T b-subdir/random.c | ||
3156 | floss$ | ||
3157 | </pre> | ||
3158 | |||
3159 | <p>That command associates the symbolic name "Release-1999_05_01" with the | ||
3160 | snapshot represented by this working copy. Defined formally, snapshot | ||
3161 | means a set of files and associated revision numbers from the project. | ||
3162 | Those revision numbers do not have to be the same from file to file and, | ||
3163 | in fact, usually aren't. For example, assuming that tag was done on the | ||
3164 | same myproj directory that we've been using throughout this chapter and | ||
3165 | that the working copy was completely up to date, the symbolic name | ||
3166 | "Release-1999_05_01" will be attached to hello.c at revision 1.5, to | ||
3167 | fish.c at revision 1.2, to random.c at revision 1.2, and to everything | ||
3168 | else at revision 1.1. | ||
3169 | |||
3170 | <p>It may help to visualize a tag as a path or string linking various | ||
3171 | revisions of files in the project. In Figure 2.1, an imaginary string | ||
3172 | passes through the tagged revision number of each file in a project. | ||
3173 | |||
3174 | <pre> | ||
3175 | File A File B File C File D File E | ||
3176 | ------ ------ ------ ------ ------ | ||
3177 | 1.1 1.1 1.1 1.1 1.1 | ||
3178 | ----1.2-. 1.2 1.2 1.2 1.2 | ||
3179 | 1.3 | 1.3 1.3 1.3 1.3 | ||
3180 | \ 1.4 .-1.4-. 1.4 1.4 | ||
3181 | \ 1.5 / 1.5 \ 1.5 1.5 | ||
3182 | \ 1.6 / 1.6 | 1.6 1.6 | ||
3183 | \ 1.7 / | 1.7 1.7 | ||
3184 | \ 1.8 / | 1.8 .-1.8-------> | ||
3185 | \ 1.9 / | 1.9 / 1.9 | ||
3186 | `1.10' | 1.10 / 1.10 | ||
3187 | 1.11 | 1.11 | | ||
3188 | | 1.12 | | ||
3189 | | 1.13 | | ||
3190 | \ 1.14 | | ||
3191 | \ 1.15 / | ||
3192 | \ 1.16 / | ||
3193 | `-1.17-' | ||
3194 | |||
3195 | [Figure 2.1: How a tag might stand in relation to files's revisions.] | ||
3196 | |||
3197 | </pre> | ||
3198 | |||
3199 | <p>But if you pull the string taut and sight directly along it, you'll see | ||
3200 | a particular moment in the project's history - namely, the moment that | ||
3201 | the tag was set (Figure 2.2). | ||
3202 | |||
3203 | <pre> | ||
3204 | File A File B File C File D File E | ||
3205 | ------ ------ ------ ------ ------ | ||
3206 | 1.1 | ||
3207 | 1.2 | ||
3208 | 1.3 | ||
3209 | 1.4 | ||
3210 | 1.5 | ||
3211 | 1.6 | ||
3212 | 1.7 | ||
3213 | 1.1 1.8 | ||
3214 | 1.2 1.9 | ||
3215 | 1.3 1.10 1.1 | ||
3216 | 1.4 1.11 1.2 | ||
3217 | 1.5 1.12 1.3 | ||
3218 | 1.6 1.13 1.4 | ||
3219 | 1.7 1.1 1.14 1.5 | ||
3220 | 1.8 1.2 1.15 1.6 | ||
3221 | 1.1 1.9 1.3 1.16 1.7 | ||
3222 | ----1.2---------1.10--------1.4---------1.17--------1.8-------> | ||
3223 | 1.3 1.11 1.5 1.17 1.9 | ||
3224 | 1.6 1.17 1.10 | ||
3225 | |||
3226 | [Figure 2.2: The same tag as a "straight sight" through the revision history.] | ||
3227 | |||
3228 | </pre> | ||
3229 | |||
3230 | <p>As you continue to edit files and commit changes, the tag will not move | ||
3231 | along with the increasing revision numbers. It stays fixed, "stickily", | ||
3232 | at the revision number of each file at the time the tag was made. | ||
3233 | |||
3234 | <p>Given their importance as descriptors, it's a bit unfortunate that log | ||
3235 | messages can't be included with tags or that the tags themselves can't | ||
3236 | be full paragraphs of prose. In the preceding example, the tag is | ||
3237 | fairly obviously stating that the project was in a releasable state as | ||
3238 | of a certain date. However, sometimes you may want to make snapshots of | ||
3239 | a more complex state, which can result in ungainly tag names such as: | ||
3240 | |||
3241 | <pre>floss$ cvs tag testing-release-3_pre-19990525-public-release | ||
3242 | </pre> | ||
3243 | |||
3244 | <p>As a general rule, you should try to keep tags as terse as possible | ||
3245 | while still including all necessary information about the event that | ||
3246 | you're trying to record. When in doubt, err on the side of being overly | ||
3247 | descriptive - you'll be glad later when you're able to tell from some | ||
3248 | verbose tag name exactly what circumstance was recorded. | ||
3249 | |||
3250 | <p>You've probably noticed that no periods or spaces were used in the tag | ||
3251 | names. CVS is rather strict about what constitutes a valid tag name. | ||
3252 | The rules are that it must start with a letter and contain letters, | ||
3253 | digits, hyphens ("-"), and underscores ("_"). No spaces, periods, | ||
3254 | colons, commas, or any other symbols may be used. | ||
3255 | |||
3256 | <p>To retrieve a snapshot by tag name, the tag name is used just like a | ||
3257 | revision number. There are two ways to retrieve snapshots: You can | ||
3258 | check out a new working copy with a certain tag, or you can switch an | ||
3259 | existing working copy over to a tag. Both result in a working copy | ||
3260 | whose files are at the revisions specified by the tag. | ||
3261 | |||
3262 | <p>Most of the time, what you're trying to do is take a look at the project | ||
3263 | as it was at the time of the snapshot. You may not necessarily want to | ||
3264 | do this in your main working copy, where you presumably have uncommitted | ||
3265 | changes and other useful states built up, so let's assume you just want | ||
3266 | to check out a separate working copy with the tag. Here's how (but make | ||
3267 | sure to invoke this somewhere other than in your existing working copy | ||
3268 | or its parent directory!): | ||
3269 | |||
3270 | <pre>floss$ cvs checkout -r Release-1999_05_01 myproj | ||
3271 | cvs checkout: Updating myproj | ||
3272 | U myproj/README.txt | ||
3273 | U myproj/hello.c | ||
3274 | cvs checkout: Updating myproj/a-subdir | ||
3275 | U myproj/a-subdir/whatever.c | ||
3276 | cvs checkout: Updating myproj/a-subdir/subsubdir | ||
3277 | U myproj/a-subdir/subsubdir/fish.c | ||
3278 | cvs checkout: Updating myproj/b-subdir | ||
3279 | U myproj/b-subdir/random.c | ||
3280 | cvs checkout: Updating myproj/c-subdir | ||
3281 | </pre> | ||
3282 | |||
3283 | <p>We've seen the -r option before in the update command, where it preceded | ||
3284 | a revision number. In many ways a tag is just like a revision number | ||
3285 | because, for any file, a given tag corresponds to exactly one revision | ||
3286 | number (it's illegal, and generally impossible, to have two tags of the | ||
3287 | same name in the same project). In fact, anywhere you can use a | ||
3288 | revision number as part of a CVS command, you can use a tag name instead | ||
3289 | (as long as the tag has been set previously). If you want to diff a | ||
3290 | file's current state against its state at the time of the last release, | ||
3291 | you can do this: | ||
3292 | |||
3293 | <pre>floss$ cvs diff -c -r Release-1999_05_01 hello.c | ||
3294 | </pre> | ||
3295 | |||
3296 | <p>And if you want to revert it temporarily to that revision, you can do | ||
3297 | this: | ||
3298 | |||
3299 | <pre>floss$ cvs update -r Release-1999_05_01 hello.c | ||
3300 | </pre> | ||
3301 | |||
3302 | <p>The interchangeability of tags and revision numbers explains some of the | ||
3303 | strict rules about valid tag names. Imagine if periods were legal in | ||
3304 | tag names; you could have a tag named "1.3" attached to an actual | ||
3305 | revision number of "1.47". If you then issued the command | ||
3306 | |||
3307 | <pre>floss$ cvs update -r 1.3 hello.c | ||
3308 | </pre> | ||
3309 | |||
3310 | <p>how would CVS know whether you were referring to the tag named "1.3", or | ||
3311 | the much earlier revision 1.3 of hello.c? Thus, restrictions are placed | ||
3312 | on tag names so that they can always be easily distinguished from | ||
3313 | revision numbers. A revision number has a period; a tag name | ||
3314 | doesn't. (There are reasons for the other restrictions, too, mostly | ||
3315 | having to do with making tag names easy for CVS to parse.) | ||
3316 | |||
3317 | <p>As you've probably guessed by this point, the second method of | ||
3318 | retrieving a snapshot - that is, switching an existing working | ||
3319 | directory over to the tagged revisions-is also done by updating: | ||
3320 | |||
3321 | <pre>floss$ cvs update -r Release-1999_05_01 | ||
3322 | cvs update: Updating . | ||
3323 | cvs update: Updating a-subdir | ||
3324 | cvs update: Updating a-subdir/subsubdir | ||
3325 | cvs update: Updating b-subdir | ||
3326 | cvs update: Updating c-subdir | ||
3327 | floss$ | ||
3328 | </pre> | ||
3329 | |||
3330 | <p>The preceding command is just like the one we used to revert hello.c to | ||
3331 | <code>Release-1999_05_01</code>, except that the filename is omitted because | ||
3332 | we want to revert the entire project over. (You can, if you want, | ||
3333 | revert just one subtree of the project to the tag by invoking the | ||
3334 | preceding command in that subtree instead of from the top level, | ||
3335 | although you hardly ever would want to do that.) | ||
3336 | |||
3337 | <p>Note that no files appear to have changed when we updated. The working | ||
3338 | copy was completely up to date when we tagged, and no changes had been | ||
3339 | committed since the tagging. | ||
3340 | |||
3341 | <p>However, this does not mean that nothing changed at all. The working | ||
3342 | copy now knows that it's at a tagged revision. When you make a change | ||
3343 | and try to commit it (let's assume we modified hello.c): | ||
3344 | |||
3345 | <pre>floss$ cvs -q update | ||
3346 | M hello.c | ||
3347 | floss$ cvs -q ci -m "trying to commit from a working copy on a tag" | ||
3348 | cvs commit: sticky tag 'Release-1999_05_01' for file 'hello.c' is not a branch | ||
3349 | cvs [commit aborted]: correct above errors first! | ||
3350 | floss$ | ||
3351 | </pre> | ||
3352 | |||
3353 | <p>CVS does not permit the commit to happen. (Don't worry about the exact | ||
3354 | meaning of that error message yet - we'll cover branches next in this | ||
3355 | chapter.) It doesn't matter whether the working copy got to be on a tag | ||
3356 | via a checkout or an update. Once it is on a tag, CVS views the working | ||
3357 | copy as a static snapshot of a moment in history, and CVS won't let you | ||
3358 | change history, at least not easily. If you run cvs status or look at | ||
3359 | the CVS/Entries files, you'll see that there is a sticky tag set on each | ||
3360 | file. Here's the top level Entries file, for example: | ||
3361 | |||
3362 | <pre>floss$ cat CVS/Entries | ||
3363 | D/a-subdir//// | ||
3364 | D/b-subdir//// | ||
3365 | D/c-subdir//// | ||
3366 | /README.txt/1.1.1.1/Sun Apr 18 18:18:22 1999//TRelease-1999_05_01 | ||
3367 | /hello.c/1.5/Tue Apr 20 07:24:10 1999//TRelease-1999_05_01 | ||
3368 | floss$ | ||
3369 | </pre> | ||
3370 | |||
3371 | <p>Tags, like other sticky properties, are removed with the -A flag to | ||
3372 | update: | ||
3373 | |||
3374 | <pre>floss$ cvs -q update -A | ||
3375 | M hello.c | ||
3376 | floss$ | ||
3377 | </pre> | ||
3378 | |||
3379 | <p>The modification to hello.c did not go away, however; CVS is still aware | ||
3380 | that the file changed with respect to the repository: | ||
3381 | |||
3382 | <pre>floss$ cvs -q diff -c hello.c | ||
3383 | Index: hello.c | ||
3384 | =================================================================== | ||
3385 | RCS file: /usr/local/cvs/myproj/hello.c,v | ||
3386 | retrieving revision 1.5 | ||
3387 | diff -c -r1.5 hello.c | ||
3388 | *** hello.c 1999/04/20 06:12:56 1.5 | ||
3389 | --- hello.c 1999/05/04 20:09:17 | ||
3390 | *************** | ||
3391 | *** 6,9 **** | ||
3392 | --- 6,10 -- | ||
3393 | printf ("Hello, world!\n"); | ||
3394 | printf ("between hello and goodbye\n"); | ||
3395 | printf ("Goodbye, world!\n"); | ||
3396 | + /* a comment on the last line */ | ||
3397 | } | ||
3398 | floss$ | ||
3399 | </pre> | ||
3400 | |||
3401 | <p>Now that you've reset with update, CVS will accept a commit: | ||
3402 | |||
3403 | <pre>floss$ cvs ci -m "added comment to end of main function" | ||
3404 | cvs commit: Examining . | ||
3405 | cvs commit: Examining a-subdir | ||
3406 | cvs commit: Examining a-subdir/subsubdir | ||
3407 | cvs commit: Examining b-subdir | ||
3408 | cvs commit: Examining c-subdir | ||
3409 | Checking in hello.c; | ||
3410 | /usr/local/cvs/myproj/hello.c,v <- hello.c | ||
3411 | new revision: 1.6; previous revision: 1.5 | ||
3412 | done | ||
3413 | floss$ | ||
3414 | </pre> | ||
3415 | |||
3416 | <p>The tag <code>Release-1999_05_01</code> is still attached to revision 1.5, of | ||
3417 | course. Compare the file's status before and after a reversion to the | ||
3418 | tag: | ||
3419 | |||
3420 | <pre>floss$ cvs -q status hello.c | ||
3421 | =================================================================== | ||
3422 | File: hello.c Status: Up-to-date | ||
3423 | Working revision: 1.6 Tue May 4 20:09:17 1999 | ||
3424 | Repository revision: 1.6 /usr/local/cvs/myproj/hello.c,v | ||
3425 | Sticky Tag: (none) | ||
3426 | Sticky Date: (none) | ||
3427 | Sticky Options: (none) | ||
3428 | floss$ cvs -q update -r Release-1999_05_01 | ||
3429 | U hello.c | ||
3430 | floss$ cvs -q status hello.c | ||
3431 | =================================================================== | ||
3432 | File: hello.c Status: Up-to-date | ||
3433 | Working revision: 1.5 Tue May 4 20:21:12 1999 | ||
3434 | Repository revision: 1.5 /usr/local/cvs/myproj/hello.c,v | ||
3435 | Sticky Tag: Release-1999_05_01 (revision: 1.5) | ||
3436 | Sticky Date: (none) | ||
3437 | Sticky Options: (none) | ||
3438 | floss$ | ||
3439 | </pre> | ||
3440 | |||
3441 | <p>Now, having just told you that CVS doesn't let you change history, I'll | ||
3442 | show you how to change history. | ||
3443 | |||
3444 | <p><hr> | ||
3445 | Node:<a name="Branches">Branches</a>, | ||
3446 | Previous:<a rel=previous href="#Other_Useful_CVS_Commands">Other Useful CVS Commands</a>, | ||
3447 | Up:<a rel=up href="#An_Overview_of_CVS">An Overview of CVS</a> | ||
3448 | <br> | ||
3449 | |||
3450 | <h2>Branches</h2> | ||
3451 | |||
3452 | <p>We've been viewing CVS as a kind of intelligent, coordinating library. | ||
3453 | However, it can also be thought of as a time machine (thanks to Jim | ||
3454 | Blandy for the analogy). So far, we've only seen how you can examine | ||
3455 | the past with CVS, without affecting anything. Like all good time | ||
3456 | machines, CVS also allows you to go back in time to change the past. | ||
3457 | What do you get then? Science fiction fans know the answer to that | ||
3458 | question: an alternate universe, running parallel to ours, but diverging | ||
3459 | from ours at exactly the point where the past was changed. A CVS branch | ||
3460 | splits a project's development into separate, parallel histories. | ||
3461 | Changes made on one branch do not affect the other. | ||
3462 | |||
3463 | <ul> | ||
3464 | <li><a href="#Branching_Basics">Branching Basics</a>: | ||
3465 | <li><a href="#Merging_Changes_From_Branch_To_Trunk">Merging Changes From Branch To Trunk</a>: | ||
3466 | <li><a href="#Multiple_Merges">Multiple Merges</a>: | ||
3467 | <li><a href="#Creating_A_Tag_Or_Branch_Without_A_Working_Copy">Creating A Tag Or Branch Without A Working Copy</a>: | ||
3468 | </ul> | ||
3469 | |||
3470 | <p><hr> | ||
3471 | Node:<a name="Branching_Basics">Branching Basics</a>, | ||
3472 | Next:<a rel=next href="#Merging_Changes_From_Branch_To_Trunk">Merging Changes From Branch To Trunk</a>, | ||
3473 | Up:<a rel=up href="#Branches">Branches</a> | ||
3474 | <br> | ||
3475 | |||
3476 | <h3>Branching Basics</h3> | ||
3477 | |||
3478 | <p>Why are branches useful? | ||
3479 | |||
3480 | <p>Let's return for a moment to the scenario of the developer who, in the | ||
3481 | midst of working on a new version of the program, receives a bug report | ||
3482 | about an older released version. Assuming the developer fixes the | ||
3483 | problem, she still needs a way to deliver the fix to the customer. It | ||
3484 | won't help to just find an old copy of the program somewhere, patch it | ||
3485 | up without CVS's knowledge, and ship it off. There would be no record | ||
3486 | of what was done; CVS would be unaware of the fix; and later if | ||
3487 | something was discovered to be wrong with the patch, no one would have a | ||
3488 | starting point for reproducing the problem. | ||
3489 | |||
3490 | <p>It's even more ill-advised to fix the bug in the current, unstable | ||
3491 | version of the sources and ship that to the customer. Sure, the | ||
3492 | reported bug may be solved, but the rest of the code is in a | ||
3493 | half-implemented, untested state. It may run, but it's certainly not | ||
3494 | ready for prime time. | ||
3495 | |||
3496 | <p>Because the last released version is thought to be stable, aside from | ||
3497 | this one bug, the ideal solution is to go back and correct the bug in | ||
3498 | the old release - that is, to create an alternate universe in which the | ||
3499 | last public release includes this bug fix. | ||
3500 | |||
3501 | <p>That's where branches come in. The developer splits off a branch, | ||
3502 | rooted in the main line of development (the trunk) not at its most | ||
3503 | recent revisions, but back at the point of the last release. Then she | ||
3504 | checks out a working copy of this branch, makes whatever changes are | ||
3505 | necessary to fix the bug, and commits them on that branch, so there's a | ||
3506 | record of the bug fix. Now she can package up an interim release based | ||
3507 | on the branch and ship it to the customer. | ||
3508 | |||
3509 | <p>Her change won't have affected the code on the trunk, nor would she want | ||
3510 | it to without first finding out whether the trunk needs the same bug fix | ||
3511 | or not. If it does, she can merge the branch changes into the trunk. | ||
3512 | In a merge, CVS calculates the changes made on the branch between the | ||
3513 | point where it diverged from the trunk and the branch's tip (its most | ||
3514 | recent state), then applies those differences to the project at the tip | ||
3515 | of the trunk. The difference between the branch's root and its tip | ||
3516 | works out, of course, to be precisely the bug fix. | ||
3517 | |||
3518 | <p>Another good way to think of a merge is as a special case of updating. | ||
3519 | The difference is that in a merge, the changes to be incorporated are | ||
3520 | derived by comparing the branch's root and tip, instead of by comparing | ||
3521 | the working copy against the repository. | ||
3522 | |||
3523 | <p>The act of updating is itself similar to receiving patches directly from | ||
3524 | their authors and applying them by hand. In fact, to do an update, CVS | ||
3525 | calculates the difference (that's "difference" as in the diff program) | ||
3526 | between the working copy and the repository and then applies that diff | ||
3527 | to the working copy just as the patch program would. This mirrors the | ||
3528 | way in which a developer takes changes from the outside world, by | ||
3529 | manually applying patch files sent in by contributors. | ||
3530 | |||
3531 | <p>Thus, merging the bug fix branch into the trunk is just like accepting | ||
3532 | some outside contributor's patch to fix the bug. The contributor would | ||
3533 | have made the patch against the last released version, just as the | ||
3534 | branch's changes are against that version. If that area of code in the | ||
3535 | current sources hasn't changed much since the last release, the merge | ||
3536 | will succeed with no problems. If the code is now substantially | ||
3537 | different, however, the merge will fail with conflict (that is, the | ||
3538 | patch will be rejected), and some manual fiddling will be necessary. | ||
3539 | Usually this is accomplished by reading the conflicting area, making the | ||
3540 | necessary changes by hand, and committing. Figure 2.3 shows a picture | ||
3541 | of what happens in a branch and merge. | ||
3542 | |||
3543 | <pre> | ||
3544 | (branch on which bug was fixed) | ||
3545 | .---------------->---------------. | ||
3546 | / | | ||
3547 | / | | ||
3548 | / | | ||
3549 | / | | ||
3550 | / V (<------ point of merge) | ||
3551 | ====*===================================================================> | ||
3552 | (main line of development) | ||
3553 | |||
3554 | |||
3555 | [Figure 2.3: A branch and then a merge. Time flows left to right.] | ||
3556 | |||
3557 | </pre> | ||
3558 | |||
3559 | <p>We'll now walk through the steps necessary to make this picture happen. | ||
3560 | Remember that it's not really time that's flowing from left to right in | ||
3561 | the diagram, but rather the revision history. The branch will not have | ||
3562 | been made at the time of the release, but is created later, rooted back | ||
3563 | at the release's revisions. | ||
3564 | |||
3565 | <p>In our case, let's assume the files in the project have gone through | ||
3566 | many revisions since they were tagged as <code>Release-1999_05_01</code>, and | ||
3567 | perhaps files have been added as well. When the bug report regarding | ||
3568 | the old release comes in, the first thing we'll want to do is create a | ||
3569 | branch rooted at the old release, which we conveniently tagged | ||
3570 | <code>Release-1999_05_01</code>. | ||
3571 | |||
3572 | <p>One way to do this is to first check out a working copy based on that | ||
3573 | tag, then create the branch by re-tagging with the -b (branch) option: | ||
3574 | |||
3575 | <pre>floss$ cd .. | ||
3576 | floss$ ls | ||
3577 | myproj/ | ||
3578 | floss$ cvs -q checkout -d myproj_old_release -r Release-1999_05_01 myproj | ||
3579 | U myproj_old_release/README.txt | ||
3580 | U myproj_old_release/hello.c | ||
3581 | U myproj_old_release/a-subdir/whatever.c | ||
3582 | U myproj_old_release/a-subdir/subsubdir/fish.c | ||
3583 | U myproj_old_release/b-subdir/random.c | ||
3584 | floss$ ls | ||
3585 | myproj/ myproj_old_release/ | ||
3586 | floss$ cd myproj_old_release | ||
3587 | floss$ ls | ||
3588 | CVS/ README.txt a-subdir/ b-subdir/ hello.c | ||
3589 | floss$ cvs -q tag -b Release-1999_05_01-bugfixes | ||
3590 | T README.txt | ||
3591 | T hello.c | ||
3592 | T a-subdir/whatever.c | ||
3593 | T a-subdir/subsubdir/fish.c | ||
3594 | T b-subdir/random.c | ||
3595 | floss$ | ||
3596 | </pre> | ||
3597 | |||
3598 | <p>Take a good look at that last command. It may seem somewhat arbitrary | ||
3599 | that tag is used to create branches, but there's actually a reason for | ||
3600 | it: The tag name will serve as a label by which the branch can be | ||
3601 | retrieved later. Branch tags do not look any different from non-branch | ||
3602 | tags, and are subject to the same naming restrictions. Some people like | ||
3603 | to always include the word branch in the tag name itself (for example, | ||
3604 | <code>Release-1999_05_01-bugfix-branch</code>), so they can distinguish branch | ||
3605 | tags from other kinds of tags. You may want to do this if you find | ||
3606 | yourself often retrieving the wrong tag. | ||
3607 | |||
3608 | <p>(And while we're at it, note the -d myproj_old_release option to | ||
3609 | checkout in the first CVS command. This tells checkout to put the | ||
3610 | working copy in a directory called myproj_old_release, so we won't | ||
3611 | confuse it with the current version in myproj. Be careful not to | ||
3612 | confuse this use of -d with the global option of the same name, or with | ||
3613 | the -d option to update.) | ||
3614 | |||
3615 | <p>Of course, merely running the tag command does not switch this working | ||
3616 | copy over to the branch. Tagging never affects the working copy; it | ||
3617 | just records some extra information in the repository to allow you to | ||
3618 | retrieve that working copy's revisions later on (as a static piece of | ||
3619 | history or as a branch, as the case may be). | ||
3620 | |||
3621 | <p>Retrieval can be done one of two ways (you're probably getting used to | ||
3622 | this motif by now!). You can check out a new working copy on the branch | ||
3623 | |||
3624 | <pre>floss$ pwd | ||
3625 | /home/whatever | ||
3626 | floss$ cvs co -d myproj_branch -r Release-1999_05_01-bugfixes myproj | ||
3627 | </pre> | ||
3628 | |||
3629 | <p>or switch an existing working copy over to it: | ||
3630 | |||
3631 | <pre>floss$ pwd | ||
3632 | /home/whatever/myproj | ||
3633 | floss$ cvs update -r Release-1999_05_01-bugfixes | ||
3634 | </pre> | ||
3635 | |||
3636 | <p>The end result is the same (well, the name of the new working copy's | ||
3637 | top-level directory may be different, but that's not important for CVS's | ||
3638 | purposes). If your current working copy has uncommitted changes, you'll | ||
3639 | probably want to use checkout instead of update to access the branch. | ||
3640 | Otherwise, CVS attempts to merge your changes into the working copy as | ||
3641 | it switches it over to the branch. In that case, you might get | ||
3642 | conflicts, and even if you didn't, you'd still have an impure branch. | ||
3643 | It won't truly reflect the state of the program as of the designated | ||
3644 | tag, because some files in the working copy will contain modifications | ||
3645 | made by you. | ||
3646 | |||
3647 | <p>Anyway, let's assume that by one method or another you get a working | ||
3648 | copy on the desired branch: | ||
3649 | |||
3650 | <pre>floss$ cvs -q status hello.c | ||
3651 | =================================================================== | ||
3652 | File: hello.c Status: Up-to-date | ||
3653 | Working revision: 1.5 Tue Apr 20 06:12:56 1999 | ||
3654 | Repository revision: 1.5 /usr/local/cvs/myproj/hello.c,v | ||
3655 | Sticky Tag: Release-1999_05_01-bugfixes | ||
3656 | (branch: 1.5.2) | ||
3657 | Sticky Date: (none) | ||
3658 | Sticky Options: (none) | ||
3659 | floss$ cvs -q status b-subdir/random.c | ||
3660 | =================================================================== | ||
3661 | File: random.c Status: Up-to-date | ||
3662 | Working revision: 1.2 Mon Apr 19 06:35:27 1999 | ||
3663 | Repository revision: 1.2 /usr/local/cvs/myproj/b-subdir/random.c,v | ||
3664 | Sticky Tag: Release-1999_05_01-bugfixes (branch: 1.2.2) | ||
3665 | Sticky Date: (none) | ||
3666 | Sticky Options: (none) | ||
3667 | floss$ | ||
3668 | </pre> | ||
3669 | |||
3670 | <p>(The contents of those <code>Sticky Tag</code> lines will be explained | ||
3671 | shortly.) If you modify hello.c and random.c, and commit | ||
3672 | |||
3673 | <pre>floss$ cvs -q update | ||
3674 | M hello.c | ||
3675 | M b-subdir/random.c | ||
3676 | floss$ cvs ci -m "fixed old punctuation bugs" | ||
3677 | cvs commit: Examining . | ||
3678 | cvs commit: Examining a-subdir | ||
3679 | cvs commit: Examining a-subdir/subsubdir | ||
3680 | cvs commit: Examining b-subdir | ||
3681 | Checking in hello.c; | ||
3682 | /usr/local/cvs/myproj/hello.c,v <- hello.c | ||
3683 | new revision: 1.5.2.1; previous revision: 1.5 | ||
3684 | done | ||
3685 | Checking in b-subdir/random.c; | ||
3686 | /usr/local/cvs/myproj/b-subdir/random.c,v <- random.c | ||
3687 | new revision: 1.2.2.1; previous revision: 1.2 | ||
3688 | done | ||
3689 | floss$ | ||
3690 | </pre> | ||
3691 | |||
3692 | <p>you'll notice that there's something funny going on with the revision | ||
3693 | numbers: | ||
3694 | |||
3695 | <pre>floss$ cvs -q status hello.c b-subdir/random.c | ||
3696 | =================================================================== | ||
3697 | File: hello.c Status: Up-to-date | ||
3698 | Working revision: 1.5.2.1 Wed May 5 00:13:58 1999 | ||
3699 | Repository revision: 1.5.2.1 /usr/local/cvs/myproj/hello.c,v | ||
3700 | Sticky Tag: Release-1999_05_01-bugfixes (branch: 1.5.2) | ||
3701 | Sticky Date: (none) | ||
3702 | Sticky Options: (none) | ||
3703 | =================================================================== | ||
3704 | File: random.c Status: Up-to-date | ||
3705 | Working revision: 1.2.2.1 Wed May 5 00:14:25 1999 | ||
3706 | Repository revision: 1.2.2.1 /usr/local/cvs/myproj/b-subdir/random.c,v | ||
3707 | Sticky Tag: Release-1999_05_01-bugfixes (branch: 1.2.2) | ||
3708 | Sticky Date: (none) | ||
3709 | Sticky Options: (none) | ||
3710 | floss$ | ||
3711 | </pre> | ||
3712 | |||
3713 | <p>They now have four digits instead of two! | ||
3714 | |||
3715 | <p>A closer look reveals that each file's revision number is just the | ||
3716 | branch number (as shown on the <code>Sticky Tag</code> line) plus an extra | ||
3717 | digit on the end. | ||
3718 | |||
3719 | <p>What you're seeing is a little bit of CVS's inner workings. Although | ||
3720 | you almost always use a branch to mark a project-wide divergence, CVS | ||
3721 | actually records the branch on a per-file basis. This project had five | ||
3722 | files in it at the point of the branch, so five individual branches were | ||
3723 | made, all with the same tag name: <code>Release-1999_05_01-bugfixes</code>. | ||
3724 | |||
3725 | <p>Most people consider this per-file scheme a rather inelegant | ||
3726 | implementation on CVS's part. It's a bit of the old RCS legacy showing | ||
3727 | through-RCS didn't know how to group files into projects, and even | ||
3728 | though CVS does, it still uses code inherited from RCS to handle | ||
3729 | branches. | ||
3730 | |||
3731 | <p>Ordinarily, you don't need to be too concerned with how CVS is keeping | ||
3732 | track of things internally, but in this case, it helps to understand the | ||
3733 | relationship between branch numbers and revision numbers. Let's look at | ||
3734 | the hello.c file; everything I'm about to say about hello.c applies to | ||
3735 | the other files in the branch (with revision/branch numbers adjusted | ||
3736 | accordingly). | ||
3737 | |||
3738 | <p>The hello.c file was on revision 1.5 at the point where the branch was | ||
3739 | rooted. When we created the branch, a new number was tacked onto the | ||
3740 | end to make a branch number (CVS chooses the first unused even, nonzero | ||
3741 | integer). Thus, the branch number in this case became <code>1.5.2</code>. | ||
3742 | The branch number by itself is not a revision number, but it is the root | ||
3743 | (that is, the prefix) of all the revision numbers for hello.c along this | ||
3744 | branch. | ||
3745 | |||
3746 | <p>However, when we ran that first CVS status in a branched working copy, | ||
3747 | hello.c's revision number showed up as only <code>1.5</code>, not | ||
3748 | <code>1.5.2.0</code> or something similar. This is because the initial | ||
3749 | revision on a branch is always the same as the trunk revision of the | ||
3750 | file, where the branch sprouts off. Therefore, CVS shows the trunk | ||
3751 | revision number in status output, for as long as the file is the same on | ||
3752 | both branch and trunk. | ||
3753 | |||
3754 | <p>Once we had committed a new revision, hello.c was no longer the same on | ||
3755 | both trunk and branch - the branch incarnation of the file had changed, | ||
3756 | while the trunk remained the same. Accordingly, hello.c was assigned | ||
3757 | its first branch revision number. We saw this in the status output | ||
3758 | after the commit, where its revision number is clearly <code>1.5.2.1</code>. | ||
3759 | |||
3760 | <p>The same story applies to the random.c file. Its revision number at the | ||
3761 | time of branching was <code>1.2</code>, so its first branch is <code>1.2.2</code>, | ||
3762 | and the first new commit of random.c on that branch received the | ||
3763 | revision number <code>1.2.2.1</code>. | ||
3764 | |||
3765 | <p>There is no numeric relationship between <code>1.5.2.1</code> and | ||
3766 | <code>1.2.2.1</code> - no reason to think that they are part of the same | ||
3767 | branch event, except that both files are tagged with | ||
3768 | <code>Release-1999_05_01-bugfixes</code>, and the tag is attached to branch | ||
3769 | numbers <code>1.5.2</code> and <code>1.2.2</code> in the respective files. | ||
3770 | Therefore, the tag name is your only handle on the branch as a | ||
3771 | project-wide entity. Although it is perfectly possible to move a file | ||
3772 | to a branch by using the revision number directly | ||
3773 | |||
3774 | <pre>floss$ cvs update -r 1.5.2.1 hello.c | ||
3775 | U hello.c | ||
3776 | floss$ | ||
3777 | </pre> | ||
3778 | |||
3779 | <p>it is almost always ill-advised. You would be mixing the branch | ||
3780 | revision of one file with non-branch revisions of the others. Who knows | ||
3781 | what losses may result? It is better to use the branch tag to refer to | ||
3782 | the branch and do all files at once by not specifying any particular | ||
3783 | file. That way you don't have to know or care what the actual branch | ||
3784 | revision number is for any particular file. | ||
3785 | |||
3786 | <p>It is also possible to have branches that sprout off other branches, to | ||
3787 | any level of absurdity. For example, if a file has a revision number of | ||
3788 | <code>1.5.4.37.2.3</code>, its revision history can be diagrammed like this: | ||
3789 | |||
3790 | <pre> 1.1 | ||
3791 | | | ||
3792 | 1.2 | ||
3793 | | | ||
3794 | 1.3 | ||
3795 | | | ||
3796 | 1.4 | ||
3797 | | | ||
3798 | 1.5 | ||
3799 | / \ | ||
3800 | / \ | ||
3801 | / \ | ||
3802 | (1.5.2) (1.5.4) <--- (these are branch numbers) | ||
3803 | / \ | ||
3804 | 1.5.2.1 1.5.4.1 | ||
3805 | | | | ||
3806 | 1.5.2.2 1.5.4.2 | ||
3807 | | | | ||
3808 | (etc) (...) <--- (collapsed 34 revisions for brevity) | ||
3809 | | | ||
3810 | 1.5.4.37 | ||
3811 | / | ||
3812 | / | ||
3813 | (1.5.4.37.2) <--- (this is also a branch number) | ||
3814 | / | ||
3815 | / | ||
3816 | 1.5.4.37.2.1 | ||
3817 | | | ||
3818 | 1.5.4.37.2.2 | ||
3819 | | | ||
3820 | 1.5.4.37.2.3 | ||
3821 | |||
3822 | [Figure 2.4: An unusually high degree of branching. Time flows downward.] | ||
3823 | |||
3824 | </pre> | ||
3825 | |||
3826 | <p>Admittedly, only the rarest circumstances make such a branching depth | ||
3827 | necessary, but isn't it nice to know that CVS will go as far as you're | ||
3828 | willing to take it? Nested branches are created the same way as any | ||
3829 | other branch: Check out a working copy on branch <code>N</code>, run cvs tag | ||
3830 | -b branchname in it, and you'll create branch <code>N.M</code> in the | ||
3831 | repository (where <code>N</code> represents the appropriate branch revision | ||
3832 | number in each file, such as <code>1.5.2.1</code>, and <code>M</code> represents the | ||
3833 | next available branch at the end of that number, such as <code>2</code>). | ||
3834 | |||
3835 | <p><hr> | ||
3836 | Node:<a name="Merging_Changes_From_Branch_To_Trunk">Merging Changes From Branch To Trunk</a>, | ||
3837 | Next:<a rel=next href="#Multiple_Merges">Multiple Merges</a>, | ||
3838 | Previous:<a rel=previous href="#Branching_Basics">Branching Basics</a>, | ||
3839 | Up:<a rel=up href="#Branches">Branches</a> | ||
3840 | <br> | ||
3841 | |||
3842 | <h3>Merging Changes From Branch To Trunk</h3> | ||
3843 | |||
3844 | <p>Now that the bug fix has been committed on the branch, let's switch the | ||
3845 | working copy over to the highest trunk revisions and see if the bug fix | ||
3846 | needs to be done there, too. We'll move the working copy off the branch | ||
3847 | by using update -A (branch tags are like other sticky properties in this | ||
3848 | respect) and then diffing against the branch we just left: | ||
3849 | |||
3850 | <pre>floss$ cvs -q update -d -A | ||
3851 | U hello.c | ||
3852 | U b-subdir/random.c | ||
3853 | floss$ cvs -q diff -c -r Release-1999_05_01-bugfixes | ||
3854 | Index: hello.c | ||
3855 | =================================================================== | ||
3856 | RCS file: /usr/local/cvs/myproj/hello.c,v | ||
3857 | retrieving revision 1.5.2.1 | ||
3858 | retrieving revision 1.6 | ||
3859 | diff -c -r1.5.2.1 -r1.6 | ||
3860 | *** hello.c 1999/05/05 00:15:07 1.5.2.1 | ||
3861 | --- hello.c 1999/05/04 20:19:16 1.6 | ||
3862 | *************** | ||
3863 | *** 4,9 **** | ||
3864 | main () | ||
3865 | { | ||
3866 | printf ("Hello, world!\n"); | ||
3867 | ! printf ("between hello and good-bye\n"); | ||
3868 | printf ("Goodbye, world!\n"); | ||
3869 | } | ||
3870 | --- 4,10 -- | ||
3871 | main () | ||
3872 | { | ||
3873 | printf ("Hello, world!\n"); | ||
3874 | ! printf ("between hello and goodbye\n"); | ||
3875 | printf ("Goodbye, world!\n"); | ||
3876 | + /* a comment on the last line */ | ||
3877 | } | ||
3878 | Index: b-subdir/random.c | ||
3879 | =================================================================== | ||
3880 | RCS file: /usr/local/cvs/myproj/b-subdir/random.c,v | ||
3881 | retrieving revision 1.2.2.1 | ||
3882 | retrieving revision 1.2 | ||
3883 | diff -c -r1.2.2.1 -r1.2 | ||
3884 | *** b-subdir/random.c 1999/05/05 00:15:07 1.2.2.1 | ||
3885 | --- b-subdir/random.c 1999/04/19 06:35:27 1.2 | ||
3886 | *************** | ||
3887 | *** 4,8 **** | ||
3888 | void main () | ||
3889 | { | ||
3890 | ! printf ("A random number.\n"); | ||
3891 | } | ||
3892 | --- 4,8 -- | ||
3893 | void main () | ||
3894 | { | ||
3895 | ! printf ("a random number\n"); | ||
3896 | } | ||
3897 | floss$ | ||
3898 | </pre> | ||
3899 | |||
3900 | <p>The diff shows that good-bye is spelled with a hyphen in the branch | ||
3901 | revision of hello.c, and that the trunk revision of that file has a | ||
3902 | comment near the end that the branch revision doesn't have. Meanwhile, | ||
3903 | in random.c, the branch revision has a capital "A" and a period, whereas | ||
3904 | the trunk doesn't. | ||
3905 | |||
3906 | <p>To actually merge the branch changes into the current working copy, run | ||
3907 | update with the -j flag (the same j for "join" that we used to revert a | ||
3908 | file to an old revision before): | ||
3909 | |||
3910 | <pre>floss$ cvs -q update -d -j Release-1999_05_01-bugfixes | ||
3911 | RCS file: /usr/local/cvs/myproj/hello.c,v | ||
3912 | retrieving revision 1.5 | ||
3913 | retrieving revision 1.5.2.1 | ||
3914 | Merging differences between 1.5 and 1.5.2.1 into hello.c | ||
3915 | RCS file: /usr/local/cvs/myproj/b-subdir/random.c,v | ||
3916 | retrieving revision 1.2 | ||
3917 | retrieving revision 1.2.2.1 | ||
3918 | Merging differences between 1.2 and 1.2.2.1 into random.c | ||
3919 | floss$ cvs -q update | ||
3920 | M hello.c | ||
3921 | M b-subdir/random.c | ||
3922 | floss$ cvs -q ci -m "merged from branch Release-1999_05_01-bugfixes" | ||
3923 | Checking in hello.c; | ||
3924 | /usr/local/cvs/myproj/hello.c,v <- hello.c | ||
3925 | new revision: 1.7; previous revision: 1.6 | ||
3926 | done | ||
3927 | Checking in b-subdir/random.c; | ||
3928 | /usr/local/cvs/myproj/b-subdir/random.c,v <- random.c | ||
3929 | new revision: 1.3; previous revision: 1.2 | ||
3930 | done | ||
3931 | floss$ | ||
3932 | </pre> | ||
3933 | |||
3934 | <p>This takes the changes from the branch's root to its tip and merges them | ||
3935 | into the current working copy (which subsequently shows those | ||
3936 | modifications just as though the files had been hand-edited into that | ||
3937 | state). The changes are then committed onto the trunk, since nothing in | ||
3938 | the repository changed when a working copy underwent a merge. | ||
3939 | |||
3940 | <p>Although no conflicts were encountered in this example, it's quite | ||
3941 | possible (even probable) that there would be some in a normal merge. If | ||
3942 | that happens, they need to be resolved like any other conflict, and then | ||
3943 | committed. | ||
3944 | |||
3945 | <p><hr> | ||
3946 | Node:<a name="Multiple_Merges">Multiple Merges</a>, | ||
3947 | Next:<a rel=next href="#Creating_A_Tag_Or_Branch_Without_A_Working_Copy">Creating A Tag Or Branch Without A Working Copy</a>, | ||
3948 | Previous:<a rel=previous href="#Merging_Changes_From_Branch_To_Trunk">Merging Changes From Branch To Trunk</a>, | ||
3949 | Up:<a rel=up href="#Branches">Branches</a> | ||
3950 | <br> | ||
3951 | |||
3952 | <h3>Multiple Merges</h3> | ||
3953 | |||
3954 | <p>Sometimes a branch will continue to be actively developed even after the | ||
3955 | trunk has undergone a merge from it. For example, this can happen if a | ||
3956 | second bug in the previous public release is discovered and has to be | ||
3957 | fixed on the branch. Maybe someone didn't get the joke in random.c, so | ||
3958 | on the branch, you have to add a line explaining it | ||
3959 | |||
3960 | <pre>floss$ pwd | ||
3961 | /home/whatever/myproj_branch | ||
3962 | floss$ cat b-subdir/random.c | ||
3963 | /* Print out a random number. */ | ||
3964 | #include <stdio.h> | ||
3965 | void main () | ||
3966 | { | ||
3967 | printf ("A random number.\n"); | ||
3968 | printf ("Get the joke?\n"); | ||
3969 | } | ||
3970 | floss$ | ||
3971 | </pre> | ||
3972 | |||
3973 | <p>and commit. If that bug fix also needs to be merged into the trunk, you | ||
3974 | might be tempted to try the same update command as before in the trunk | ||
3975 | working copy to "re-merge": | ||
3976 | |||
3977 | <pre>floss$ cvs -q update -d -j Release-1999_05_01-bugfixes | ||
3978 | RCS file: /usr/local/cvs/myproj/hello.c,v | ||
3979 | retrieving revision 1.5 | ||
3980 | retrieving revision 1.5.2.1 | ||
3981 | Merging differences between 1.5 and 1.5.2.1 into hello.c | ||
3982 | RCS file: /usr/local/cvs/myproj/b-subdir/random.c,v | ||
3983 | retrieving revision 1.2 | ||
3984 | retrieving revision 1.2.2.2 | ||
3985 | Merging differences between 1.2 and 1.2.2.2 into random.c | ||
3986 | rcsmerge: warning: conflicts during merge | ||
3987 | floss$ | ||
3988 | </pre> | ||
3989 | |||
3990 | <p>As you can see, that didn't have quite the desired effect-we got a | ||
3991 | conflict, even though the trunk copy hadn't been modified there and, | ||
3992 | therefore, no conflict was expected. | ||
3993 | |||
3994 | <p>The trouble was that the update command behaved exactly as described: It | ||
3995 | tried to take all the changes between the branch's root and tip and | ||
3996 | merge them into the current working copy. The only problem is, some of | ||
3997 | those changes had already been merged into this working copy. That's | ||
3998 | why we got the conflict: | ||
3999 | |||
4000 | <pre>floss$ pwd | ||
4001 | /home/whatever/myproj | ||
4002 | floss$ cat b-subdir/random.c | ||
4003 | /* Print out a random number. */ | ||
4004 | #include <stdio.h | ||
4005 | void main () | ||
4006 | { | ||
4007 | <<<<<<< random.c | ||
4008 | printf ("A random number.\n"); | ||
4009 | ======= | ||
4010 | printf ("A random number.\n"); | ||
4011 | printf ("Get the joke?\n"); | ||
4012 | >>>>>>> 1.2.2.2 | ||
4013 | } | ||
4014 | floss$ | ||
4015 | </pre> | ||
4016 | |||
4017 | <p>You could go through resolving all such conflicts by hand-it's usually | ||
4018 | not hard to tell what you need to do in each file. Nevertheless, it is | ||
4019 | even better to avoid a conflict in the first place. By passing two -j | ||
4020 | flags instead of one, you'll get only those changes from where you last | ||
4021 | merged to the tip instead of all of the changes on the branch, from root | ||
4022 | to tip. The first -j gives the starting point on the branch, and the | ||
4023 | second is just the plain branch name (which implies the tip of the | ||
4024 | branch). | ||
4025 | |||
4026 | <p>The question then is, how can you specify the point on the branch from | ||
4027 | which you last merged? One way is to qualify by using a date along with | ||
4028 | the branch tag name. CVS provides a special syntax for this: | ||
4029 | |||
4030 | <pre>floss$ cvs -q update -d -j "Release-1999_05_01-bugfixes:2 days ago" \ | ||
4031 | -j Release-1999_05_01-bugfixes | ||
4032 | RCS file: /usr/local/cvs/myproj/b-subdir/random.c,v | ||
4033 | retrieving revision 1.2.2.1 | ||
4034 | retrieving revision 1.2.2.2 | ||
4035 | Merging differences between 1.2.2.1 and 1.2.2.2 into random.c | ||
4036 | floss$ | ||
4037 | </pre> | ||
4038 | |||
4039 | <p>If the branch tag name is followed by a colon and then a date (in any of | ||
4040 | the usual CVS date syntaxes), CVS will include only changes later than | ||
4041 | that date. So if you knew that the original bug fix was committed on | ||
4042 | the branch three days ago, the preceding command would merge the second | ||
4043 | bug fix only. | ||
4044 | |||
4045 | <p>A better way, if you plan ahead, is to tag the branch after each bug fix | ||
4046 | (just a regular tag - we're not starting a new branch here or anything | ||
4047 | like that). Suppose after fixing the bug in the branch and committing, | ||
4048 | you do this in the branch's working copy: | ||
4049 | |||
4050 | <pre>floss$ cvs -q tag Release-1999_05_01-bugfixes-fix-number-1 | ||
4051 | T README.txt | ||
4052 | T hello.c | ||
4053 | T a-subdir/whatever.c | ||
4054 | T a-subdir/subsubdir/fish.c | ||
4055 | T b-subdir/random.c | ||
4056 | floss$ | ||
4057 | </pre> | ||
4058 | |||
4059 | <p>Then, when it's time to merge the second change into the trunk, you can | ||
4060 | use that conveniently placed tag to delimit the earlier revision: | ||
4061 | |||
4062 | <pre>floss$ cvs -q update -d -j Release-1999_05_01-bugfixes-fix-number-1 \ | ||
4063 | -j Release-1999_05_01-bugfixes | ||
4064 | RCS file: /usr/local/cvs/myproj/b-subdir/random.c,v | ||
4065 | retrieving revision 1.2.2.1 | ||
4066 | retrieving revision 1.2.2.2 | ||
4067 | Merging differences between 1.2.2.1 and 1.2.2.2 into random.c | ||
4068 | floss$ | ||
4069 | </pre> | ||
4070 | |||
4071 | <p>This way, of course, is much better than trying to recall how long ago | ||
4072 | you made one change versus another, but it only works if you remember to | ||
4073 | tag the branch every time it is merged to the trunk. The lesson, | ||
4074 | therefore, is to tag early and tag often! It's better to err on the side | ||
4075 | of too many tags (as long as they all have descriptive names) than to | ||
4076 | have too few. In these last examples, for instance, there was no | ||
4077 | requirement that the new tag on the branch have a name similar to the | ||
4078 | branch tag itself. Although I named it | ||
4079 | <code>Release-1999_05_01-bugfixes-fix-number-1</code>, it could just as easily | ||
4080 | have been <code>fix1</code>. However, the former is preferable, because it | ||
4081 | contains the name of the branch and thus won't ever be confused with a | ||
4082 | tag on some other branch. (Remember that tag names are unique within | ||
4083 | files, not within branches. You can't have two tags named <code>fix1</code> | ||
4084 | in the same file, even if they refer to revisions on different | ||
4085 | branches.) | ||
4086 | |||
4087 | <p><hr> | ||
4088 | Node:<a name="Creating_A_Tag_Or_Branch_Without_A_Working_Copy">Creating A Tag Or Branch Without A Working Copy</a>, | ||
4089 | Previous:<a rel=previous href="#Multiple_Merges">Multiple Merges</a>, | ||
4090 | Up:<a rel=up href="#Branches">Branches</a> | ||
4091 | <br> | ||
4092 | |||
4093 | <h3>Creating A Tag Or Branch Without A Working Copy</h3> | ||
4094 | |||
4095 | <p>As stated earlier, tagging affects the repository, not the working copy. | ||
4096 | That begs the question: Why require a working copy at all when tagging? | ||
4097 | The only purpose that it serves is to designate which project and which | ||
4098 | revisions of the various files in the project are being tagged. If you | ||
4099 | could specify the project and revisions independently of the working | ||
4100 | copy, no working copy would be necessary. | ||
4101 | |||
4102 | <p>There is such a way: the rtag command (for "repository tag"). It's very | ||
4103 | similar to tag; a couple of examples will explain its usage. Let's go | ||
4104 | back to the moment when the first bug report came in and we needed to | ||
4105 | create a branch rooted at the last public release. We checked out a | ||
4106 | working copy at the release tag and then ran <code>tag -b</code> on it: | ||
4107 | |||
4108 | <pre>floss$ cvs tag -b Release-1999_05_01-bugfixes | ||
4109 | </pre> | ||
4110 | |||
4111 | <p>This created a branch rooted at <code>Release-1999_05_01</code>. However, | ||
4112 | because we know the release tag, we could have used it in an rtag | ||
4113 | command to specify where to root the branch, not even bothering with a | ||
4114 | working copy: | ||
4115 | |||
4116 | <pre>floss$ cvs rtag -b -r Release-1999_05_01 Release-1999_05_01-bugfixes myproj | ||
4117 | </pre> | ||
4118 | |||
4119 | <p>That's all there is to it. That command can be issued from anywhere, | ||
4120 | inside or outside a working copy. However, your CVSROOT environment | ||
4121 | variable would have to point to the repository, of course, or you can | ||
4122 | specify it with the global -d option. It works for non-branch tagging, | ||
4123 | too, but it's less useful that way because you have to specify each | ||
4124 | file's revision number, one by one. (Or you can refer to it by tag, but | ||
4125 | then you'd obviously already have a tag there, so why would you want to | ||
4126 | set a second one on the exact same revisions?) | ||
4127 | |||
4128 | <p>You now know enough to get around in CVS and probably enough to start | ||
4129 | working with other people on a project. There are still a few minor | ||
4130 | features that haven't been introduced, as well as some unmentioned but | ||
4131 | useful options to features already seen. These will all be presented as | ||
4132 | appropriate in chapters to come, in scenarios that will demonstrate both | ||
4133 | how and why to use them. When in doubt, don't hesitate to consult the | ||
4134 | Cederqvist manual; it is an indispensable resource for serious CVS | ||
4135 | users. | ||
4136 | |||
4137 | <p><hr> | ||
4138 | Node:<a name="Repository_Administration">Repository Administration</a>, | ||
4139 | Next:<a rel=next href="#Advanced_CVS">Advanced CVS</a>, | ||
4140 | Previous:<a rel=previous href="#An_Overview_of_CVS">An Overview of CVS</a>, | ||
4141 | Up:<a rel=up href="#Top">Top</a> | ||
4142 | <br> | ||
4143 | |||
4144 | <h1>Repository Administration</h1> | ||
4145 | |||
4146 | <p>In <a href="#An_Overview_of_CVS">An Overview of CVS</a>, you learned enough CVS to use it | ||
4147 | effectively as a project participant. If you're going to be a project | ||
4148 | maintainer, however, you'll need to know how to install CVS and | ||
4149 | administer repositories. In this chapter, we'll throw back the curtain | ||
4150 | and look in detail at how the repository is structured, and how CVS uses | ||
4151 | it. You'll learn all the major steps CVS goes through during updates | ||
4152 | and commits, and how you can modify its behavior. By understanding how | ||
4153 | CVS works, you'll also be able to trace problems to their causes, and | ||
4154 | fix them in maintainable ways. | ||
4155 | |||
4156 | <p>This may sound very involved, but remember that CVS has already proven | ||
4157 | quite long-lived, and will probably be around for many years to come. | ||
4158 | Whatever you learn now will be useful for a long time. CVS also tends | ||
4159 | to become more indispensable the more you use it. If you're going to be | ||
4160 | that dependent on something (and trust me, you are), it's worth really | ||
4161 | getting to know it. | ||
4162 | |||
4163 | <p>With that in mind, let's begin at the beginning: putting CVS on your | ||
4164 | system. | ||
4165 | |||
4166 | <ul> | ||
4167 | <li><a href="#Getting_And_Installing_CVS">Getting And Installing CVS</a>: Putting CVS on your system. | ||
4168 | <li><a href="#Anatomy_Of_A_CVS_Distribution">Anatomy Of A CVS Distribution</a>: What's in the CVS distribution. | ||
4169 | <li><a href="#Starting_A_Repository">Starting A Repository</a>: Setting up a repository. | ||
4170 | <li><a href="#The_Password-Authenticating_Server">The Password-Authenticating Server</a>: One method of remote access. | ||
4171 | <li><a href="#Anonymous_Access">Anonymous Access</a>: Granting access to the public. | ||
4172 | <li><a href="#Repository_Structure">Repository Structure</a>: How the repository is arranged. | ||
4173 | <li><a href="#RCS_Format">RCS Format</a>: How repository storage works. | ||
4174 | <li><a href="#What_Happens_When_You_Remove_A_File">What Happens When You Remove A File</a>: CVS keeps an Attic for old files. | ||
4175 | <li><a href="#The_CVSROOT__Administrative_Directory">The CVSROOT/ Administrative Directory</a>: Run-time server configuration files. | ||
4176 | <li><a href="#Commit_Emails">Commit Emails</a>: Arranging automatic commit notices. | ||
4177 | <li><a href="#Finding_Out_More">Finding Out More</a>: Other sources of information. | ||
4178 | </ul> | ||
4179 | |||
4180 | <p><hr> | ||
4181 | Node:<a name="Getting_And_Installing_CVS">Getting And Installing CVS</a>, | ||
4182 | Next:<a rel=next href="#Anatomy_Of_A_CVS_Distribution">Anatomy Of A CVS Distribution</a>, | ||
4183 | Up:<a rel=up href="#Repository_Administration">Repository Administration</a> | ||
4184 | <br> | ||
4185 | |||
4186 | <h2>Getting And Installing CVS</h2> | ||
4187 | |||
4188 | <p>In many cases, you won't have to go out and get CVS, because it will | ||
4189 | already be on your system. If you run one of the major Linux or FreeBSD | ||
4190 | distributions, it's probably already installed in /usr/bin or some other | ||
4191 | likely location. If not, Red Hat Linux users can usually find an RPM | ||
4192 | (Red Hat Package) for the latest, or nearly latest, version of CVS in | ||
4193 | their distributions. And Debian users can install the latest Debian | ||
4194 | package with these commands: | ||
4195 | |||
4196 | <pre>floss$ apt-get update | ||
4197 | floss$ apt-get install cvs | ||
4198 | </pre> | ||
4199 | |||
4200 | <p>If CVS isn't already on your machine, you'll probably have to build it | ||
4201 | from source. If you're a non-Unix user, you'll probably find it easier | ||
4202 | to get a prebuilt binary for your operating system (more on that later). | ||
4203 | Fortunately, CVS is fully <dfn>autoconfiscated</dfn> - that is, it uses the | ||
4204 | GNU autoconfiguration mechanism, making compilation from source | ||
4205 | surprisingly easy. | ||
4206 | |||
4207 | <ul> | ||
4208 | <li><a href="#Getting_And_Building_CVS_Under_Unix">Getting And Building CVS Under Unix</a>: | ||
4209 | <li><a href="#Getting_And_Installing_CVS_Under_Windows">Getting And Installing CVS Under Windows</a>: | ||
4210 | <li><a href="#Getting_And_Installing_CVS_On_A_Macintosh">Getting And Installing CVS On A Macintosh</a>: | ||
4211 | <li><a href="#Limitations_Of_The_Windows_And_Macintosh_Versions">Limitations Of The Windows And Macintosh Versions</a>: | ||
4212 | </ul> | ||
4213 | |||
4214 | <p><hr> | ||
4215 | Node:<a name="Getting_And_Building_CVS_Under_Unix">Getting And Building CVS Under Unix</a>, | ||
4216 | Next:<a rel=next href="#Getting_And_Installing_CVS_Under_Windows">Getting And Installing CVS Under Windows</a>, | ||
4217 | Up:<a rel=up href="#Getting_And_Installing_CVS">Getting And Installing CVS</a> | ||
4218 | <br> | ||
4219 | |||
4220 | <h3>Getting And Building CVS Under Unix</h3> | ||
4221 | |||
4222 | <p>As of this writing, there are two canonical sites from which you can | ||
4223 | download CVS. One is the Free Software Foundation's FTP site, | ||
4224 | <a href="ftp://ftp.gnu.org/gnu/cvs/">ftp://ftp.gnu.org/gnu/cvs/</a>, which offers CVS as an official GNU | ||
4225 | tool. The other is Cyclic Software's download site. Cyclic Software | ||
4226 | is, if not the maintainer of CVS, then the "maintainer of the | ||
4227 | maintainers", by providing a repository server and download access for | ||
4228 | users and developers. They distribute releases from | ||
4229 | <a href="http://download.cyclic.com/pub/">http://download.cyclic.com/pub/</a>. | ||
4230 | |||
4231 | <p>Either location is fine. In the following example, I use Cyclic | ||
4232 | Software's site. If you point your FTP client (probably your Web | ||
4233 | browser) there, you'll see a list of directories, something like this: | ||
4234 | |||
4235 | <pre>Index of /pub | ||
4236 | cvs-1.10.5/ 18-Feb-99 21:36 - | ||
4237 | cvs-1.10.6/ 17-May-99 10:34 - | ||
4238 | cvs-1.10/ 09-Dec-98 17:26 - | ||
4239 | macintosh/ 23-Feb-99 00:53 - | ||
4240 | os2/ 09-Dec-98 17:26 - | ||
4241 | packages/ 09-Dec-98 17:26 - | ||
4242 | rcs/ 09-Dec-98 17:26 - | ||
4243 | tkcvs/ 09-Dec-98 17:26 - | ||
4244 | training/ 09-Dec-98 17:26 - | ||
4245 | unix/ 09-Dec-98 17:26 - | ||
4246 | vms/ 09-Dec-98 17:26 - | ||
4247 | </pre> | ||
4248 | |||
4249 | <p>Pay attention to the directories beginning with "cvs-" (you can ignore | ||
4250 | most of the others). There are three such directories, which means that | ||
4251 | you're already faced with a choice: Get the designated "stable" release, | ||
4252 | or go with a newer (but less-tested) interim release. The stable | ||
4253 | releases have only one decimal point, as in "cvs-1.10", whereas the | ||
4254 | interim releases have minor version increments tacked on the end, as in | ||
4255 | "1.10.5". | ||
4256 | |||
4257 | <p>The GNU site usually only offers the major releases, not the interim | ||
4258 | ones, so you won't see all of this if you get CVS from there. In | ||
4259 | general, the interim releases have been pretty safe, and sometimes | ||
4260 | contain fixes to bugs that were found in the major release. Your best | ||
4261 | policy is to go with the highest interim release, but if you encounter | ||
4262 | any problems with it, be prepared to drop back to the previous release, | ||
4263 | as many times as necessary. The highest release listed in the earlier | ||
4264 | example is cvs-1.10.6. Entering that directory, we see this: | ||
4265 | |||
4266 | <pre>Index of /pub/cvs-1.10.6 | ||
4267 | cvs-1.10.6.tar.gz 17-May-99 08:44 2.2M | ||
4268 | </pre> | ||
4269 | |||
4270 | <p>That's it - the full source code to CVS. Just download it to your | ||
4271 | machine, and you're ready to build. At this point, if you're already | ||
4272 | familiar with the standard build process for GNU tools, you know what to | ||
4273 | do and probably don't need to read anything between here and the section | ||
4274 | <a href="#Anatomy_Of_A_CVS_Distribution">Anatomy Of A CVS Distribution</a>. On the other hand, if you're not | ||
4275 | sure how to proceed, then read on.... | ||
4276 | |||
4277 | <p>The following compilation instructions and examples assume that you have | ||
4278 | a fairly standard distribution of Unix. Any of the free versions of | ||
4279 | Unix (for example, FreeBSD or Linux) should work with no problem, as | ||
4280 | should the major commercial Unix versions (such as SunOS/Solaris, AIX, | ||
4281 | HP-UX, or Ultrix). Even if these instructions don't work for you | ||
4282 | exactly as written, don't give up hope. Although covering the details | ||
4283 | of compiling on every operating system is beyond the scope of this book, | ||
4284 | I'll give some pointers to other help resources later in this chapter. | ||
4285 | |||
4286 | <p>Anyway, to proceed with the compilation, first unpack the tar file using | ||
4287 | GNU gunzip and tar (if you don't have these installed on your system, | ||
4288 | you can get gunzip from <a href="ftp://ftp.gnu.org/gnu/gzip/">ftp://ftp.gnu.org/gnu/gzip/</a> and GNU's | ||
4289 | version of tar from <a href="ftp://ftp.gnu.org/gnu/tar/">ftp://ftp.gnu.org/gnu/tar/</a>): | ||
4290 | |||
4291 | <pre>floss$ gunzip cvs-1.10.6.tar.gz | ||
4292 | floss$ tar xvf cvs-1.10.6.tar | ||
4293 | </pre> | ||
4294 | |||
4295 | <p>You'll see a lot of file names fly by on your screen. | ||
4296 | |||
4297 | <p>Now you have a new directory on your machine - cvs-1.10.6 - and it is | ||
4298 | populated with the CVS source code. Go into that directory and | ||
4299 | configure CVS for your system, by using the provided configure script: | ||
4300 | |||
4301 | <pre>floss$ cd cvs-1.10.6 | ||
4302 | floss$ ./configure | ||
4303 | creating cache ./config.cache | ||
4304 | checking for gcc... gcc | ||
4305 | checking whether we are using GNU C... yes | ||
4306 | checking whether gcc accepts -g... yes | ||
4307 | checking how to run the C preprocessor... gcc -E | ||
4308 | (etc) | ||
4309 | </pre> | ||
4310 | |||
4311 | <p>When the configure command finishes, the source tree will know | ||
4312 | everything it needs to know about compiling on your machine. The next | ||
4313 | step is to type: | ||
4314 | |||
4315 | <pre>floss$ make | ||
4316 | </pre> | ||
4317 | |||
4318 | <p>You'll see lots of output fly by, then type: | ||
4319 | |||
4320 | <pre>floss$ make install | ||
4321 | </pre> | ||
4322 | |||
4323 | <p>You'll see yet more output fly by; when it's all over, CVS will be | ||
4324 | installed on your system. (You will probably need to do that last step | ||
4325 | as the superuser.) | ||
4326 | |||
4327 | <p>By default, the CVS executable will end up as <code>/usr/local/bin/cvs</code>. | ||
4328 | This assumes you have a decent make program installed on your system | ||
4329 | (again, if you don't have one, get the GNU project's make from | ||
4330 | <a href="ftp://ftp.gnu.org/gnu/make/">ftp://ftp.gnu.org/gnu/make/</a>). | ||
4331 | |||
4332 | <p>If you want CVS to install to a location other than /usr/local/bin, you | ||
4333 | should change how you run the initial configuration step. For example, | ||
4334 | |||
4335 | <pre>floss$ ./configure --prefix=/usr | ||
4336 | </pre> | ||
4337 | |||
4338 | <p>results in CVS being installed as /usr/bin/cvs (it always ends up as | ||
4339 | PREFIX/bin/cvs). The default prefix is /usr/local, which is fine for | ||
4340 | most installations. | ||
4341 | |||
4342 | <p>Note To Experienced Users: Although older versions of CVS consisted of | ||
4343 | more than just an executable in that they depended on having RCS | ||
4344 | installed as well, this has not been the case since Version 1.10. | ||
4345 | Therefore, you don't need to worry about any libraries or executables | ||
4346 | other than cvs itself. | ||
4347 | |||
4348 | <p>If you just intend to use CVS to access remote repositories, the | ||
4349 | preceding is all you need to do. If you also plan to serve a repository | ||
4350 | from this system, a few additional steps are necessary, which are | ||
4351 | covered later in this chapter. | ||
4352 | |||
4353 | <p><hr> | ||
4354 | Node:<a name="Getting_And_Installing_CVS_Under_Windows">Getting And Installing CVS Under Windows</a>, | ||
4355 | Next:<a rel=next href="#Getting_And_Installing_CVS_On_A_Macintosh">Getting And Installing CVS On A Macintosh</a>, | ||
4356 | Previous:<a rel=previous href="#Getting_And_Building_CVS_Under_Unix">Getting And Building CVS Under Unix</a>, | ||
4357 | Up:<a rel=up href="#Getting_And_Installing_CVS">Getting And Installing CVS</a> | ||
4358 | <br> | ||
4359 | |||
4360 | <h3>Getting And Installing CVS Under Windows</h3> | ||
4361 | |||
4362 | <p>Unless you're truly religious about having the source code to your | ||
4363 | executable, you don't need to compile CVS from source on your Windows | ||
4364 | box. Unlike Unix, the necessary compilation tools probably do not | ||
4365 | already exist on your system, so a source build would involve first | ||
4366 | going out and getting those tools. Because such a project is beyond the | ||
4367 | scope of this book, I'll just give instructions for getting a | ||
4368 | precompiled CVS binary. | ||
4369 | |||
4370 | <p>First, note that Windows binary distributions of CVS are usually made | ||
4371 | only for major releases of CVS - not for the interim releases - and | ||
4372 | are not found on the GNU FTP site. So you'll need to go to Cyclic | ||
4373 | Software's download site, where in the major version directory, | ||
4374 | <a href="http://download.cyclic.com/pub/cvs-1.10/">http://download.cyclic.com/pub/cvs-1.10/</a>, you'll see an extra | ||
4375 | subdirectory | ||
4376 | |||
4377 | <pre>Index of /pub/cvs-1.10 | ||
4378 | cvs-1.10.tar.gz 14-Aug-98 09:35 2.4M | ||
4379 | windows/ | ||
4380 | </pre> | ||
4381 | |||
4382 | <p>inside of which is a ZIP file: | ||
4383 | |||
4384 | <pre>Index of /pub/cvs-1.10/windows | ||
4385 | cvs-1.10-win.zip 14-Aug-98 10:10 589k | ||
4386 | </pre> | ||
4387 | |||
4388 | <p>This ZIP file contains a binary distribution of CVS. Download and | ||
4389 | extract that ZIP file: | ||
4390 | |||
4391 | <pre>floss$ unzip cvs-1.10-win.zip | ||
4392 | |||
4393 | Archive: cvs-1.10-win.zip | ||
4394 | inflating: cvs.html | ||
4395 | inflating: cvs.exe | ||
4396 | inflating: README | ||
4397 | inflating: FAQ | ||
4398 | inflating: NEWS | ||
4399 | inflating: patch.exe | ||
4400 | inflating: win32gnu.dll | ||
4401 | </pre> | ||
4402 | |||
4403 | <p>The README there contains detailed instructions. For most | ||
4404 | installations, they can be summarized as follows: Put all of the EXE and | ||
4405 | DLL files in a directory in your PATH. Additionally, if you're going to | ||
4406 | be using the pserver method to access a remote repository, you may need | ||
4407 | to put the following in your <code>C:\AUTOEXEC.BAT</code> file and reboot: | ||
4408 | |||
4409 | <pre>set HOME=C: | ||
4410 | </pre> | ||
4411 | |||
4412 | <p>This tells CVS where to store the .cvspass file. | ||
4413 | |||
4414 | <p>CVS running under Windows cannot currently serve repositories to remote | ||
4415 | machines; it can be a client (connecting to remote repositories), and | ||
4416 | operate in local mode (using a repository on the same machine). For the | ||
4417 | most part, this book assumes that CVS under Windows is operating as a | ||
4418 | client. However, it shouldn't be too hard to set up a local repository | ||
4419 | under Windows after reading the Unix-oriented instructions in the rest | ||
4420 | of this chapter. | ||
4421 | |||
4422 | <p>If you are only accessing remote repositories, you may not even need to | ||
4423 | run CVS. There is a tool called WinCvs that implements only the | ||
4424 | client-side portion of CVS. It is distributed separately from CVS | ||
4425 | itself but, like CVS, is freely available under the GNU General Public | ||
4426 | License. More information is available from <a href="http://www.wincvs.org">http://www.wincvs.org</a>. | ||
4427 | |||
4428 | <p><hr> | ||
4429 | Node:<a name="Getting_And_Installing_CVS_On_A_Macintosh">Getting And Installing CVS On A Macintosh</a>, | ||
4430 | Next:<a rel=next href="#Limitations_Of_The_Windows_And_Macintosh_Versions">Limitations Of The Windows And Macintosh Versions</a>, | ||
4431 | Previous:<a rel=previous href="#Getting_And_Installing_CVS_Under_Windows">Getting And Installing CVS Under Windows</a>, | ||
4432 | Up:<a rel=up href="#Getting_And_Installing_CVS">Getting And Installing CVS</a> | ||
4433 | <br> | ||
4434 | |||
4435 | <h3>Getting And Installing CVS On A Macintosh</h3> | ||
4436 | |||
4437 | <p>CVS is available for the Macintosh, but not as part of the main | ||
4438 | distribution. At the moment, there are actually three separate | ||
4439 | Macintosh CVS clients available: | ||
4440 | |||
4441 | <ul> | ||
4442 | <li>MacCvs - <a href="http://www.wincvs.org">http://www.wincvs.org</a> | ||
4443 | <li>MacCVSClient - <a href="http://www.glink.net.hk/~jb/MacCVSClient">http://www.glink.net.hk/~jb/MacCVSClient</a> | ||
4444 | or <a href="http://www.cyclic.com/maccvsclient/">http://www.cyclic.com/maccvsclient/</a> | ||
4445 | <li>MacCVS Pro - <a href="http://www.maccvs.org">http://www.maccvs.org</a> | ||
4446 | </ul> | ||
4447 | |||
4448 | <p>Frankly, I have no idea which one is best. Try them all, not | ||
4449 | necessarily in the order given, and see which one you like. MacCVS Pro | ||
4450 | seems to be under active development. MacCvs is apparently a companion | ||
4451 | project of WinCVS and shares a home page with it. (As of this writing, a | ||
4452 | notice on the WinCVS page states, "Development of MacCvs will be resumed | ||
4453 | soon.", whatever that means.) | ||
4454 | |||
4455 | <p><hr> | ||
4456 | Node:<a name="Limitations_Of_The_Windows_And_Macintosh_Versions">Limitations Of The Windows And Macintosh Versions</a>, | ||
4457 | Previous:<a rel=previous href="#Getting_And_Installing_CVS_On_A_Macintosh">Getting And Installing CVS On A Macintosh</a>, | ||
4458 | Up:<a rel=up href="#Getting_And_Installing_CVS">Getting And Installing CVS</a> | ||
4459 | <br> | ||
4460 | |||
4461 | <h3>Limitations Of The Windows And Macintosh Versions</h3> | ||
4462 | |||
4463 | <p>The Windows and Macintosh distributions of CVS are generally limited in | ||
4464 | functionality. They can all act as clients, meaning that they can | ||
4465 | contact a repository server to obtain a working copy, commit, update, | ||
4466 | and so on. But they can't serve repositories themselves. If you set it | ||
4467 | up right, the Windows port can use a local-disk repository, but it still | ||
4468 | can't serve projects from that repository to other machines. In | ||
4469 | general, if you want to have a network-accessible CVS repository, you | ||
4470 | must run the CVS server on a Unix box. | ||
4471 | |||
4472 | <p><hr> | ||
4473 | Node:<a name="Anatomy_Of_A_CVS_Distribution">Anatomy Of A CVS Distribution</a>, | ||
4474 | Next:<a rel=next href="#Starting_A_Repository">Starting A Repository</a>, | ||
4475 | Previous:<a rel=previous href="#Getting_And_Installing_CVS">Getting And Installing CVS</a>, | ||
4476 | Up:<a rel=up href="#Repository_Administration">Repository Administration</a> | ||
4477 | <br> | ||
4478 | |||
4479 | <h2>Anatomy Of A CVS Distribution</h2> | ||
4480 | |||
4481 | <p>The preceding instructions are designed to get you up and running | ||
4482 | quickly, but there's a lot more inside a CVS source distribution than | ||
4483 | just the code. Here's a quick road map to the source tree, so you'll | ||
4484 | know which parts are useful resources and which can be ignored. | ||
4485 | |||
4486 | <ul> | ||
4487 | <li><a href="#Informational_Files">Informational Files</a>: NEWS, BUGS, FAQ, etc. | ||
4488 | <li><a href="#Subdirectories">Subdirectories</a>: How the distribution is laid out. | ||
4489 | <li><a href="#The_Cederqvist_Manual">The Cederqvist Manual</a>: The CVS Online Manual. | ||
4490 | <li><a href="#Other_Sources_Of_Information">Other Sources Of Information</a>: Where else to find help. | ||
4491 | </ul> | ||
4492 | |||
4493 | <p><hr> | ||
4494 | Node:<a name="Informational_Files">Informational Files</a>, | ||
4495 | Next:<a rel=next href="#Subdirectories">Subdirectories</a>, | ||
4496 | Up:<a rel=up href="#Anatomy_Of_A_CVS_Distribution">Anatomy Of A CVS Distribution</a> | ||
4497 | <br> | ||
4498 | |||
4499 | <h3>Informational Files</h3> | ||
4500 | |||
4501 | <p>In the top level of the distribution tree, you'll find several files | ||
4502 | containing useful information (and pointers to further information). | ||
4503 | They are, in approximate order of importance: | ||
4504 | |||
4505 | <ul> | ||
4506 | |||
4507 | <li><code>NEWS</code> - This file lists the changes from one release to the next, | ||
4508 | in reverse chronological order (that is, most recent first). If you've | ||
4509 | already been using CVS for a while and have just upgraded to a new | ||
4510 | version, you should look at the NEWS file to see what new features are | ||
4511 | available. Also, although most changes to CVS preserve backward | ||
4512 | compatibility, noncompatible changes do occur from time to time. It's | ||
4513 | better to read about them here than be surprised when CVS doesn't behave | ||
4514 | the way you expect it to. | ||
4515 | |||
4516 | <li><code>BUGS</code> - This file contains exactly what you think it does: a list | ||
4517 | of known bugs in CVS. They usually aren't show-stoppers, but you should | ||
4518 | read over them whenever you install a new release. | ||
4519 | |||
4520 | <li><code>DEVEL-CVS</code> - This file is the CVS "constitution". It describes | ||
4521 | the process by which changes are accepted into the main CVS distribution | ||
4522 | and the procedures through which a person becomes a CVS developer. You | ||
4523 | don't really need to read it if you just want to use CVS; however, it's | ||
4524 | highly interesting if you want to understand how the mostly | ||
4525 | uncoordinated efforts of people scattered across the globe coalesce into | ||
4526 | a working, usable piece of software. And of course, it's required | ||
4527 | reading if you plan to submit a patch (be it a bug fix or new feature) | ||
4528 | to CVS. | ||
4529 | |||
4530 | <li><code>HACKING</code> - Despite its name, the HACKING file doesn't say much | ||
4531 | about the design or implementation of CVS. It's mainly a guide to | ||
4532 | coding standards and other technical administrivia for people thinking | ||
4533 | of writing a patch to CVS. It can be thought of as an addendum to the | ||
4534 | DEVEL-CVS file. After you understand the basic philosophy of CVS | ||
4535 | development, you must read the HACKING file to translate that into | ||
4536 | concrete coding practices. | ||
4537 | |||
4538 | <li><code>FAQ</code> - This is the CVS "Frequently Asked Questions" document. | ||
4539 | Unfortunately it has a rather spotty maintenance history. David Grubbs | ||
4540 | took care of it until 1995, then he (presumably) got too busy and it | ||
4541 | languished for a while. Eventually, in 1997, Pascal Molli took over | ||
4542 | maintenance. Molli also didn't have time to maintain it by hand, but at | ||
4543 | least he found time to put it into his automated FAQ-O-Matic system, | ||
4544 | which allows the public to maintain the FAQ in a decentralized manner | ||
4545 | (basically, anyone can edit or add entries via a Web form). This was | ||
4546 | probably a good thing, in that at least the FAQ was once again being | ||
4547 | maintained; however, its overall organization and quality control are | ||
4548 | not on the same level as if a person were maintaining it. | ||
4549 | |||
4550 | <p>The master version of the FAQ is always available from Molli's Web site | ||
4551 | (<a href="http://www.loria.fr/~molli/cvs-index.html">http://www.loria.fr/~molli/cvs-index.html</a>, under the link | ||
4552 | "Documentation"). The FAQ file shipped with CVS distributions is | ||
4553 | generated automatically from that FAQ-O-Matic database, so by the time | ||
4554 | it reaches the public it's already a little bit out of date. | ||
4555 | Nevertheless, it can be quite helpful when you're looking for hints and | ||
4556 | examples about how to do something specific (say, merging a large branch | ||
4557 | back into the trunk or resurrecting a removed file). The best way to | ||
4558 | use it is as a reference document; you can bring it up in your favorite | ||
4559 | editor and do text searches on terms that interest you. Trying to use | ||
4560 | it as a tutorial would be a mistake - it's missing too many important | ||
4561 | facts about CVS to serve as a complete guide. | ||
4562 | |||
4563 | </ul> | ||
4564 | |||
4565 | <p><hr> | ||
4566 | Node:<a name="Subdirectories">Subdirectories</a>, | ||
4567 | Next:<a rel=next href="#The_Cederqvist_Manual">The Cederqvist Manual</a>, | ||
4568 | Previous:<a rel=previous href="#Informational_Files">Informational Files</a>, | ||
4569 | Up:<a rel=up href="#Anatomy_Of_A_CVS_Distribution">Anatomy Of A CVS Distribution</a> | ||
4570 | <br> | ||
4571 | |||
4572 | <h3>Subdirectories</h3> | ||
4573 | |||
4574 | <p>The CVS distribution contains a number of subdirectories. In the course | ||
4575 | of a normal installation, you won't have to navigate among them, but if | ||
4576 | you want to go poking around in the sources, it's nice to know what each | ||
4577 | one does. Here they are: | ||
4578 | |||
4579 | <pre>contrib/ | ||
4580 | diff/ | ||
4581 | doc/ | ||
4582 | emx/ | ||
4583 | lib/ | ||
4584 | man/ | ||
4585 | os2/ | ||
4586 | src/ | ||
4587 | tools/ | ||
4588 | vms/ | ||
4589 | windows-NT/ | ||
4590 | zlib/ | ||
4591 | </pre> | ||
4592 | |||
4593 | <p>The majority of these can be ignored. The emx/, os2/, vms/, and | ||
4594 | windows-NT/ subdirectories all contain operating-system-specific source | ||
4595 | code, which you would only need if you're actually trying to debug a | ||
4596 | code-level problem in CVS (an unlikely situation, though not unheard | ||
4597 | of). The diff/ and zlib/ subdirectories contain CVS's internal | ||
4598 | implementations of the diff program and the GNU gzip compression | ||
4599 | library, respectively. (CVS uses the latter to reduce the number of bits | ||
4600 | it has to send over the network when accessing remote repositories.) | ||
4601 | |||
4602 | <p>The contrib/ and tools/ subdirectories contain free third-party software | ||
4603 | meant to be used with CVS. In contrib/, you will find an assortment of | ||
4604 | small, specialized shell scripts (read contrib/README to find out what | ||
4605 | they do). The tools/ subdirectory used to contain contributed software, | ||
4606 | but now contains a README file, which says in part: | ||
4607 | |||
4608 | <pre>This subdirectory formerly contained tools that can be used with CVS. | ||
4609 | In particular, it used to contain a copy of pcl-cvs version 1.x. | ||
4610 | Pcl-cvs is an Emacs interface to CVS. | ||
4611 | |||
4612 | If you are looking for pcl-cvs, we'd suggest pcl-cvs version 2.x, at: | ||
4613 | ftp://ftp.weird.com/pub/local/ | ||
4614 | </pre> | ||
4615 | |||
4616 | <p>The PCL-CVS package it's referring to is very handy, and I'll have more | ||
4617 | to say about it in <a href="#Third-Party_Tools">Third-Party Tools</a>. | ||
4618 | |||
4619 | <p>The src/ and lib/ subdirectories contain the bulk of the CVS source | ||
4620 | code, which involves the CVS internals. The main data structures and | ||
4621 | commands are implemented in src/, whereas lib/ contains small code | ||
4622 | modules of general utility that CVS uses. | ||
4623 | |||
4624 | <p>The man/ subdirectory contains the CVS man pages (intended for the Unix | ||
4625 | online manual system). When you ran make install, they were | ||
4626 | incorporated into your Unix system's regular man pages, so you can type | ||
4627 | |||
4628 | <pre>floss$ man cvs | ||
4629 | </pre> | ||
4630 | |||
4631 | <p>and get a rather terse introduction and subcommand reference to CVS. | ||
4632 | Although useful as a quick reference, the man pages may not be as up to | ||
4633 | date or complete as the Cederqvist manual (see the next section); | ||
4634 | however, the man pages are more likely to be incomplete than actually | ||
4635 | wrong, if it's any comfort. | ||
4636 | |||
4637 | <p><hr> | ||
4638 | Node:<a name="The_Cederqvist_Manual">The Cederqvist Manual</a>, | ||
4639 | Next:<a rel=next href="#Other_Sources_Of_Information">Other Sources Of Information</a>, | ||
4640 | Previous:<a rel=previous href="#Subdirectories">Subdirectories</a>, | ||
4641 | Up:<a rel=up href="#Anatomy_Of_A_CVS_Distribution">Anatomy Of A CVS Distribution</a> | ||
4642 | <br> | ||
4643 | |||
4644 | <h3>The Cederqvist Manual</h3> | ||
4645 | |||
4646 | <p>That leaves the doc/ subdirectory, whose most important inhabitant is | ||
4647 | the famed <dfn>Cederqvist</dfn>. These days, it's probably a stretch to call | ||
4648 | it "the Cederqvist". Although Per Cederqvist (of Signum Support, | ||
4649 | Linkoping Sweden, www.signum.se) wrote the first version around 1992, it | ||
4650 | has been updated since then by many other people. For example, when | ||
4651 | contributors add a new feature to CVS, they usually also document it in | ||
4652 | the Cederqvist. | ||
4653 | |||
4654 | <p>The Cederqvist manual is written in Texinfo format, which is used by the | ||
4655 | GNU project because it's relatively easy to produce both online and | ||
4656 | printed output from it (in Info and PostScript formats, respectively). | ||
4657 | The Texinfo master file is doc/cvs.texinfo, but CVS distributions come | ||
4658 | with the Info and PostScript pregenerated, so you don't have to worry | ||
4659 | about running any Texinfo tools yourself. | ||
4660 | |||
4661 | <p>Although the Cederqvist can be used as an introduction and tutorial, it | ||
4662 | is probably most useful as a reference document. For that reason, most | ||
4663 | people browse it online instead of printing it out (although the | ||
4664 | PostScript file is <code>doc/cvs.ps</code>, for those with paper to spare). | ||
4665 | If this is the first time you've installed CVS on your system, you'll | ||
4666 | have to take an extra step to make sure the manual is accessible online. | ||
4667 | |||
4668 | <p>The Info files (doc/cvs.info, doc/cvs.info-1, doc/cvs.info-2, and so on) | ||
4669 | were installed for you when you ran make install. Although the files | ||
4670 | were copied into the system's Info tree, you may still have to add a | ||
4671 | line for CVS to the Info table of contents, the "Top" node. (This will | ||
4672 | only be necessary if this is the first time CVS has been installed on | ||
4673 | your system; otherwise, the entry from previous installations should | ||
4674 | already be in the table of contents.) | ||
4675 | |||
4676 | <p>If you've added new Info documentation before, you may be familiar with | ||
4677 | the process. First figure out where the Info pages were installed. If | ||
4678 | you used the default installation (in /usr/local/), then the Info files | ||
4679 | are /usr/local/info/cvs.info*. If you installed using | ||
4680 | |||
4681 | <pre>floss$ ./configure --prefix=/usr | ||
4682 | </pre> | ||
4683 | |||
4684 | <p>the files ended up as /usr/info/cvs.*. After you locate the files, | ||
4685 | you'll need to add a line for CVS to the Info table of contents, which | ||
4686 | is in a file named dir in that directory (so in the latter case, it | ||
4687 | would be /usr/info/dir). If you don't have root access, ask your system | ||
4688 | administrator to do it. Here is an excerpt from dir before the | ||
4689 | reference to CVS documentation was added: | ||
4690 | |||
4691 | <pre>* Bison: (bison). The Bison parser generator. | ||
4692 | * Cpp: (cpp). The GNU C preprocessor. | ||
4693 | * Flex: (flex). A fast scanner generator | ||
4694 | </pre> | ||
4695 | |||
4696 | <p>And here is the same region of dir afterwards: | ||
4697 | |||
4698 | <pre>* Bison: (bison). The Bison parser generator. | ||
4699 | * Cpp: (cpp). The GNU C preprocessor. | ||
4700 | * Cvs: (cvs). Concurrent Versions System | ||
4701 | * Flex: (flex). A fast scanner generator | ||
4702 | </pre> | ||
4703 | |||
4704 | <p>The format of the line is very important. You must include the | ||
4705 | asterisk, spaces, and colon in <code>* Cvs:</code> and the parentheses and | ||
4706 | period in <code>(cvs).</code> after it. If any of these elements are missing, | ||
4707 | the Info dir format will be corrupt, and you'll be unable to read the | ||
4708 | Cederqvist. | ||
4709 | |||
4710 | <p>Once the manual is installed and referred to from the table of contents, | ||
4711 | you can read it with any Info-compatible browser. The ones most likely | ||
4712 | to be installed on a typical Unix system are either the command-line | ||
4713 | Info reader, which can be invoked this way if you want to go straight to | ||
4714 | the CVS pages | ||
4715 | |||
4716 | <pre>floss$ info cvs | ||
4717 | </pre> | ||
4718 | |||
4719 | <p>and the one within Emacs, which is invoked by typing | ||
4720 | |||
4721 | <pre>M-x info | ||
4722 | </pre> | ||
4723 | |||
4724 | <p>or | ||
4725 | |||
4726 | <pre>C-h i | ||
4727 | </pre> | ||
4728 | |||
4729 | <p>Take whatever time is necessary to get the Cederqvist set up properly on | ||
4730 | your system when you install CVS; it will pay off many times down the | ||
4731 | road when you need to look something up. | ||
4732 | |||
4733 | <p><hr> | ||
4734 | Node:<a name="Other_Sources_Of_Information">Other Sources Of Information</a>, | ||
4735 | Previous:<a rel=previous href="#The_Cederqvist_Manual">The Cederqvist Manual</a>, | ||
4736 | Up:<a rel=up href="#Anatomy_Of_A_CVS_Distribution">Anatomy Of A CVS Distribution</a> | ||
4737 | <br> | ||
4738 | |||
4739 | <h3>Other Sources Of Information</h3> | ||
4740 | |||
4741 | <p>In addition to the Cederqvist, the FAQ, and the other files in the | ||
4742 | distribution itself, there are Internet resources devoted to CVS. If | ||
4743 | you're going to administrate a CVS server, you'll probably want to join | ||
4744 | the info-cvs mailing list. To subscribe, send email to | ||
4745 | <a href="mailto:info-cvs-request@gnu.org">info-cvs-request@gnu.org</a> (the list itself is | ||
4746 | <a href="mailto:info-cvs@gnu.org">info-cvs@gnu.org</a>). Traffic can be medium to heavy, around 10 | ||
4747 | to 20 emails a day, most of them questions seeking answers. The | ||
4748 | majority of these can be deleted without reading (unless you want to | ||
4749 | help people by answering their questions, which is always nice), but | ||
4750 | every now and then someone will announce the discovery of a bug or | ||
4751 | announce a patch that implements some feature you've been wanting. | ||
4752 | |||
4753 | <p>You can also join the formal bug report mailing list, which includes | ||
4754 | every bug report sent in. This probably isn't necessary, unless you | ||
4755 | intend to help fix the bugs, which would be great, or you're | ||
4756 | terrifically paranoid and want to know about every problem other people | ||
4757 | find with CVS. If you do want to join, send email to | ||
4758 | <a href="mailto:bug-cvs-request@gnu.org">bug-cvs-request@gnu.org</a>. | ||
4759 | |||
4760 | <p>There's also a Usenet newsgroup, <code>comp.software.config-mgmt</code>, which | ||
4761 | is about version control and configuration management systems in | ||
4762 | general, in which there is a fair amount of discussion about CVS. | ||
4763 | |||
4764 | <p>Finally, there are at least three Web sites devoted to CVS. Cyclic | ||
4765 | Software's <a href="http://www.cyclic.com">http://www.cyclic.com</a> has been CVS's informal home | ||
4766 | site for a few years, and probably will continue to be for the | ||
4767 | foreseeable future. Cyclic Software also provides server space and Net | ||
4768 | access for the repository where the CVS sources are kept. The Cyclic | ||
4769 | Web pages contain comprehensive links to experimental patches for CVS, | ||
4770 | third-party tools that work with CVS, documentation, mailing list | ||
4771 | archives, and just about everything else. If you can't find what you | ||
4772 | need in the distribution, <a href="http://www.cyclic.com">http://www.cyclic.com</a> is the place to | ||
4773 | start looking. | ||
4774 | |||
4775 | <p>Two other good sites are Pascal Molli's | ||
4776 | <a href="http://www.loria.fr/~molli/cvs-index.html">http://www.loria.fr/~molli/cvs-index.html</a> and Sean Dreilinger's | ||
4777 | <a href="http://durak.org/cvswebsites/">http://durak.org/cvswebsites/</a>. The biggest attraction at Molli's | ||
4778 | site is, of course, the FAQ, but it also has links to CVS-related tools | ||
4779 | and mailing list archives. Dreilinger's site specializes in information | ||
4780 | about using CVS to manage Web documents and also has a CVS-specific | ||
4781 | search engine. | ||
4782 | |||
4783 | <p><hr> | ||
4784 | Node:<a name="Starting_A_Repository">Starting A Repository</a>, | ||
4785 | Next:<a rel=next href="#The_Password-Authenticating_Server">The Password-Authenticating Server</a>, | ||
4786 | Previous:<a rel=previous href="#Anatomy_Of_A_CVS_Distribution">Anatomy Of A CVS Distribution</a>, | ||
4787 | Up:<a rel=up href="#Repository_Administration">Repository Administration</a> | ||
4788 | <br> | ||
4789 | |||
4790 | <h2>Starting A Repository</h2> | ||
4791 | |||
4792 | <p>Once the CVS executable is installed on your system, you can start using | ||
4793 | it right away as a client to access remote repositories, following the | ||
4794 | procedures described in <a href="#An_Overview_of_CVS">An Overview of CVS</a>. However, if you want | ||
4795 | to serve revisions from your machine, you have to create a repository | ||
4796 | there. The command to do that is | ||
4797 | |||
4798 | <pre>floss$ cvs -d /usr/local/newrepos init | ||
4799 | </pre> | ||
4800 | |||
4801 | <p>where <code>/usr/local/newrepos</code> is a path to wherever you want the | ||
4802 | repository to be (of course, you must have write permission to that | ||
4803 | location, which may imply running the command as the root user). It may | ||
4804 | seem somewhat counterintuitive that the location of the new repository | ||
4805 | is specified before the init subcommand instead of after it, but by | ||
4806 | using the -d option, it stays consistent with other CVS commands. | ||
4807 | |||
4808 | <p>The command will return silently after it is run. Let's examine the new | ||
4809 | directory: | ||
4810 | |||
4811 | <pre>floss$ ls -ld /usr/local/newrepos | ||
4812 | drwxrwxr-x 3 root root 1024 Jun 19 17:59 /usr/local/newrepos/ | ||
4813 | floss$ cd /usr/local/newrepos | ||
4814 | floss$ ls | ||
4815 | CVSROOT | ||
4816 | floss$ cd CVSROOT | ||
4817 | floss$ ls | ||
4818 | checkoutlist config,v history notify taginfo,v | ||
4819 | checkoutlist,v cvswrappers loginfo notify,v verifymsg | ||
4820 | commitinfo cvswrappers,v loginfo,v rcsinfo verifymsg,v | ||
4821 | commitinfo,v editinfo modules rcsinfo,v | ||
4822 | config editinfo,v modules,v taginfo | ||
4823 | |||
4824 | floss$ | ||
4825 | </pre> | ||
4826 | |||
4827 | <p>The single subdirectory in the new repository - CVSROOT/ - contains | ||
4828 | various administrative files that control CVS's behavior. Later on, | ||
4829 | we'll examine those files one by one; for now, the goal is just to get | ||
4830 | the repository working. In this case, "working" means users can import, | ||
4831 | check out, update, and commit projects. | ||
4832 | |||
4833 | <p>Don't confuse the CVSROOT environment variable introduced in <a href="#An_Overview_of_CVS">An Overview of CVS</a> with this CVSROOT subdirectory in the repository. They | ||
4834 | are unrelated - it is an unfortunate coincidence that they share the | ||
4835 | same name. The former is a way for users to avoid having to type | ||
4836 | <code>-d <repository-location></code> every time they use CVS; the latter | ||
4837 | is the administrative subdirectory of a repository. | ||
4838 | |||
4839 | <p>Once the repository is created, you must take care of its permissions. | ||
4840 | CVS does not require any particular, standardized permission or file | ||
4841 | ownership scheme; it merely needs write access to the repository. | ||
4842 | However - partly for security reasons, but mainly for your own sanity | ||
4843 | as an administrator - I highly recommend that you take the following | ||
4844 | steps: | ||
4845 | |||
4846 | <ol type=1 start=1> | ||
4847 | |||
4848 | </p><li>Add a Unix group <code>cvs</code> to your system. Any users who need to | ||
4849 | access the repository should be in this group. For example, here's the | ||
4850 | relevant line from my machine's <code>/etc/group</code> file: | ||
4851 | |||
4852 | <pre>cvs:*:105:kfogel,sussman,jimb,noel,lefty,fitz,craig,anonymous,jrandom | ||
4853 | </pre> | ||
4854 | |||
4855 | <li>Make the repository's group ownership and permissions reflect this new | ||
4856 | group: | ||
4857 | |||
4858 | <pre>floss$ cd /usr/local/newrepos | ||
4859 | floss$ chgrp -R cvs . | ||
4860 | floss$ chmod ug+rwx . CVSROOT | ||
4861 | </pre> | ||
4862 | |||
4863 | </ol> | ||
4864 | |||
4865 | <p>Now any of the users listed in that group can start a project by running | ||
4866 | <code>cvs import</code>, as described in <a href="#An_Overview_of_CVS">An Overview of CVS</a>. | ||
4867 | Checkout, update, and commit should work as well. They can also reach | ||
4868 | the repository from remote locations by using the <code>:ext:</code> method, | ||
4869 | assuming that they have rsh or ssh access to the repository | ||
4870 | machine. (You may have noticed that the chgrp and chmod commands in that | ||
4871 | example gave write access to a user named <code>anonymous</code>, which is not | ||
4872 | what one would expect. The reason is that even anonymous, read-only | ||
4873 | repository users need system-level write access, so that their CVS | ||
4874 | processes can create temporary lockfiles inside the repository. CVS | ||
4875 | enforces the "read-only" restriction of anonymous access not through | ||
4876 | Unix file permissions, but by other means, which will be covered in | ||
4877 | <a href="#Anonymous_Access">Anonymous Access</a>.) | ||
4878 | |||
4879 | <p>If your repository is intended to serve projects to the general public, | ||
4880 | where contributors won't necessarily have accounts on the repository | ||
4881 | machine, you should set up the password-authenticating server now | ||
4882 | (see <a href="#The_Password-Authenticating_Server">The Password-Authenticating Server</a>). It's necessary for | ||
4883 | anonymous read-only access, and it's also probably the easiest way to | ||
4884 | grant commit access to certain people without giving them full accounts | ||
4885 | on the machine. | ||
4886 | |||
4887 | <p><hr> | ||
4888 | Node:<a name="The_Password-Authenticating_Server">The Password-Authenticating Server</a>, | ||
4889 | Next:<a rel=next href="#Anonymous_Access">Anonymous Access</a>, | ||
4890 | Previous:<a rel=previous href="#Starting_A_Repository">Starting A Repository</a>, | ||
4891 | Up:<a rel=up href="#Repository_Administration">Repository Administration</a> | ||
4892 | <br> | ||
4893 | |||
4894 | <h2>The Password-Authenticating Server</h2> | ||
4895 | |||
4896 | <p>Before running through the steps needed to set up the password server, | ||
4897 | let's examine how such connections work in the abstract. When a remote | ||
4898 | CVS client uses the <code>:pserver:</code> method to connect to a repository, | ||
4899 | the client is actually contacting a specific port number on the server | ||
4900 | machine - specifically, port number 2401 (which is 49 squared, if you | ||
4901 | like that sort of thing). Port 2401 is the designated default port for | ||
4902 | the CVS pserver, although one could arrange for a different port to be | ||
4903 | used as long as both client and server agree on it. | ||
4904 | |||
4905 | <p>The CVS server is not actually waiting for connections at that port - | ||
4906 | the server won't get started up until a connection actually arrives. | ||
4907 | Instead, the Unix inetd (InterNET Daemon) program is listening on that | ||
4908 | port, and needs to know that when it receives a connection request | ||
4909 | there, it should start up the CVS server and connect it to the incoming | ||
4910 | client. | ||
4911 | |||
4912 | <p>This is accomplished by modifying inetd's configuration files: | ||
4913 | <code>/etc/services</code> and <code>/etc/inetd.conf</code>. The services file maps | ||
4914 | raw port numbers to service names and then inetd.conf tells inetd what | ||
4915 | to do for a given service name. | ||
4916 | |||
4917 | <p>First, put a line like this into /etc/services (after checking to make | ||
4918 | sure it isn't already there): | ||
4919 | |||
4920 | <pre>cvspserver2401/tcp | ||
4921 | </pre> | ||
4922 | |||
4923 | <p>Then in /etc/inetd.conf, put this: | ||
4924 | |||
4925 | <pre>cvspserver stream tcp nowait root /usr/local/bin/cvs cvs \ | ||
4926 | --allow-root=/usr/local/newrepos pserver | ||
4927 | </pre> | ||
4928 | |||
4929 | <p>(In the actual file, this should be all one long line, with no | ||
4930 | backslash.) If your system uses tcpwrappers, you may want to use | ||
4931 | something like this instead: | ||
4932 | |||
4933 | <pre>cvspserver stream tcp nowait root /usr/sbin/tcpd /usr/local/bin/cvs \ | ||
4934 | --allow-root=/usr/local/newrepos pserver | ||
4935 | </pre> | ||
4936 | |||
4937 | <p>Now, restart inetd so it notices the changes to its configuration files | ||
4938 | (if you don't know how to restart the daemon, just reboot the machine - | ||
4939 | that will work too). | ||
4940 | |||
4941 | <p>That's enough to permit connections, but you'll also want to set up | ||
4942 | special CVS passwords - separate from the users' regular login | ||
4943 | passwords - so people can access the repository without compromising | ||
4944 | overall system security. | ||
4945 | |||
4946 | <p>The CVS password file is CVSROOT/passwd in the repository. It was not | ||
4947 | created by default when you ran cvs init, because CVS doesn't know for | ||
4948 | sure that you'll be using pserver. Even if the password file had been | ||
4949 | created, CVS would have no way of knowing what usernames and passwords | ||
4950 | to create. So, you'll have to create one yourself; here's a sample | ||
4951 | CVSRoot/passwd file: | ||
4952 | |||
4953 | <pre>kfogel:rKa5jzULzmhOo | ||
4954 | anonymous:XR4EZcEs0szik | ||
4955 | melissa:tGX1fS8sun6rY:pubcvs | ||
4956 | </pre> | ||
4957 | |||
4958 | <p>The format is as simple as it looks. Each line is: | ||
4959 | |||
4960 | <pre><USERNAME>:<ENCRYPTED_PASSWORD>:<OPTIONAL_SYSTEM_USERNAME> | ||
4961 | </pre> | ||
4962 | |||
4963 | <p>The extra colon followed by an optional system username tells CVS that | ||
4964 | connections authenticated with USERNAME should run as the system account | ||
4965 | SYSTEM_USERNAME - in other words, that CVS session would only be able | ||
4966 | to do things in the repository that someone logged in as SYSTEM_USERNAME | ||
4967 | could do. | ||
4968 | |||
4969 | <p>If no system username is given, USERNAME must match an actual login | ||
4970 | account name on the system, and the session will run with that user's | ||
4971 | permissions. In either case, the encrypted password should not be the | ||
4972 | same as the user's actual login password. It should be an independent | ||
4973 | password used only for CVS pserver connections. | ||
4974 | |||
4975 | <p>The password is encrypted using the same algorithm as the standard Unix | ||
4976 | system passwords stored in /etc/passwd. You may be wondering at this | ||
4977 | point, how does one acquire an encrypted version of a password? For | ||
4978 | Unix system passwords, the passwd command takes care of the encryption | ||
4979 | in /etc/passwd for you. Unfortunately, there is no corresponding cvs | ||
4980 | passwd command (it has been proposed several times, but no one's gotten | ||
4981 | around to writing it - perhaps you'll do it?). | ||
4982 | |||
4983 | <p>This is an inconvenience, but only a slight one. If nothing else, you | ||
4984 | can always temporarily change a regular user's system password using | ||
4985 | passwd, cut and paste the encrypted text from /etc/passwd into | ||
4986 | CVSROOT/passwd, and then restore the old password (note that on some | ||
4987 | systems, the encrypted passwords are found in /etc/shadow and are | ||
4988 | readable only by root.) | ||
4989 | |||
4990 | <p>That scheme is workable but rather cumbersome. It would be much easier | ||
4991 | to have a command-line utility that takes a plain text password as its | ||
4992 | argument and outputs the encrypted version. Here is such a tool, | ||
4993 | written in Perl: | ||
4994 | |||
4995 | <pre>#!/usr/bin/perl | ||
4996 | |||
4997 | srand (time()); | ||
4998 | my $randletter = "(int (rand (26)) + (int (rand (1) + .5) % 2 ? 65 : 97))"; | ||
4999 | my $salt = sprintf ("%c%c", eval $randletter, eval $randletter); | ||
5000 | my $plaintext = shift; | ||
5001 | my $crypttext = crypt ($plaintext, $salt); | ||
5002 | |||
5003 | print "${crypttext}\n"; | ||
5004 | </pre> | ||
5005 | |||
5006 | <p>I keep the preceding script in <code>/usr/local/bin/cryptout.pl</code>: | ||
5007 | |||
5008 | <pre>floss$ ls -l /usr/local/bin/cryptout.pl | ||
5009 | |||
5010 | -rwxr-xr-x 1 root root 265 Jun 14 20:41 /usr/local/bin/cryptout.pl | ||
5011 | floss$ cryptout.pl "some text" | ||
5012 | sB3A79YDX5L4s | ||
5013 | |||
5014 | floss$ | ||
5015 | </pre> | ||
5016 | |||
5017 | <p>If I took the output of this example and used it to create the following | ||
5018 | entry in CVSROOT/passwd | ||
5019 | |||
5020 | <pre>jrandom:sB3A79YDX5L4s:craig | ||
5021 | </pre> | ||
5022 | |||
5023 | <p>then someone could connect to the repository with the following command: | ||
5024 | |||
5025 | <pre>remote$ cvs -d :pserver:jrandom@floss.red-bean.com:/usr/local/newrepos login | ||
5026 | </pre> | ||
5027 | |||
5028 | <p>They could then type <code>some text</code> as their password and thereafter | ||
5029 | be able to execute CVS commands with the same access privileges as the | ||
5030 | system user <code>craig</code>. | ||
5031 | |||
5032 | <p>If someone attempts to authenticate with a username and password that | ||
5033 | don't appear in CVSROOT/passwd, CVS will check to see if that username | ||
5034 | and password are present in /etc/passwd. If they are (and if the | ||
5035 | password matches, of course), CVS will grant access. It behaves this | ||
5036 | way for the administrator's convenience, so that separate CVSROOT/passwd | ||
5037 | entries don't have to be set up for regular system users. However, this | ||
5038 | behavior is also a security hole, because it means that if one of those | ||
5039 | users does connect to the CVS server, her regular login password will | ||
5040 | have crossed over the network in cleartext, potentially vulnerable to | ||
5041 | the eyes of password sniffers. A bit further on, you'll learn how to | ||
5042 | turn off this "fallback" behavior, so that CVS consults only its own | ||
5043 | passwd file. Whether you leave it on or off, you should probably force | ||
5044 | any CVS users who also have login accounts to maintain different | ||
5045 | passwords for the two functions. | ||
5046 | |||
5047 | <p>Although the passwd file authenticates for the whole repository, with a | ||
5048 | little extra work you can still use it to grant project-specific access. | ||
5049 | Here's one method: | ||
5050 | |||
5051 | <p>Suppose you want to grant some remote developers access to project | ||
5052 | <code>foo</code>, and others access to project <code>bar</code>, and you don't want | ||
5053 | developers from one project to have commit access to the other. You can | ||
5054 | accomplish this by creating project-specific user accounts and groups on | ||
5055 | the system and then mapping to those accounts in the CVSROOT/passwd | ||
5056 | file. | ||
5057 | |||
5058 | <p>Here's the relevant excerpt from /etc/passwd | ||
5059 | |||
5060 | <pre>cvs-foo:*:600:600:Public CVS Account for Project Foo:/usr/local/cvs:/bin/false | ||
5061 | cvs-bar:*:601:601:Public CVS Account for Project Bar:/usr/local/cvs:/bin/false | ||
5062 | </pre> | ||
5063 | |||
5064 | <p>and from /etc/group | ||
5065 | |||
5066 | <pre>cvs-foo:*:600:cvs-foo | ||
5067 | cvs-bar:*:601:cvs-bar | ||
5068 | </pre> | ||
5069 | |||
5070 | <p>and, finally, CVSROOT/passwd: | ||
5071 | |||
5072 | <pre>kcunderh:rKa5jzULzmhOo:cvs-foo | ||
5073 | jmankoff:tGX1fS8sun6rY:cvs-foo | ||
5074 | brebard:cAXVPNZN6uFH2:cvs-foo | ||
5075 | xwang:qp5lsf7nzRzfs:cvs-foo | ||
5076 | dstone:JDNNF6HeX/yLw:cvs-bar | ||
5077 | twp:glUHEM8KhcbO6:cvs-bar | ||
5078 | ffranklin:cG6/6yXbS9BHI:cvs-bar | ||
5079 | yyang:YoEqcCeCUq1vQ:cvs-bar | ||
5080 | </pre> | ||
5081 | |||
5082 | <p>Some of the CVS usernames map onto the system user account | ||
5083 | <code>cvs-foo</code> and some onto <code>cvs-bar</code>. Because CVS runs under the | ||
5084 | user ID of the system account, you just have to make sure that the | ||
5085 | relevant parts of the repository are writeable only by the appropriate | ||
5086 | users and groups. If you just make sure that the user accounts are | ||
5087 | locked down pretty tight (no valid login password, <code>/bin/false</code> as | ||
5088 | the shell), then this system is reasonably secure (but see later in this | ||
5089 | chapter about CVSROOT permissions!). Also, CVS does record changes and | ||
5090 | log messages under the CVS username, not the system username, so you can | ||
5091 | still tell who is responsible for a given change. | ||
5092 | |||
5093 | <p><hr> | ||
5094 | Node:<a name="Anonymous_Access">Anonymous Access</a>, | ||
5095 | Next:<a rel=next href="#Repository_Structure">Repository Structure</a>, | ||
5096 | Previous:<a rel=previous href="#The_Password-Authenticating_Server">The Password-Authenticating Server</a>, | ||
5097 | Up:<a rel=up href="#Repository_Administration">Repository Administration</a> | ||
5098 | <br> | ||
5099 | |||
5100 | <h2>Anonymous Access</h2> | ||
5101 | |||
5102 | <p>So far we've only seen how to use the password-authenticating server to | ||
5103 | grant normal full access to the repository (although admittedly one can | ||
5104 | restrict that access through carefully arranged Unix file permissions). | ||
5105 | Turning this into anonymous, read-only access is a simple step: You just | ||
5106 | have to add a new file, or possibly two, in CVSROOT/. The files' names | ||
5107 | are <code>readers</code> and <code>writers</code> - the former containing a list of | ||
5108 | usernames who can only read the repository, the latter users who can | ||
5109 | read and write. | ||
5110 | |||
5111 | <p>If you list a username in CVSROOT/readers, that user will have only read | ||
5112 | access to all projects in the repository. If you list a username in | ||
5113 | CVSROOT/writers, that user will have write access, and every pserver | ||
5114 | user not listed in writers will have read-only access (that is, if the | ||
5115 | writers file exists at all, it implies read-only access for all those | ||
5116 | not listed in it). If the same username is listed in both files, CVS | ||
5117 | resolves the conflict in the more conservative way: the user will have | ||
5118 | read-only access. | ||
5119 | |||
5120 | <p>The format of the files is very simple: one user per line (don't forget | ||
5121 | to put a newline after the last user). Here is a sample readers file: | ||
5122 | |||
5123 | <pre>anonymous | ||
5124 | splotnik | ||
5125 | guest | ||
5126 | jbrowse | ||
5127 | </pre> | ||
5128 | |||
5129 | <p>Note that the files apply to CVS usernames, not system usernames. If | ||
5130 | you use user aliasing in the CVSROOT/passwd file (putting a system | ||
5131 | username after a second colon), the leftmost username is the one to list | ||
5132 | in a readers or writers file. | ||
5133 | |||
5134 | <p>Just to be painfully accurate about it, here is a formal description of | ||
5135 | the server's behavior in deciding whether to grant read-only or | ||
5136 | read-write access: | ||
5137 | |||
5138 | <p>If a readers file exists and this user is listed in it, then she gets | ||
5139 | read-only access. If a writers file exists and this user is not listed | ||
5140 | in it, then she also gets read-only access (this is true even if a | ||
5141 | readers file exists but that person is not listed there). If that | ||
5142 | person is listed in both, she gets read-only access. In all other | ||
5143 | cases, that person gets full read-write access. | ||
5144 | |||
5145 | <p>Thus, a typical repository with anonymous CVS access has this (or | ||
5146 | something like it) in CVSROOT/passwd | ||
5147 | |||
5148 | <pre>anonymous:XR4EZcEs0szik | ||
5149 | </pre> | ||
5150 | |||
5151 | <p>this (or something like it) in /etc/passwd | ||
5152 | |||
5153 | <pre>anonymous:!:1729:105:Anonymous CVS User:/usr/local/newrepos:/bin/false | ||
5154 | </pre> | ||
5155 | |||
5156 | <p>and this in CVSROOT/readers: | ||
5157 | |||
5158 | <pre>anonymous | ||
5159 | </pre> | ||
5160 | |||
5161 | <p>And, of course, the aforementioned setup in /etc/services and | ||
5162 | /etc/inetd.conf. That's all there is to it! | ||
5163 | |||
5164 | <p>Note that some older Unix systems don't support usernames longer than | ||
5165 | eight characters. One way to get around this would be to call the user | ||
5166 | <code>anon</code> instead of <code>anonymous</code> in CVSROOT/passwd and in the | ||
5167 | system files, because people often assume that anon is short for | ||
5168 | anonymous anyway. But it might be better to put something like this | ||
5169 | into the CVSROOT/passwd file | ||
5170 | |||
5171 | <pre>anonymous:XR4EZcEs0szik:cvsanon | ||
5172 | </pre> | ||
5173 | |||
5174 | <p>(and then of course use <code>cvsanon</code> in the system files). That way, | ||
5175 | you'd be able to publish a repository address that uses | ||
5176 | <code>anonymous</code>, which is more or less standard now. People accessing | ||
5177 | the repository with | ||
5178 | |||
5179 | <pre>cvs -d :pserver:anonymous@cvs.foobar.com:/usr/local/newrepos (etc...) | ||
5180 | </pre> | ||
5181 | |||
5182 | <p>would actually run on the server as cvsanon (or whatever). But they | ||
5183 | wouldn't need to know or care about how things are set up on the server | ||
5184 | side - they'd only see the published address. | ||
5185 | |||
5186 | <p><hr> | ||
5187 | Node:<a name="Repository_Structure">Repository Structure</a>, | ||
5188 | Next:<a rel=next href="#RCS_Format">RCS Format</a>, | ||
5189 | Previous:<a rel=previous href="#Anonymous_Access">Anonymous Access</a>, | ||
5190 | Up:<a rel=up href="#Repository_Administration">Repository Administration</a> | ||
5191 | <br> | ||
5192 | |||
5193 | <h2>Repository Structure</h2> | ||
5194 | |||
5195 | <p>The new repository still has no projects in it. Let's re-run the | ||
5196 | initial import from <a href="#An_Overview_of_CVS">An Overview of CVS</a>, watching what happens to | ||
5197 | the repository. (For simplicity's sake, all commands will assume that | ||
5198 | the CVSROOT environment variable has been set to /usr/local/newrepos, so | ||
5199 | there's no need to specify the repository with -d on imports and | ||
5200 | checkouts.) | ||
5201 | |||
5202 | <pre>floss$ ls /usr/local/newrepos | ||
5203 | CVSROOT/ | ||
5204 | floss$ pwd | ||
5205 | /home/jrandom/src/ | ||
5206 | floss$ ls | ||
5207 | myproj/ | ||
5208 | floss$ cd myproj | ||
5209 | floss$ cvs import -m "initial import into CVS" myproj jrandom start | ||
5210 | N myproj/README.txt | ||
5211 | N myproj/hello.c | ||
5212 | cvs import: Importing /usr/local/newrepos/myproj/a-subdir | ||
5213 | N myproj/a-subdir/whatever.c | ||
5214 | cvs import: Importing /usr/local/newrepos/myproj/a-subdir/subsubdir | ||
5215 | N myproj/a-subdir/subsubdir/fish.c | ||
5216 | cvs import: Importing /usr/local/newrepos/myproj/b-subdir | ||
5217 | N myproj/b-subdir/random.c | ||
5218 | |||
5219 | No conflicts created by this import | ||
5220 | |||
5221 | floss$ ls /usr/local/newrepos | ||
5222 | CVSROOT/ myproj/ | ||
5223 | floss$ cd /usr/local/newrepos/myproj | ||
5224 | floss$ ls | ||
5225 | README.txt,v a-subdir/ b-subdir/ hello.c,v | ||
5226 | floss$ cd a-subdir | ||
5227 | floss$ ls | ||
5228 | subsubdir/ whatever.c,v | ||
5229 | floss$ cd .. | ||
5230 | |||
5231 | floss$ | ||
5232 | </pre> | ||
5233 | |||
5234 | <p>Before the import, the repository contained only its administrative | ||
5235 | area, CVSROOT. After the import, a new directory - <code>myproj</code> - | ||
5236 | appeared. The files and subdirectories inside that new directory look | ||
5237 | suspiciously like the project we imported, except that the files have | ||
5238 | the suffix <code>,v</code>. These are RCS-format version control files (the | ||
5239 | <code>,v</code> stands for "version"), and they are the backbone of the | ||
5240 | repository. Each RCS file stores the revision history of its | ||
5241 | corresponding file in the project, including all branches and tags. | ||
5242 | |||
5243 | <p><hr> | ||
5244 | Node:<a name="RCS_Format">RCS Format</a>, | ||
5245 | Next:<a rel=next href="#What_Happens_When_You_Remove_A_File">What Happens When You Remove A File</a>, | ||
5246 | Previous:<a rel=previous href="#Repository_Structure">Repository Structure</a>, | ||
5247 | Up:<a rel=up href="#Repository_Administration">Repository Administration</a> | ||
5248 | <br> | ||
5249 | |||
5250 | <h2>RCS Format</h2> | ||
5251 | |||
5252 | <p>You do not need to know any of the RCS format to use CVS (although there | ||
5253 | is an excellent writeup included with the source distribution, see | ||
5254 | doc/RCSFILES). However, a basic understanding of the format can be of | ||
5255 | immense help in troubleshooting CVS problems, so we'll take a brief peek | ||
5256 | into one of the files, <code>hello.c,v</code>. Here are its contents: | ||
5257 | |||
5258 | <pre>head 1.1; | ||
5259 | branch 1.1.1; | ||
5260 | access ; | ||
5261 | symbols start:1.1.1.1 jrandom:1.1.1; | ||
5262 | locks ; strict; | ||
5263 | comment @ * @; | ||
5264 | |||
5265 | 1.1 | ||
5266 | date 99.06.20.17.47.26; author jrandom; state Exp; | ||
5267 | branches 1.1.1.1; | ||
5268 | next; | ||
5269 | |||
5270 | 1.1.1.1 | ||
5271 | date 99.06.20.17.47.26; author jrandom; state Exp; | ||
5272 | branches ; | ||
5273 | next; | ||
5274 | |||
5275 | desc | ||
5276 | @@ | ||
5277 | |||
5278 | 1.1 | ||
5279 | log | ||
5280 | @Initial revision | ||
5281 | @ | ||
5282 | text | ||
5283 | @#include <stdio.h> | ||
5284 | |||
5285 | void | ||
5286 | main () | ||
5287 | { | ||
5288 | printf ("Hello, world!\n"); | ||
5289 | } | ||
5290 | @ | ||
5291 | |||
5292 | 1.1.1.1 | ||
5293 | log | ||
5294 | @initial import into CVS | ||
5295 | @ | ||
5296 | text | ||
5297 | @@ | ||
5298 | </pre> | ||
5299 | |||
5300 | <p>Whew! Most of that you can ignore; don't worry about the relationship | ||
5301 | between 1.1 and 1.1.1.1, for example, or the implied 1.1.1 branch - | ||
5302 | they aren't really significant from a user's or even an administrator's | ||
5303 | point of view. What you should try to grok is the overall format. At | ||
5304 | the top is a collection of header fields: | ||
5305 | |||
5306 | <pre>head 1.1; | ||
5307 | branch 1.1.1; | ||
5308 | access ; | ||
5309 | symbols start:1.1.1.1 jrandom:1.1.1; | ||
5310 | locks ; strict; | ||
5311 | comment @ * @; | ||
5312 | </pre> | ||
5313 | |||
5314 | <p>Farther down in the file are groups of meta-information about each | ||
5315 | revision (but still not showing the contents of that revision), such as: | ||
5316 | |||
5317 | <pre>1.1 | ||
5318 | date 99.06.20.17.47.26; author jrandom; state Exp; | ||
5319 | branches 1.1.1.1; | ||
5320 | next ; | ||
5321 | </pre> | ||
5322 | |||
5323 | <p>And finally, the log message and text of an actual revision: | ||
5324 | |||
5325 | <pre>1.1 | ||
5326 | log | ||
5327 | @Initial revision | ||
5328 | @ | ||
5329 | text | ||
5330 | @#include <stdio.h> | ||
5331 | |||
5332 | void | ||
5333 | main () | ||
5334 | { | ||
5335 | printf ("Hello, world!\n"); | ||
5336 | } | ||
5337 | @ | ||
5338 | |||
5339 | 1.1.1.1 | ||
5340 | log | ||
5341 | @initial import into CVS | ||
5342 | @ | ||
5343 | text | ||
5344 | @@ | ||
5345 | </pre> | ||
5346 | |||
5347 | <p>If you look closely, you'll see that the first revision's contents are | ||
5348 | stored under the heading 1.1, but that the log message there is "Initial | ||
5349 | revision", whereas the log message we actually used at import time was | ||
5350 | "initial import into CVS", which appears farther down, under | ||
5351 | <code>Revision 1.1.1.1</code>. You don't need to worry about this discrepancy | ||
5352 | right now. It happens because imports are a special circumstance: In | ||
5353 | order to make repeated imports into the same project have a useful | ||
5354 | effect, import actually places the initial revision on both the main | ||
5355 | trunk and on a special branch (the reasons for this will become clearer | ||
5356 | when we look at vendor branches in <a href="#Advanced_CVS">Advanced CVS</a>). For now, you | ||
5357 | can treat <code>1.1</code> and <code>1.1.1.1</code> as the same thing. | ||
5358 | |||
5359 | <p>The file becomes even more revealing after we commit the first | ||
5360 | modification to hello.c: | ||
5361 | |||
5362 | <pre>floss$ cvs -Q co myproj | ||
5363 | floss$ cd myproj | ||
5364 | floss$ emacs hello.c | ||
5365 | (make some changes to the file) | ||
5366 | |||
5367 | floss$ cvs ci -m "print goodbye too" | ||
5368 | cvs commit: Examining . | ||
5369 | cvs commit: Examining a-subdir | ||
5370 | cvs commit: Examining a-subdir/subsubdir | ||
5371 | cvs commit: Examining b-subdir | ||
5372 | Checking in hello.c; | ||
5373 | /usr/local/newrepos/myproj/hello.c,v <-- hello.c | ||
5374 | new revision: 1.2; previous revision: 1.1 | ||
5375 | done | ||
5376 | </pre> | ||
5377 | |||
5378 | <p>If you look at hello.c,v in the repository now, you can see the effect | ||
5379 | of the commit: | ||
5380 | |||
5381 | <pre>head 1.2; | ||
5382 | access; | ||
5383 | symbols | ||
5384 | start:1.1.1.1 jrandom:1.1.1; | ||
5385 | locks; strict; | ||
5386 | comment @ * @; | ||
5387 | |||
5388 | 1.2 | ||
5389 | date 99.06.21.01.49.40; author jrandom; state Exp; | ||
5390 | branches; | ||
5391 | next 1.1; | ||
5392 | |||
5393 | 1.1 | ||
5394 | date 99.06.20.17.47.26; author jrandom; state Exp; | ||
5395 | branches | ||
5396 | 1.1.1.1; | ||
5397 | next ; | ||
5398 | |||
5399 | 1.1.1.1 | ||
5400 | date 99.06.20.17.47.26; author jrandom; state Exp; | ||
5401 | branches; | ||
5402 | next ; | ||
5403 | |||
5404 | desc | ||
5405 | @@ | ||
5406 | |||
5407 | 1.2 | ||
5408 | log | ||
5409 | @print goodbye too | ||
5410 | @ | ||
5411 | text | ||
5412 | @#include <stdio.h> | ||
5413 | |||
5414 | void | ||
5415 | main () | ||
5416 | { | ||
5417 | printf ("Hello, world!\n"); | ||
5418 | printf ("Goodbye, world!\n"); | ||
5419 | } | ||
5420 | @ | ||
5421 | |||
5422 | 1.1 | ||
5423 | log | ||
5424 | @Initial revision | ||
5425 | @ | ||
5426 | text | ||
5427 | @d7 1 | ||
5428 | @ | ||
5429 | |||
5430 | 1.1.1.1 | ||
5431 | log | ||
5432 | @initial import into CVS | ||
5433 | @ | ||
5434 | text | ||
5435 | @@ | ||
5436 | </pre> | ||
5437 | |||
5438 | <p>Now the full contents of Revision 1.2 are stored in the file, and the | ||
5439 | text for Revision 1.1 has been replaced with the cryptic formula: | ||
5440 | |||
5441 | <pre>d7 1 | ||
5442 | </pre> | ||
5443 | |||
5444 | <p>The <code>d7 1</code> is a diff code that means "starting at line 7, | ||
5445 | delete 1 line". In other words, to derive Revision 1.1, delete line 7 | ||
5446 | from Revision 1.2! Try working through it yourself. You'll see that it | ||
5447 | does indeed produce Revision 1.1 - it simply does away with the line we | ||
5448 | added to the file. | ||
5449 | |||
5450 | <p>This demonstrates the basic principle of RCS format: It stores only the | ||
5451 | differences between revisions, thereby saving a lot of space compared | ||
5452 | with storing each revision in full. To go backwards from the most | ||
5453 | recent revision to the previous one, it patches the later revision using | ||
5454 | the stored diff. Of course, this means that the further back you travel | ||
5455 | in the revision history, the more patch operations must be performed | ||
5456 | (for example, if the file is on Revision 1.7 and CVS is asked to | ||
5457 | retrieve Revision 1.4, it has to produce 1.6 by patching backwards from | ||
5458 | 1.7, then 1.5 by patching 1.6, then 1.4 by patching 1.5). Fortunately, | ||
5459 | old revisions are also the ones least often retrieved, so the RCS system | ||
5460 | works out pretty well in practice: The more recent the revision, the | ||
5461 | cheaper it is to obtain. | ||
5462 | |||
5463 | <p>As for the header information at the top of the file, you don't need to | ||
5464 | know what all of it means. However, the effects of certain operations | ||
5465 | show up very clearly in the headers, and a passing familiarity with them | ||
5466 | may prove useful. | ||
5467 | |||
5468 | <p>When you commit a new revision on the trunk, the <code>head</code> label is | ||
5469 | updated (note how it became 1.2 in the preceding example, when the | ||
5470 | second revision to hello.c was committed). When you add a file as | ||
5471 | binary or tag it, those operations are recorded in the headers as well. | ||
5472 | As an example, we'll add foo.jpg as a binary file and then tag it a | ||
5473 | couple of times: | ||
5474 | |||
5475 | <pre>floss$ cvs add -kb foo.jpg | ||
5476 | cvs add: scheduling file 'foo.jpg' for addition | ||
5477 | cvs add: use 'cvs commit' to add this file permanently | ||
5478 | floss$ cvs -q commit -m "added a random image; ask jrandom@red-bean.com why" | ||
5479 | RCS file: /usr/local/newrepos/myproj/foo.jpg,v | ||
5480 | done | ||
5481 | Checking in foo.jpg; | ||
5482 | /usr/local/newrepos/myproj/foo.jpg,v <-- foo.jpg | ||
5483 | initial revision: 1.1 | ||
5484 | done | ||
5485 | floss$ cvs tag some_random_tag foo.jpg | ||
5486 | T foo.jpg | ||
5487 | floss$ cvs tag ANOTHER-TAG foo.jpg | ||
5488 | T foo.jpg | ||
5489 | floss$ | ||
5490 | </pre> | ||
5491 | |||
5492 | <p>Now examine the header section of foo.jpg,v in the repository: | ||
5493 | |||
5494 | <pre>head 1.1; | ||
5495 | access; | ||
5496 | symbols | ||
5497 | ANOTHER-TAG:1.1 | ||
5498 | some_random_tag:1.1; | ||
5499 | locks; strict; | ||
5500 | comment @# @; | ||
5501 | expand@b@; | ||
5502 | </pre> | ||
5503 | |||
5504 | <p>Notice the b in the expand line at the end - it's due to our having | ||
5505 | used the -kb flag when adding the file, and means the file won't undergo | ||
5506 | any keyword or newline expansions, which would normally occur during | ||
5507 | checkouts and updates if it were a regular text file. The tags appear | ||
5508 | in the symbols section, one tag per line - both of them are attached to | ||
5509 | the first revision, since that's what was tagged both times. (This also | ||
5510 | helps explain why tag names can only contain letters, numbers, hyphens, | ||
5511 | and underscores. If the tag itself contained colons or dots, the RCS | ||
5512 | file's record of it might be ambiguous, because there would be no way to | ||
5513 | find the textual boundary between the tag and the revision to which it | ||
5514 | is attached.) | ||
5515 | |||
5516 | <h2>RCS Format Always Quotes @ Signs</h2> | ||
5517 | |||
5518 | <p>The <code>@</code> symbol is used as a field delimiter in RCS files, which | ||
5519 | means that if one appears in the text of a file or in a log message, it | ||
5520 | must be quoted (otherwise, CVS would incorrectly interpret it as marking | ||
5521 | the end of that field). It is quoted by doubling - that is, CVS always | ||
5522 | interprets <code>@@</code> as "literal @ sign", never as "end of current | ||
5523 | field". When we committed foo.jpg, the log message was | ||
5524 | |||
5525 | <pre>"added a random image; ask jrandom@red-bean.com why" | ||
5526 | </pre> | ||
5527 | |||
5528 | <p>which is stored in foo.jpg,v like this: | ||
5529 | |||
5530 | <pre>1.1 | ||
5531 | log | ||
5532 | @added a random image; ask jrandom@@red-bean.com why | ||
5533 | @ | ||
5534 | </pre> | ||
5535 | |||
5536 | <p>The @ sign in jrandom@@red-bean.com will be automatically unquoted | ||
5537 | whenever CVS retrieves the log message: | ||
5538 | |||
5539 | <pre>floss$ cvs log foo.jpg | ||
5540 | RCS file: /usr/local/newrepos/myproj/foo.jpg,v | ||
5541 | Working file: foo.jpg | ||
5542 | head: 1.1 | ||
5543 | branch: | ||
5544 | locks: strict | ||
5545 | access list: | ||
5546 | symbolic names: | ||
5547 | ANOTHER-TAG: 1.1 | ||
5548 | some_random_tag: 1.1 | ||
5549 | keyword substitution: b | ||
5550 | total revisions: 1;selected revisions: 1 | ||
5551 | description: | ||
5552 | ---------------------------- | ||
5553 | revision 1.1 | ||
5554 | date: 1999/06/21 02:56:18; author: jrandom; state: Exp; | ||
5555 | added a random image; ask jrandom@red-bean.com why | ||
5556 | ============================================================================ | ||
5557 | |||
5558 | floss$ | ||
5559 | </pre> | ||
5560 | |||
5561 | <p>The only reason you should care is that if you ever find yourself | ||
5562 | hand-editing RCS files (a rare circumstance, but not unheard of), you | ||
5563 | must remember to use double @ signs in revision contents and log | ||
5564 | messages. If you don't, the RCS file will be corrupt and will probably | ||
5565 | exhibit strange and undesirable behaviors. | ||
5566 | |||
5567 | <p>Speaking of hand-editing RCS files, don't be fooled by the permissions | ||
5568 | in the repository: | ||
5569 | |||
5570 | <pre>floss$ ls -l | ||
5571 | total 6 | ||
5572 | -r--r--r-- 1 jrandom users 410 Jun 20 12:47 README.txt,v | ||
5573 | drwxrwxr-x 3 jrandom users 1024 Jun 20 21:56 a-subdir/ | ||
5574 | drwxrwxr-x 2 jrandom users 1024 Jun 20 21:56 b-subdir/ | ||
5575 | -r--r--r-- 1 jrandom users 937 Jun 20 21:56 foo.jpg,v | ||
5576 | -r--r--r-- 1 jrandom users 564 Jun 20 21:11 hello.c,v | ||
5577 | |||
5578 | floss$ | ||
5579 | </pre> | ||
5580 | |||
5581 | <p>(For those not fluent in Unix ls output, the <code>-r--r--r--</code> lines on | ||
5582 | the left essentially mean that the files can be read but not changed.) | ||
5583 | Although the files appear to be read-only for everyone, the directory | ||
5584 | permissions must also be taken into account: | ||
5585 | |||
5586 | <pre>floss$ ls -ld . | ||
5587 | drwxrwxr-x 4 jrandom users 1024 Jun 20 22:16 ./ | ||
5588 | floss$ | ||
5589 | </pre> | ||
5590 | |||
5591 | <p>The myproj/ directory itself - and its subdirectories - are all | ||
5592 | writeable by the owner (jrandom) and the group (users). This means that | ||
5593 | CVS (running as jrandom, or as anyone in the users group) can create and | ||
5594 | delete files in those directories, even if it can't directly edit files | ||
5595 | already present. CVS edits an RCS file by making a separate copy of it, | ||
5596 | so you should also make all of your changes in a temporary copy, and | ||
5597 | then replace the existing RCS file with the new one. (But please don't | ||
5598 | ask why the files themselves are read-only - there are historical | ||
5599 | reasons for that, having to do with the way RCS works when run as a | ||
5600 | standalone program.) | ||
5601 | |||
5602 | <p>Incidentally, having the files' group be <code>users</code> is probably not | ||
5603 | what you want, considering that the top-level directory of the | ||
5604 | repository was explicitly assigned group <code>cvs</code>. You can correct | ||
5605 | the problem by running this command inside the repository: | ||
5606 | |||
5607 | <pre>floss$ cd /usr/local/newrepos | ||
5608 | floss$ chgrp -R cvs myproj | ||
5609 | </pre> | ||
5610 | |||
5611 | <p>The usual Unix file-creation rules govern which group is assigned to new | ||
5612 | files that appear in the repository, so once in a while you may need to | ||
5613 | run chgrp or chmod on certain files or directories in the repository | ||
5614 | (setting the SGID bit with <code>chmod g+s</code> is often a good | ||
5615 | strategy: it makes children of a directory inherit the directory's group | ||
5616 | ownership, which is usually what you want in the repository). There are | ||
5617 | no hard and fast rules about how you should structure repository | ||
5618 | permissions; it just depends on who is working on what projects. | ||
5619 | |||
5620 | <p><hr> | ||
5621 | Node:<a name="What_Happens_When_You_Remove_A_File">What Happens When You Remove A File</a>, | ||
5622 | Next:<a rel=next href="#The_CVSROOT__Administrative_Directory">The CVSROOT/ Administrative Directory</a>, | ||
5623 | Previous:<a rel=previous href="#RCS_Format">RCS Format</a>, | ||
5624 | Up:<a rel=up href="#Repository_Administration">Repository Administration</a> | ||
5625 | <br> | ||
5626 | |||
5627 | <h2>What Happens When You Remove A File</h2> | ||
5628 | |||
5629 | <p>When you remove a file from a project, it doesn't just disappear. CVS | ||
5630 | must be able to retrieve such files when you request an old snapshot of | ||
5631 | the project. Instead, the file gets put in the <code>Attic</code>, literally: | ||
5632 | |||
5633 | <pre>floss$ pwd | ||
5634 | /home/jrandom/src/myproj | ||
5635 | floss$ ls /usr/local/newrepos/myproj/ | ||
5636 | README.txt,v a-subdir/ b-subdir/ foo.jpg,v hello.c,v | ||
5637 | floss$ rm foo.jpg | ||
5638 | floss$ cvs rm foo.jpg | ||
5639 | cvs remove: scheduling 'foo.jpg' for removal | ||
5640 | cvs remove: use 'cvs commit' to remove this file permanently | ||
5641 | floss$ cvs ci -m "Removed foo.jpg" foo.jpg | ||
5642 | Removing foo.jpg; | ||
5643 | /usr/local/newrepos/myproj/foo.jpg,v <-- foo.jpg | ||
5644 | new revision: delete; previous revision: 1.1 | ||
5645 | done | ||
5646 | floss$ cd /usr/local/newrepos/myproj/ | ||
5647 | floss$ ls | ||
5648 | Attic/ README.txt,v a-subdir/ b-subdir/ hello.c,v | ||
5649 | floss$ cd Attic | ||
5650 | floss$ ls | ||
5651 | foo.jpg,v | ||
5652 | floss$ | ||
5653 | </pre> | ||
5654 | |||
5655 | <p>In each repository directory of a project, the presence of an | ||
5656 | <code>Attic/</code> subdirectory means that at least one file has been removed | ||
5657 | from that directory (this means that you shouldn't use directories named | ||
5658 | Attic in your projects). CVS doesn't merely move the RCS file into | ||
5659 | Attic/, however; it also commits a new revision into the file, with a | ||
5660 | special revision state of <code>dead</code>. Here's the relevant section from | ||
5661 | Attic/foo.jpg,v: | ||
5662 | |||
5663 | <pre>1.2 | ||
5664 | date 99.06.21.03.38.07; author jrandom; state dead; | ||
5665 | branches; | ||
5666 | next1.1; | ||
5667 | </pre> | ||
5668 | |||
5669 | <p>If the file is later brought back to life, CVS has a way of recording | ||
5670 | that it was dead at some point in the past and is now alive again. | ||
5671 | |||
5672 | <p>This means that if you want to restore a removed file, you can't just | ||
5673 | take it out of the Attic/ and put it back into the project. Instead, | ||
5674 | you have to do something like this in a working copy: | ||
5675 | |||
5676 | <pre>floss$ pwd | ||
5677 | /home/jrandom/src/myproj | ||
5678 | floss$ cvs -Q update -p -r 1.1 foo.jpg > foo.jpg | ||
5679 | floss$ ls | ||
5680 | CVS/ README.txt a-subdir/ b-subdir/ foo.jpg hello.c | ||
5681 | floss$ cvs add -kb foo.jpg | ||
5682 | cvs add: re-adding file foo.jpg (in place of dead revision 1.2) | ||
5683 | cvs add: use 'cvs commit' to add this file permanently | ||
5684 | floss$ cvs ci -m "revived jpg image" foo.jpg | ||
5685 | Checking in foo.jpg; | ||
5686 | /usr/local/newrepos/myproj/foo.jpg,v <-- foo.jpg | ||
5687 | new revision: 1.3; previous revision: 1.2 | ||
5688 | done | ||
5689 | floss$ cd /usr/local/newrepos/myproj/ | ||
5690 | floss$ ls | ||
5691 | Attic/ a-subdir/ foo.jpg,v | ||
5692 | README.txt,v b-subdir/ hello.c,v | ||
5693 | floss$ ls Attic/ | ||
5694 | floss$ | ||
5695 | </pre> | ||
5696 | |||
5697 | <p>There's a lot more to know about RCS format, but this is sufficient for | ||
5698 | a CVS adminstrator to maintain a repository. It's quite rare to | ||
5699 | actually edit an RCS file; you'll usually just have to tweak file | ||
5700 | permissions in the repository, at least if my own experience is any | ||
5701 | guide. Nevertheless, when CVS starts behaving truly weirdly (rare, but | ||
5702 | not completely outside the realm of possibility), you may want to | ||
5703 | actually look inside the RCS files to figure out what's going on. | ||
5704 | |||
5705 | <p><hr> | ||
5706 | Node:<a name="The_CVSROOT__Administrative_Directory">The CVSROOT/ Administrative Directory</a>, | ||
5707 | Next:<a rel=next href="#Commit_Emails">Commit Emails</a>, | ||
5708 | Previous:<a rel=previous href="#What_Happens_When_You_Remove_A_File">What Happens When You Remove A File</a>, | ||
5709 | Up:<a rel=up href="#Repository_Administration">Repository Administration</a> | ||
5710 | <br> | ||
5711 | |||
5712 | <h2>The CVSROOT/ Administrative Directory</h2> | ||
5713 | |||
5714 | <p>The files in newrepos/CVSROOT/ are not part of any project, but are used | ||
5715 | to control CVS's behavior in the repository. The best way to edit those | ||
5716 | files is to check out a working copy of CVSROOT, just like a regular | ||
5717 | project: | ||
5718 | |||
5719 | <pre>floss$ cvs co CVSROOT | ||
5720 | cvs checkout: Updating CVSROOT | ||
5721 | U CVSROOT/checkoutlist | ||
5722 | U CVSROOT/commitinfo | ||
5723 | U CVSROOT/config | ||
5724 | U CVSROOT/cvswrappers | ||
5725 | U CVSROOT/editinfo | ||
5726 | U CVSROOT/loginfo | ||
5727 | U CVSROOT/modules | ||
5728 | U CVSROOT/notify | ||
5729 | U CVSROOT/rcsinfo | ||
5730 | U CVSROOT/taginfo | ||
5731 | U CVSROOT/verifymsg | ||
5732 | floss$ | ||
5733 | </pre> | ||
5734 | |||
5735 | <p>We'll take the files in their approximate order of importance. Note | ||
5736 | that each of the files comes with an explanatory comment at the | ||
5737 | beginning (the comment convention is the same across all of them: A | ||
5738 | <code>#</code> sign at the beginning of the line signifies a comment, and CVS | ||
5739 | ignores such lines when parsing the files). Remember that any change | ||
5740 | you make to the administrative files in your checked out working copy | ||
5741 | won't affect CVS's behavior until you commit the changes. | ||
5742 | |||
5743 | <p>If you're extremely security conscious, you may want to arrange the | ||
5744 | Unix-level permissions on CVSROOT to be different from permissions | ||
5745 | elsewhere in the repository, in order to have fine-grained control over | ||
5746 | who can commit changes to CVSROOT. As you'll see a little later, being | ||
5747 | able to modify the files in CVSROOT essentially gives any CVS user - | ||
5748 | even remote ones - the ability to run arbitrary commands on the | ||
5749 | repository machine. | ||
5750 | |||
5751 | <ul> | ||
5752 | <li><a href="#The_config_File">The config File</a>: | ||
5753 | <li><a href="#The_modules_File">The modules File</a>: | ||
5754 | <li><a href="#The_commitinfo_And_loginfo_And_rcsinfo_Files">The commitinfo And loginfo And rcsinfo Files</a>: | ||
5755 | <li><a href="#The_verifymsg_And_rcsinfo_Files">The verifymsg And rcsinfo Files</a>: | ||
5756 | <li><a href="#The_taginfo_File">The taginfo File</a>: | ||
5757 | <li><a href="#The_cvswrappers_File">The cvswrappers File</a>: | ||
5758 | <li><a href="#The_editinfo_File">The editinfo File</a>: | ||
5759 | <li><a href="#The_notify_File">The notify File</a>: | ||
5760 | <li><a href="#The_checkoutlist_File">The checkoutlist File</a>: | ||
5761 | </ul> | ||
5762 | |||
5763 | <p><hr> | ||
5764 | Node:<a name="The_config_File">The config File</a>, | ||
5765 | Next:<a rel=next href="#The_modules_File">The modules File</a>, | ||
5766 | Up:<a rel=up href="#The_CVSROOT__Administrative_Directory">The CVSROOT/ Administrative Directory</a> | ||
5767 | <br> | ||
5768 | |||
5769 | <h3>The config File</h3> | ||
5770 | |||
5771 | <p>The <dfn>config</dfn> file allows you to configure certain global behavioral | ||
5772 | parameters. It follows a very strict format | ||
5773 | |||
5774 | <pre>PARAMETER=VALUE | ||
5775 | (etc) | ||
5776 | </pre> | ||
5777 | |||
5778 | <p>with no extra spaces allowed. For example, here is a possible config | ||
5779 | file: | ||
5780 | |||
5781 | <pre>SystemAuth=yes | ||
5782 | TopLevelAdmin=no | ||
5783 | PreservePermissions=no | ||
5784 | </pre> | ||
5785 | |||
5786 | <p>(An absent entry would be equivalent to <code>no</code>.) | ||
5787 | |||
5788 | <p>The <code>SystemAuth</code> parameter governs whether CVS should look in the | ||
5789 | system passwd file if it fails to find a given username in the | ||
5790 | CVSROOT/passwd file. CVS distributions are shipped with this set to | ||
5791 | <code>no</code> to be conservative about your system's security. | ||
5792 | |||
5793 | <p><code>TopLevelAdmin</code> tells CVS whether to make a sibling CVS/ directory | ||
5794 | when it checks out a working copy. This CVS/ directory would not be | ||
5795 | inside the working copy, but rather next to it. It might be convenient | ||
5796 | to turn this on if you tend (and your repository's users tend) to check | ||
5797 | out many different projects from the same repository. Otherwise, you | ||
5798 | should leave it off, as it can be disconcerting to see an extra CVS/ | ||
5799 | directory appear where you don't expect it. | ||
5800 | |||
5801 | <p><code>PreservePermissions</code> governs whether to preserve file permissions | ||
5802 | and similar metadata in the revision history. This is a somewhat | ||
5803 | obscure feature that probably isn't worth describing in detail. See the | ||
5804 | node <cite>Special Files</cite> in the Cederqvist if you're interested | ||
5805 | (<dfn>node</dfn> is Texinfo-speak for a particular location within an Info | ||
5806 | document. To go to a node while reading Info, just type <kbd>g</kbd> | ||
5807 | followed by the name of the node, from anywhere inside the document). | ||
5808 | |||
5809 | <p><code>LockDir</code> is also a rarely used feature. In special circumstances, | ||
5810 | you may want to tell CVS to create its lockfiles somewhere other than | ||
5811 | directly in the project subdirectories, in order to avoid permission | ||
5812 | problems. These lockfiles keep CVS from tripping over itself when | ||
5813 | multiple operations are performed on the same repository directory | ||
5814 | simultaneously. Generally, you never need to worry about them, but | ||
5815 | sometimes users may have trouble updating or checking out from a | ||
5816 | repository directory because they're unable to create a lockfile (even | ||
5817 | on read-only operations, CVS needs to create a lockfile to avoid | ||
5818 | situations where it could end up reading while another invocation of CVS | ||
5819 | is writing). The usual fix for this is to change repository | ||
5820 | permissions, but when that's not feasible, the LockDir parameter can | ||
5821 | come in handy. | ||
5822 | |||
5823 | <p>There are no other parameters at this time, but future versions of CVS | ||
5824 | may add new ones; you should always check the Cederqvist or the | ||
5825 | distribution config file itself for updates. | ||
5826 | |||
5827 | <p><hr> | ||
5828 | Node:<a name="The_modules_File">The modules File</a>, | ||
5829 | Next:<a rel=next href="#The_commitinfo_And_loginfo_And_rcsinfo_Files">The commitinfo And loginfo And rcsinfo Files</a>, | ||
5830 | Previous:<a rel=previous href="#The_config_File">The config File</a>, | ||
5831 | Up:<a rel=up href="#The_CVSROOT__Administrative_Directory">The CVSROOT/ Administrative Directory</a> | ||
5832 | <br> | ||
5833 | |||
5834 | <h3>The modules File</h3> | ||
5835 | |||
5836 | <p>In modules, you can define aliases and alternate groupings for projects | ||
5837 | in the repository. The most basic module line is of the form: | ||
5838 | |||
5839 | <pre>MODULE_NAME DIRECTORY_IN_REPOSITORY | ||
5840 | </pre> | ||
5841 | |||
5842 | <p>for example, | ||
5843 | |||
5844 | <pre>mp myproj | ||
5845 | asub myproj/a-subdir | ||
5846 | </pre> | ||
5847 | |||
5848 | <p>(The paths given on the right are relative to the top of the | ||
5849 | repository.) This gives developers an alternate name by which to check | ||
5850 | out a project or a portion of a project: | ||
5851 | |||
5852 | <pre>floss$ cvs co mp | ||
5853 | cvs checkout: Updating mp | ||
5854 | U mp/README.txt | ||
5855 | U mp/foo.jpg | ||
5856 | U mp/hello.c | ||
5857 | cvs checkout: Updating mp/a-subdir | ||
5858 | U mp/a-subdir/whatever.c | ||
5859 | cvs checkout: Updating mp/a-subdir/subsubdir | ||
5860 | U mp/a-subdir/subsubdir/fish.c | ||
5861 | cvs checkout: Updating mp/b-subdir | ||
5862 | U mp/b-subdir/random.c | ||
5863 | </pre> | ||
5864 | |||
5865 | <p>or | ||
5866 | |||
5867 | <pre>floss$ cvs -d /usr/local/newrepos/ co asub | ||
5868 | cvs checkout: Updating asub | ||
5869 | U asub/whatever.c | ||
5870 | cvs checkout: Updating asub/subsubdir | ||
5871 | U asub/subsubdir/fish.c | ||
5872 | </pre> | ||
5873 | |||
5874 | <p>Notice how in both cases the module's name became the name of the | ||
5875 | directory created for the working copy. In the case of asub, it didn't | ||
5876 | even bother with the intermediate myproj/ directory, but created a | ||
5877 | top-level asub/ instead, even though it came from myproj/a-subdir in the | ||
5878 | repository. Updates, commits, and all other CVS commands will behave | ||
5879 | normally in those working copies - the only thing unusual about them | ||
5880 | are their names. | ||
5881 | |||
5882 | <p>By putting file names after the directory name, you can define a module | ||
5883 | consisting of just some of the files in a given repository directory. | ||
5884 | For example | ||
5885 | |||
5886 | <pre>readme myproj README.txt | ||
5887 | </pre> | ||
5888 | |||
5889 | <p>and | ||
5890 | |||
5891 | <pre>no-readme myproj hello.c foo.jpg | ||
5892 | </pre> | ||
5893 | |||
5894 | <p>would permit the following checkouts, respectively: | ||
5895 | |||
5896 | <pre>floss$ cvs -q co readme | ||
5897 | U readme/README.txt | ||
5898 | floss$ cvs -q co no-readme | ||
5899 | U no-readme/hello.c | ||
5900 | U no-readme/foo.jpg | ||
5901 | floss$ | ||
5902 | </pre> | ||
5903 | |||
5904 | <p>You can define a module that will include multiple repository | ||
5905 | directories by using the -a (for <code>alias</code>) flag, but note that the | ||
5906 | directories will get them checked out under their original names. For | ||
5907 | example, this line | ||
5908 | |||
5909 | <pre>twoproj -a myproj yourproj | ||
5910 | </pre> | ||
5911 | |||
5912 | <p>would allow you to do this (assuming that both myproj/ and yourproj/ are | ||
5913 | in the repository): | ||
5914 | |||
5915 | <pre>floss$ cvs co twoproj | ||
5916 | U myproj/README.txt | ||
5917 | U myproj/foo.jpg | ||
5918 | U myproj/hello.c | ||
5919 | U myproj/a-subdir/whatever.c | ||
5920 | U myproj/a-subdir/subsubdir/fish.c | ||
5921 | U myproj/b-subdir/random.c | ||
5922 | U yourproj/README | ||
5923 | U yourproj/foo.c | ||
5924 | U yourproj/some-subdir/file1.c | ||
5925 | U yourproj/some-subdir/file2.c | ||
5926 | U yourproj/some-subdir/another-subdir/blah.c | ||
5927 | </pre> | ||
5928 | |||
5929 | <p>The name <code>twoproj</code> was a convenient handle to pull in both | ||
5930 | projects, but it didn't affect the names of the working copies. (There | ||
5931 | is no requirement that alias modules refer to multiple directories, by | ||
5932 | the way; we could have omitted twoproj, in which case myproj would still | ||
5933 | have been checked out under the name <code>myproj</code>.) | ||
5934 | |||
5935 | <p>Modules can even refer to other modules, by prefixing them with an | ||
5936 | ampersand: | ||
5937 | |||
5938 | <pre>mp myproj | ||
5939 | asub myproj/a-subdir | ||
5940 | twoproj -a myproj yourproj | ||
5941 | tp &twoproj | ||
5942 | </pre> | ||
5943 | |||
5944 | <p>Doing a checkout of <code>tp</code> would have exactly the same result as the | ||
5945 | checkout of <code>twoproj</code> did. | ||
5946 | |||
5947 | <p>There are a few other tricks you can do with modules, most of them less | ||
5948 | frequently used than the ones just presented. See the node modules in | ||
5949 | the Cederqvist for information about them. | ||
5950 | |||
5951 | <p><hr> | ||
5952 | Node:<a name="The_commitinfo_And_loginfo_And_rcsinfo_Files">The commitinfo And loginfo And rcsinfo Files</a>, | ||
5953 | Next:<a rel=next href="#The_verifymsg_And_rcsinfo_Files">The verifymsg And rcsinfo Files</a>, | ||
5954 | Previous:<a rel=previous href="#The_modules_File">The modules File</a>, | ||
5955 | Up:<a rel=up href="#The_CVSROOT__Administrative_Directory">The CVSROOT/ Administrative Directory</a> | ||
5956 | <br> | ||
5957 | |||
5958 | <h3>The commitinfo And loginfo And rcsinfo Files</h3> | ||
5959 | |||
5960 | <p>Most of the other administrative files provide programmatic <dfn>hooks</dfn> | ||
5961 | into various parts of the commit process (for example, the ability to | ||
5962 | validate log messages or file states before permitting the commit, or | ||
5963 | the ability to notify a group of developers whenever a commit happens in | ||
5964 | a certain directory of the repository). | ||
5965 | |||
5966 | <p>The files generally share a common syntax. Each line is of the form: | ||
5967 | |||
5968 | <pre>REGULAR_EXPRESSION PROGRAM_TO_RUN | ||
5969 | </pre> | ||
5970 | |||
5971 | <p>The regular expression will be tested against the directory into which | ||
5972 | the commit is taking place (with the directory name relative to the top | ||
5973 | of the repository). If it matches, the designated program will be run. | ||
5974 | The program will be passed the names of each of the files in the commit; | ||
5975 | it can do whatever it likes with those names, including opening up the | ||
5976 | files and examining their contents. If the program returns with a | ||
5977 | nonzero exit status, the commit is prevented from taking place. | ||
5978 | |||
5979 | <p>(<dfn>Regular expressions</dfn> are a system for concisely describing classes | ||
5980 | of strings. If you aren't familiar with regular expressions, you can | ||
5981 | get by with the following short summary: <code>foo</code> would match any file | ||
5982 | whose name contains the string <code>foo</code>; and <code>foo.*bar</code> would | ||
5983 | match any file whose name contains <code>foo</code>, followed by any number of | ||
5984 | characters, followed by the string <code>bar</code>. That's because normal | ||
5985 | substrings match themselves, but <code>.</code> and <code>*</code> are special. | ||
5986 | <code>.</code> matches any character, and <code>*</code> means match any number of | ||
5987 | the preceding character, including zero. The <code>^</code> and <code>$</code> | ||
5988 | signs mean match at the beginning and end of the string, respectively; | ||
5989 | thus, <code>^foo.*bar.*baz$</code> would match any string beginning with | ||
5990 | <code>foo</code>, containing <code>bar</code> somewhere in the middle, and ending | ||
5991 | with <code>baz</code>. That's all we'll go into here; this summary is a very | ||
5992 | abbreviated subset of full regular expression syntax.) | ||
5993 | |||
5994 | <p>The <dfn>commitinfo</dfn> file is for generic hooks you want run on every | ||
5995 | commit. Here are some example commitinfo lines: | ||
5996 | |||
5997 | <pre>^a-subdir* /usr/local/bin/check-asubdir.sh | ||
5998 | ou /usr/local/bin/validate-project.pl | ||
5999 | </pre> | ||
6000 | |||
6001 | <p>So any commit into myproj/a-subdir/ would match the first line, which | ||
6002 | would then run the check-asubdir.sh script. A commit in any project | ||
6003 | whose name (actual repository directory name, not necessarily module | ||
6004 | name) contained the string <code>ou</code> would run the validate-project.pl | ||
6005 | script, unless the commit had already matched the previous a-subdir | ||
6006 | line. | ||
6007 | |||
6008 | <p>In place of a regular expression, the word <code>DEFAULT</code> or <code>ALL</code> | ||
6009 | may be used. The DEFAULT line (or the first DEFAULT line, if there are | ||
6010 | more than one) will be run if no regular expression matches, and each of | ||
6011 | the ALL lines will be run in addition to any other lines that may match. | ||
6012 | |||
6013 | <p>The file names passed to the program do not refer to RCS files - they | ||
6014 | point to normal files, whose contents are exactly the same as the | ||
6015 | working-copy files being committed. The only unusual aspect is that CVS | ||
6016 | has them temporarily placed inside the repository, so they'll be | ||
6017 | available to programs running on the machine where the repository is | ||
6018 | located. | ||
6019 | |||
6020 | <p>The <dfn>loginfo</dfn> file is similar to commitinfo, except that instead of | ||
6021 | acting on the files' contents, it acts on the log message. The left | ||
6022 | side of the loginfo file contains regular expressions, including | ||
6023 | possibly DEFAULT and ALL lines. The program invoked on the right side | ||
6024 | receives the log message on its standard input; it can do whatever it | ||
6025 | wants with that input. | ||
6026 | |||
6027 | <p>The program on the right side can also take an arbitrary number of | ||
6028 | command-line arguments. One of those arguments can be a special | ||
6029 | <code>%</code> code, to be expanded by CVS at runtime, as follows: | ||
6030 | |||
6031 | <pre>%s ------> name(s) of the file(s) being committed | ||
6032 | %V ------> revision number(s) before the commit | ||
6033 | %v ------> revision number(s) after the commit | ||
6034 | </pre> | ||
6035 | |||
6036 | <p>The expansion always begins with the repository subdirectory (relative | ||
6037 | to the top of the repository), followed by the per-file information. | ||
6038 | For example, if the files committed were foo, bar, and baz, all in | ||
6039 | <code>myproj/a-subdir</code>, then <code>%s</code> would expand into | ||
6040 | |||
6041 | <pre>myproj/a-subdir foo bar baz | ||
6042 | </pre> | ||
6043 | |||
6044 | <p>whereas <code>%V</code> would expand to show their old revision numbers | ||
6045 | |||
6046 | <pre>myproj/a-subdir 1.7 1.134 1.12 | ||
6047 | </pre> | ||
6048 | |||
6049 | <p>and <code>%v</code> their new revision numbers: | ||
6050 | |||
6051 | <pre>myproj/a-subdir 1.8 1.135 1.13 | ||
6052 | </pre> | ||
6053 | |||
6054 | <p>You can combine <code>%</code> expressions by enclosing them in curly braces | ||
6055 | following <code>%</code> sign - this will expand them into a series of | ||
6056 | comma-separated sublists, each containing the corresponding information | ||
6057 | for one file in the commit. For instance, <code>%{sv}</code> would expand | ||
6058 | to | ||
6059 | |||
6060 | <pre>myproj/a-subdir foo,1.8 bar,1.135 baz,1.13 | ||
6061 | </pre> | ||
6062 | |||
6063 | <p>and <code>%{sVv}</code> would expand to | ||
6064 | |||
6065 | <pre>myproj/a-subdir foo,1.7,1.8 bar,1.134,1.135 baz,1.12,1.13 | ||
6066 | </pre> | ||
6067 | |||
6068 | <p>(You may have to look carefully to distinguish the commas from the | ||
6069 | periods in those examples.) | ||
6070 | |||
6071 | <p>Here is a sample loginfo file: | ||
6072 | |||
6073 | <pre>^myproj$ /usr/local/newrepos/CVSROOT/log.pl -m myproj-devel@foobar.com %s | ||
6074 | ou /usr/local/bin/ou-notify.pl %{sv} | ||
6075 | DEFAULT /usr/local/bin/default-notify.pl %{sVv} | ||
6076 | </pre> | ||
6077 | |||
6078 | <p>In the first line, any commit in the myproj subdirectory of the | ||
6079 | repository invokes <code>log.pl</code>, passing it an email address (to which | ||
6080 | <code>log.pl</code> will send a mail containing the log message), followed by | ||
6081 | the repository, followed by all the files in the commit. | ||
6082 | |||
6083 | <p>In the second line, any commit in a repository subdirectory containing | ||
6084 | the string <code>ou</code> will invoke the (imaginary) <code>ou-notify.pl</code> | ||
6085 | script, passing it the repository followed by the file names and new | ||
6086 | revision numbers of the files in the commit. | ||
6087 | |||
6088 | <p>The third line invokes the (equally imaginary) <code>default-notify.pl</code> | ||
6089 | script for any commit that didn't match either of the two previous | ||
6090 | lines, passing it all possible information (path to repository, file | ||
6091 | names, old revisions, and new revisions). | ||
6092 | |||
6093 | <p><hr> | ||
6094 | Node:<a name="The_verifymsg_And_rcsinfo_Files">The verifymsg And rcsinfo Files</a>, | ||
6095 | Next:<a rel=next href="#The_taginfo_File">The taginfo File</a>, | ||
6096 | Previous:<a rel=previous href="#The_commitinfo_And_loginfo_And_rcsinfo_Files">The commitinfo And loginfo And rcsinfo Files</a>, | ||
6097 | Up:<a rel=up href="#The_CVSROOT__Administrative_Directory">The CVSROOT/ Administrative Directory</a> | ||
6098 | <br> | ||
6099 | |||
6100 | <h3>The verifymsg And rcsinfo Files</h3> | ||
6101 | |||
6102 | <p>Sometimes you may just want a program to automatically verify that the | ||
6103 | log message conforms to a certain standard and to stop the commit if | ||
6104 | that standard is not met. This can be accomplished by using | ||
6105 | <code>verifymsg</code>, possibly with some help from <code>rcsinfo</code>. | ||
6106 | |||
6107 | <p>The <dfn>verifymsg</dfn> file is the usual combination of regular expressions | ||
6108 | and programs. The program receives the log message on standard input; | ||
6109 | presumably it runs some checks to verify that the log message meets | ||
6110 | certain criteria, then it exits with status zero or nonzero. If the | ||
6111 | latter, the commit will fail. | ||
6112 | |||
6113 | <p>Meanwhile, the left side of rcsinfo has the usual regular expressions, | ||
6114 | but the right side points to template files instead of programs. A | ||
6115 | template file might be something like this | ||
6116 | |||
6117 | <pre>Condition: | ||
6118 | Fix: | ||
6119 | Comments: | ||
6120 | </pre> | ||
6121 | |||
6122 | <p>or some other collection of fields that a developer is supposed to fill | ||
6123 | out to form a valid log message. The template is not very useful if | ||
6124 | everyone commits using the -m option explicitly, but many developers | ||
6125 | prefer not to do that. Instead, they run | ||
6126 | |||
6127 | <pre>floss$ cvs commit | ||
6128 | </pre> | ||
6129 | |||
6130 | <p>and wait for CVS to automatically fire up a text editor (as specified in | ||
6131 | the EDITOR environment variable). There they write a log message, then | ||
6132 | save the file and exit the editor, after which CVS continues with the | ||
6133 | commit. | ||
6134 | |||
6135 | <p>In that scenario, an rcsinfo template would insert itself into the | ||
6136 | editor before the user starts typing, so the fields would be displayed | ||
6137 | along with a reminder to fill them in. Then when the user commits, the | ||
6138 | appropriate program in <code>verifymsg</code> is invoked. Presumably, it will | ||
6139 | check that the message does follow that format, and its exit status will | ||
6140 | reflect the results of its inquiry (with zero meaning success). | ||
6141 | |||
6142 | <p>As an aid to the verification programs, the path to the template from | ||
6143 | the rcsinfo file is appended as the last argument to the program command | ||
6144 | line in <code>verifymsg</code>; that way, the program can base its | ||
6145 | verification process on the template itself, if desired. | ||
6146 | |||
6147 | <p>Note that when someone checks out a working copy to a remote machine, | ||
6148 | the appropriate rcsinfo template file is sent to the client as well | ||
6149 | (it's stored in the CVS/ subdirectory of the working copy). However, | ||
6150 | this means that if the rcsinfo file on the server is changed after that, | ||
6151 | the client won't see the changes without re-checking out the project | ||
6152 | (merely doing an update won't work). | ||
6153 | |||
6154 | <p>Note also that in the verifymsg file, the ALL keyword is not supported | ||
6155 | (although DEFAULT still is). This is to make it easier to override | ||
6156 | default verification scripts with subdirectory-specific ones. | ||
6157 | |||
6158 | <p><hr> | ||
6159 | Node:<a name="The_taginfo_File">The taginfo File</a>, | ||
6160 | Next:<a rel=next href="#The_cvswrappers_File">The cvswrappers File</a>, | ||
6161 | Previous:<a rel=previous href="#The_verifymsg_And_rcsinfo_Files">The verifymsg And rcsinfo Files</a>, | ||
6162 | Up:<a rel=up href="#The_CVSROOT__Administrative_Directory">The CVSROOT/ Administrative Directory</a> | ||
6163 | <br> | ||
6164 | |||
6165 | <h3>The taginfo File</h3> | ||
6166 | |||
6167 | <p>What loginfo does for log messages, taginfo does for tags. The left | ||
6168 | side of taginfo is regular expressions, as usual, and the right side is | ||
6169 | programs. Each program is automatically handed arguments when CVS tag | ||
6170 | is invoked, in this order: | ||
6171 | |||
6172 | <pre>arg 1: tag name | ||
6173 | arg 2: operation ("add" => tag, "mov" => tag -F, "del" => tag -d) | ||
6174 | arg 3: repository | ||
6175 | arg 4, 5, etc: file revision [file revision ...] | ||
6176 | </pre> | ||
6177 | |||
6178 | <p>If the program returns nonzero, the tag is aborted. | ||
6179 | |||
6180 | <p>We haven't covered the -F option to tag before now, but it's exactly | ||
6181 | what the above implies: a way to move a tag from one revision to | ||
6182 | another. For example, if the tag <code>Known_Working</code> is attached to | ||
6183 | Revision 1.7 of a file and you want it attached to Revision 1.11 | ||
6184 | instead, you'd do this | ||
6185 | |||
6186 | <pre>cvs tag -r 1.11 -F Known_Working foo.c | ||
6187 | </pre> | ||
6188 | |||
6189 | <p>which removes the tag from 1.7, or wherever it was previously in that | ||
6190 | file, and puts it at 1.11. | ||
6191 | |||
6192 | <p><hr> | ||
6193 | Node:<a name="The_cvswrappers_File">The cvswrappers File</a>, | ||
6194 | Next:<a rel=next href="#The_editinfo_File">The editinfo File</a>, | ||
6195 | Previous:<a rel=previous href="#The_taginfo_File">The taginfo File</a>, | ||
6196 | Up:<a rel=up href="#The_CVSROOT__Administrative_Directory">The CVSROOT/ Administrative Directory</a> | ||
6197 | <br> | ||
6198 | |||
6199 | <h3>The cvswrappers File</h3> | ||
6200 | |||
6201 | <p>The redundantly-named cvswrappers file gives you a way to specify that | ||
6202 | certain files should be treated as binary, based on their file name. | ||
6203 | CVS does not assume that all .jpg files are JPG image data, for example, | ||
6204 | so it doesn't automatically use -kb when adding JPG files. Nonetheless, | ||
6205 | certain projects would find it very useful to simply designate all JPG | ||
6206 | files as binary. Here is a line in cvswrappers to do that: | ||
6207 | |||
6208 | <pre>*.jpg -k 'b' | ||
6209 | </pre> | ||
6210 | |||
6211 | <p>The <code>b</code> is separate and in quotes because it's not the only | ||
6212 | possible RCS keyword expansion mode; one could also specify <code>o</code>, | ||
6213 | which means not to expand <code>$</code> sign keywords but to do newline | ||
6214 | conversion. However, <code>b</code> is the most common parameter. | ||
6215 | |||
6216 | <p>There are a few other modes that can be specified from the wrappers | ||
6217 | file, but they're for such rare situations that they're probably not | ||
6218 | worth documenting here (translation: your author has never had to use | ||
6219 | them). See the node <cite>Wrappers</cite> in the Cederqvist if you're | ||
6220 | curious. | ||
6221 | |||
6222 | <p><hr> | ||
6223 | Node:<a name="The_editinfo_File">The editinfo File</a>, | ||
6224 | Next:<a rel=next href="#The_notify_File">The notify File</a>, | ||
6225 | Previous:<a rel=previous href="#The_cvswrappers_File">The cvswrappers File</a>, | ||
6226 | Up:<a rel=up href="#The_CVSROOT__Administrative_Directory">The CVSROOT/ Administrative Directory</a> | ||
6227 | <br> | ||
6228 | |||
6229 | <h3>The editinfo File</h3> | ||
6230 | |||
6231 | <p>This file is obsolete, even though it's still included in distributions. | ||
6232 | Just ignore it. | ||
6233 | |||
6234 | <p><hr> | ||
6235 | Node:<a name="The_notify_File">The notify File</a>, | ||
6236 | Next:<a rel=next href="#The_checkoutlist_File">The checkoutlist File</a>, | ||
6237 | Previous:<a rel=previous href="#The_editinfo_File">The editinfo File</a>, | ||
6238 | Up:<a rel=up href="#The_CVSROOT__Administrative_Directory">The CVSROOT/ Administrative Directory</a> | ||
6239 | <br> | ||
6240 | |||
6241 | <h3>The notify File</h3> | ||
6242 | |||
6243 | <p>This file is used in conjunction with CVS's <code>watch</code> features, which | ||
6244 | are described in <a href="#Advanced_CVS">Advanced CVS</a>. Nothing about it will make sense | ||
6245 | until you understand what watches are (they're a useful but | ||
6246 | non-essential feature), so see <a href="#Advanced_CVS">Advanced CVS</a> for details about this | ||
6247 | file and about watches. | ||
6248 | |||
6249 | <p><hr> | ||
6250 | Node:<a name="The_checkoutlist_File">The checkoutlist File</a>, | ||
6251 | Previous:<a rel=previous href="#The_notify_File">The notify File</a>, | ||
6252 | Up:<a rel=up href="#The_CVSROOT__Administrative_Directory">The CVSROOT/ Administrative Directory</a> | ||
6253 | <br> | ||
6254 | |||
6255 | <h3>The checkoutlist File</h3> | ||
6256 | |||
6257 | <p>If you look inside CVSROOT/, you'll see that working copies of the files | ||
6258 | exist side by side with their RCS revision files: | ||
6259 | |||
6260 | <pre>floss$ ls /usr/local/newrepos/CVSROOT | ||
6261 | checkoutlist config,v history notify taginfo | ||
6262 | checkoutlist,v cvswrappers loginfo notify,v taginfo,v | ||
6263 | commitinfo cvswrappers,v loginfo,v passwd verifymsg | ||
6264 | commitinfo,v editinfo modules rcsinfo verifymsg,v | ||
6265 | config editinfo,v modules,v rcsinfo,v | ||
6266 | |||
6267 | floss$ | ||
6268 | </pre> | ||
6269 | |||
6270 | <p>CVS only pays attention to the working versions, not the RCS files, when | ||
6271 | it's looking for guidance on how to behave. Therefore, whenever you | ||
6272 | commit your working copy of CVSROOT/ (which might, after all, even be | ||
6273 | checked out to a different machine), CVS automatically updates any | ||
6274 | changed files in the repository itself. You will know that this has | ||
6275 | happened because CVS will print a message at the end of such commits: | ||
6276 | |||
6277 | <pre>floss$ cvs ci -m "added mp and asub modules" modules | ||
6278 | Checking in modules; | ||
6279 | /usr/local/newrepos/CVSROOT/modules,v <-- modules | ||
6280 | new revision: 1.2; previous revision: 1.1 | ||
6281 | done | ||
6282 | cvs commit: Rebuilding administrative file database | ||
6283 | </pre> | ||
6284 | |||
6285 | <p>CVS automatically knows about the standard administrative files, and | ||
6286 | will rebuild them in CVSROOT/ as necessary. If you decide to put custom | ||
6287 | files in CVSROOT/ (such as programs or rcsinfo template files), you'll | ||
6288 | have to tell CVS explicitly to treat them the same way. | ||
6289 | |||
6290 | <p>That's the purpose of the checkoutlist file. It has a different format | ||
6291 | from most of the files we've looked at so far | ||
6292 | |||
6293 | <pre>FILENAME ERROR_MESSAGE_IF_FILE_CANNOT_BE_CHECKED_OUT | ||
6294 | </pre> | ||
6295 | |||
6296 | <p>for example, | ||
6297 | |||
6298 | <pre>log.pl unable to check out / update log.pl in CVSROOT | ||
6299 | |||
6300 | bugfix.tmpl unable to check out / update bugfix.tmpl in CVSROOT | ||
6301 | </pre> | ||
6302 | |||
6303 | <p>Certain files in CVSROOT are traditionally not kept under revision | ||
6304 | control. One such is the <dfn>history</dfn> file, which keeps a running | ||
6305 | record of all actions in the repository, for use by the <code>cvs history</code> command (which lists checkout, update, and tag activity for a | ||
6306 | given file or project directory). Incidentally, if you just remove the | ||
6307 | <code>history</code> file, CVS will obligingly stop keeping that log. | ||
6308 | |||
6309 | <p>Note: sometimes the history file is the cause of permission problems, | ||
6310 | and the easiest way to solve them is to either make it world-writeable | ||
6311 | or just remove it. | ||
6312 | |||
6313 | <p>Another <code>unrevisioned</code> administrative file is passwd, the | ||
6314 | assumption being that having it checked out over the network might | ||
6315 | compromise the passwords (even though they're encrypted). You'll have | ||
6316 | to decide based on your own security situation whether you want to add | ||
6317 | passwd to checkoutlist or not; by default, it is not in checkoutlist. | ||
6318 | |||
6319 | <p>Two final notes about the CVSROOT/ directory: It is possible, if you | ||
6320 | make a big enough mistake, to commit an administrative file that is | ||
6321 | broken in such a way as to prevent any commits from happening at all. | ||
6322 | If you do that, naturally you won't be able to commit a fixed version of | ||
6323 | the administrative file! The solution is to go in and hand-edit the | ||
6324 | repository's working copy of the administrative file to correct the | ||
6325 | problem; the whole repository may stay inaccessible until you do that. | ||
6326 | |||
6327 | <p>Also, for security's sake, make sure your CVSROOT/ directory is only | ||
6328 | writeable by users you trust (by <code>trust</code>, I mean you trust both | ||
6329 | their intentions and their ability not to compromise their password). | ||
6330 | The <code>*info</code> files give people the ability to invoke arbitrary | ||
6331 | programs, so anyone who can commit or edit files in the CVSROOT/ | ||
6332 | directory can essentially run any command on the system. That's | ||
6333 | something you should always keep in mind. | ||
6334 | |||
6335 | <p><hr> | ||
6336 | Node:<a name="Commit_Emails">Commit Emails</a>, | ||
6337 | Next:<a rel=next href="#Finding_Out_More">Finding Out More</a>, | ||
6338 | Previous:<a rel=previous href="#The_CVSROOT__Administrative_Directory">The CVSROOT/ Administrative Directory</a>, | ||
6339 | Up:<a rel=up href="#Repository_Administration">Repository Administration</a> | ||
6340 | <br> | ||
6341 | |||
6342 | <h2>Commit Emails</h2> | ||
6343 | |||
6344 | <p>The loginfo file is how one sets up commit emails - automated emails | ||
6345 | that go out to everyone working on a project whenever a commit takes | ||
6346 | place. (It may seem counterintuitive that this is done in loginfo | ||
6347 | instead of commitinfo, but the point is that one wants to include the | ||
6348 | log message in the email). The program to do the mailing - | ||
6349 | <code>contrib/log.pl</code> in the CVS source distribution - can be installed | ||
6350 | anywhere on your system. I customarily put it in the repository's | ||
6351 | CVSROOT/ subdirectory, but that's just a matter of taste. | ||
6352 | |||
6353 | <p>You may need to edit <code>log.pl</code> a bit to get it to work on your | ||
6354 | system, possibly changing the first line to point to your Perl | ||
6355 | interpreter, and maybe changing this line | ||
6356 | |||
6357 | <pre>$mailcmd = "| Mail -s 'CVS update: $modulepath'"; | ||
6358 | </pre> | ||
6359 | |||
6360 | <p>to invoke your preferred mailer, which may or may not be named | ||
6361 | <code>Mail</code>. Once you've got it set the way you like it, you can put | ||
6362 | lines similar to these into your loginfo: | ||
6363 | |||
6364 | <pre>listerizer CVSROOT/log.pl %s -f CVSROOT/commitlog -m listerizer@red-bean.com | ||
6365 | RoadMail CVSROOT/log.pl %s -f CVSROOT/commitlog -m roadmail@red-bean.com | ||
6366 | bk/*score CVSROOT/log.pl %s -f CVSROOT/commitlog -m \ | ||
6367 | bkscore-devel@red-bean.com | ||
6368 | </pre> | ||
6369 | |||
6370 | <p>The <code>%s</code> expands to the names of the files being committed; the -f | ||
6371 | option to <code>log.pl</code> takes a file name, to which the log message will | ||
6372 | be appended (so CVSROOT/commitlog is an ever-growing file of log | ||
6373 | messages); and the -m flag takes an email address, to which | ||
6374 | <code>log.pl</code> will send a message about the commit. The address is | ||
6375 | usually a mailing list, but you can specify the -m option as many times | ||
6376 | as necessary in one log.pl command line. | ||
6377 | |||
6378 | <p><hr> | ||
6379 | Node:<a name="Finding_Out_More">Finding Out More</a>, | ||
6380 | Previous:<a rel=previous href="#Commit_Emails">Commit Emails</a>, | ||
6381 | Up:<a rel=up href="#Repository_Administration">Repository Administration</a> | ||
6382 | <br> | ||
6383 | |||
6384 | <h2>Finding Out More</h2> | ||
6385 | |||
6386 | <p>Although this chapter tries to give a complete introduction to | ||
6387 | installing and administering CVS, I've left out things that are either | ||
6388 | too rarely used to be worth mentioning or already well documented in the | ||
6389 | Cederqvist manual. The latter category includes setting up the other | ||
6390 | remote access methods: RSH/SSH, kserver (Kerberos 4), and GSSAPI (which | ||
6391 | includes Kerberos 5, among other things). It should be noted that | ||
6392 | nothing special needs to be done for RSH/SSH connections, other than | ||
6393 | making sure that the user in question can log into the repository | ||
6394 | machine using RSH or SSH. If they can and CVS is installed on both | ||
6395 | client and server, and they have the right permissions to use the | ||
6396 | repository directly from the server machine, then they should be able to | ||
6397 | access the repository remotely via the :ext: method. | ||
6398 | |||
6399 | <p>Descriptions of certain specialized features of CVS have been deferred | ||
6400 | to later chapters, so they can be introduced in contexts where their | ||
6401 | usefulness is obvious. General CVS troubleshooting tips are found in | ||
6402 | <a href="#Tips_And_Troubleshooting">Tips And Troubleshooting</a>. Although it's not necessary to read the | ||
6403 | entire Cederqvist manual, you should familiarize yourself with it; it | ||
6404 | will be an invaluable reference tool. If for some reason you don't have | ||
6405 | Info working on your machine and don't want to print the manual, you can | ||
6406 | browse it online at <a href="http://durak.org/cvswebsites/doc/">http://durak.org/cvswebsites/doc/</a> or | ||
6407 | <a href="http://www.loria.fr/~molli/cvs/doc/cvs_toc.html">http://www.loria.fr/~molli/cvs/doc/cvs_toc.html</a>. | ||
6408 | |||
6409 | <p><hr> | ||
6410 | Node:<a name="Advanced_CVS">Advanced CVS</a>, | ||
6411 | Next:<a rel=next href="#Tips_And_Troubleshooting">Tips And Troubleshooting</a>, | ||
6412 | Previous:<a rel=previous href="#Repository_Administration">Repository Administration</a>, | ||
6413 | Up:<a rel=up href="#Top">Top</a> | ||
6414 | <br> | ||
6415 | |||
6416 | <h1>Advanced CVS</h1> | ||
6417 | |||
6418 | <p>Now that we've covered the basic concepts of CVS usage and repository | ||
6419 | administration, we'll look at how CVS can be incorporated into the | ||
6420 | entire process of development. The fundamental CVS working cycle - | ||
6421 | checkout, update, commit, update, commit, and so on - was demonstrated | ||
6422 | by the examples in <a href="#An_Overview_of_CVS">An Overview of CVS</a>. This chapter elaborates on | ||
6423 | the cycle and discusses how CVS can be used to help developers | ||
6424 | communicate, give overviews of project activity and history, isolate and | ||
6425 | reunite different branches of development, and automate frequently | ||
6426 | performed tasks. Some of the techniques covered introduce new CVS | ||
6427 | commands, but many merely explain better ways to use commands that you | ||
6428 | already know. | ||
6429 | |||
6430 | <ul> | ||
6431 | <li><a href="#Watches__CVS_As_Telephone_">Watches (CVS As Telephone)</a>: | ||
6432 | <li><a href="#Log_Messages_And_Commit_Emails">Log Messages And Commit Emails</a>: | ||
6433 | <li><a href="#Changing_A_Log_Message_After_Commit">Changing A Log Message After Commit</a>: | ||
6434 | <li><a href="#Getting_Rid_Of_A_Working_Copy">Getting Rid Of A Working Copy</a>: | ||
6435 | <li><a href="#History_--_A_Summary_Of_Repository_Activity">History -- A Summary Of Repository Activity</a>: | ||
6436 | <li><a href="#Annotations_--_A_Detailed_View_Of_Project_Activity">Annotations -- A Detailed View Of Project Activity</a>: | ||
6437 | <li><a href="#Annotations_And_Branches">Annotations And Branches</a>: | ||
6438 | <li><a href="#Using_Keyword_Expansion">Using Keyword Expansion</a>: | ||
6439 | <li><a href="#Going_Out_On_A_Limb__How_To_Work_With_Branches_And_Survive_">Going Out On A Limb (How To Work With Branches And Survive)</a>: | ||
6440 | <li><a href="#Tracking_Third-Party_Sources__Vendor_Branches_">Tracking Third-Party Sources (Vendor Branches)</a>: | ||
6441 | <li><a href="#Exporting_For_Public_Distribution">Exporting For Public Distribution</a>: | ||
6442 | <li><a href="#The_Humble_Guru">The Humble Guru</a>: | ||
6443 | </ul> | ||
6444 | |||
6445 | <p><hr> | ||
6446 | Node:<a name="Watches__CVS_As_Telephone_">Watches (CVS As Telephone)</a>, | ||
6447 | Next:<a rel=next href="#Log_Messages_And_Commit_Emails">Log Messages And Commit Emails</a>, | ||
6448 | Up:<a rel=up href="#Advanced_CVS">Advanced CVS</a> | ||
6449 | <br> | ||
6450 | |||
6451 | <h2>Watches (CVS As Telephone)</h2> | ||
6452 | |||
6453 | <p>A major benefit of using CVS on a project is that it can function as a | ||
6454 | communications device as well as a record-keeper. This section | ||
6455 | concentrates on how CVS can be used to keep participants informed about | ||
6456 | what's going on in a project. As is true with other aspects of CVS, | ||
6457 | these features reward cooperation. The participants must want to be | ||
6458 | informed; if people choose not to use the communications features, | ||
6459 | there's nothing CVS can do about it. | ||
6460 | |||
6461 | <ul> | ||
6462 | <li><a href="#How_Watches_Work">How Watches Work</a>: | ||
6463 | <li><a href="#Enabling_Watches_In_The_Repository">Enabling Watches In The Repository</a>: | ||
6464 | <li><a href="#Using_Watches_In_Development">Using Watches In Development</a>: | ||
6465 | <li><a href="#Ending_An_Editing_Session">Ending An Editing Session</a>: | ||
6466 | <li><a href="#Controlling_What_Actions_Are_Watched">Controlling What Actions Are Watched</a>: | ||
6467 | <li><a href="#Finding_Out_Who_Is_Watching_What">Finding Out Who Is Watching What</a>: | ||
6468 | <li><a href="#Reminding_People_To_Use_Watches">Reminding People To Use Watches</a>: | ||
6469 | <li><a href="#What_Watches_Look_Like_In_The_Repository">What Watches Look Like In The Repository</a>: | ||
6470 | </ul> | ||
6471 | |||
6472 | <p><hr> | ||
6473 | Node:<a name="How_Watches_Work">How Watches Work</a>, | ||
6474 | Next:<a rel=next href="#Enabling_Watches_In_The_Repository">Enabling Watches In The Repository</a>, | ||
6475 | Up:<a rel=up href="#Watches__CVS_As_Telephone_">Watches (CVS As Telephone)</a> | ||
6476 | <br> | ||
6477 | |||
6478 | <h3>How Watches Work</h3> | ||
6479 | |||
6480 | <p>In its default behavior, CVS treats each working copy as an isolated | ||
6481 | sandbox. No one knows what you're doing in your working copy until you | ||
6482 | commit your changes. In turn, you don't know what others are doing in | ||
6483 | theirs - except via the usual methods of communication, such as | ||
6484 | shouting down the hallway, "Hey, I'm going to work on parse.c now. Let | ||
6485 | me know if you're editing it so we can avoid conflicts!" | ||
6486 | |||
6487 | <p>This informality works for projects where people have a general idea of | ||
6488 | who's responsible for what. However, this process can break down when a | ||
6489 | large number of developers are active in all parts of a code base and | ||
6490 | want to avoid conflicts. In such cases, they frequently have to cross | ||
6491 | each others' areas of responsibility but can't shout down the hallway at | ||
6492 | each other because they're geographically distributed. | ||
6493 | |||
6494 | <p>A feature of CVS called <code>watches</code> provides developers with a way to | ||
6495 | notify each other about who is working on what files at a given time. | ||
6496 | By "setting a watch" on a file, a developer can have CVS notify her if | ||
6497 | anyone else starts to work on that file. The notifications are normally | ||
6498 | sent via email, although it is possible to set up other notification | ||
6499 | methods. | ||
6500 | |||
6501 | <p>To use watches, you must modify one or two files in the repository | ||
6502 | administrative area, and developers must add some extra steps to the | ||
6503 | usual checkout/update/commit cycle. The changes on the repository side | ||
6504 | are fairly simple: You may need to edit the <code>CVSROOT/notify</code> file | ||
6505 | so that CVS knows how notifications are to be performed. You may also | ||
6506 | have to add lines to the <code>CVSROOT/users</code> file, which supplies | ||
6507 | external email addresses. | ||
6508 | |||
6509 | <p>On the working copy side, developers have to tell CVS which files they | ||
6510 | want to watch so that CVS can send them notifications when someone else | ||
6511 | starts editing those files. They also need to tell CVS when they start | ||
6512 | or stop editing a file, so CVS can send out notifications to others who | ||
6513 | may be watching. The following commands are used to implement these | ||
6514 | extra steps: | ||
6515 | |||
6516 | <ul> | ||
6517 | <li>cvs watch | ||
6518 | <li>cvs edit | ||
6519 | <li>cvs unedit | ||
6520 | </ul> | ||
6521 | |||
6522 | <p>The command <code>watch</code> differs from the usual CVS command pattern in | ||
6523 | that it requires further subcommands, such as <code>cvs watch add...</code>, <code>cvs watch remove...</code>, and so on. | ||
6524 | |||
6525 | <p>In the following example, we'll look at how to turn on watches in the | ||
6526 | repository and then how to use watches from the developer's side. The | ||
6527 | two example users, jrandom and qsmith, each have their own separate | ||
6528 | working copies of the same project; the working copies may even be on | ||
6529 | different machines. As usual, all examples assume that the $CVSROOT | ||
6530 | environment variable has already been set, so there's no need to pass -d | ||
6531 | <REPOS> to any CVS commands. | ||
6532 | |||
6533 | <p><hr> | ||
6534 | Node:<a name="Enabling_Watches_In_The_Repository">Enabling Watches In The Repository</a>, | ||
6535 | Next:<a rel=next href="#Using_Watches_In_Development">Using Watches In Development</a>, | ||
6536 | Previous:<a rel=previous href="#How_Watches_Work">How Watches Work</a>, | ||
6537 | Up:<a rel=up href="#Watches__CVS_As_Telephone_">Watches (CVS As Telephone)</a> | ||
6538 | <br> | ||
6539 | |||
6540 | <h3>Enabling Watches In The Repository</h3> | ||
6541 | |||
6542 | <p>First, the CVSROOT/notify file must be edited to turn on email | ||
6543 | notification. One of the developers can do this, or the repository | ||
6544 | administrator can if the developers don't have permission to change the | ||
6545 | repository's administrative files. In any case, the first thing to do is | ||
6546 | check out the administrative area and edit the notify file: | ||
6547 | |||
6548 | <pre>floss$ cvs -q co CVSROOT | ||
6549 | U CVSROOT/checkoutlist | ||
6550 | U CVSROOT/commitinfo | ||
6551 | U CVSROOT/config | ||
6552 | U CVSROOT/cvswrappers | ||
6553 | U CVSROOT/editinfo | ||
6554 | U CVSROOT/loginfo | ||
6555 | U CVSROOT/modules | ||
6556 | U CVSROOT/notify | ||
6557 | U CVSROOT/rcsinfo | ||
6558 | U CVSROOT/taginfo | ||
6559 | U CVSROOT/verifymsg | ||
6560 | floss$ cd CVSROOT | ||
6561 | floss$ emacs notify | ||
6562 | ... | ||
6563 | </pre> | ||
6564 | |||
6565 | <p>When you edit the notify file for the first time, you'll see something | ||
6566 | like this: | ||
6567 | |||
6568 | <pre># The "notify" file controls where notifications from watches set by | ||
6569 | # "cvs watch add" or "cvs edit" are sent. The first entry on a line is | ||
6570 | # a regular expression which is tested against the directory that the | ||
6571 | # change is being made to, relative to the $CVSROOT. If it matches, | ||
6572 | # then the remainder of the line is a filter program that should contain | ||
6573 | # one occurrence of %s for the user to notify, and information on its | ||
6574 | # standard input. | ||
6575 | # | ||
6576 | # "ALL" or "DEFAULT" can be used in place of the regular expression. | ||
6577 | # | ||
6578 | # For example: | ||
6579 | # ALL mail %s -s "CVS notification" | ||
6580 | </pre> | ||
6581 | |||
6582 | <p>All you really need to do is uncomment the last line by removing the | ||
6583 | initial <code>#</code> mark. Although the notify file provides the same | ||
6584 | flexible interface as the other administrative files, with regular | ||
6585 | expressions matching against directory names, the truth is that you | ||
6586 | almost never want to use any of that flexibility. The only reason to | ||
6587 | have multiple lines, with each line's regular expression matching a | ||
6588 | particular part of the repository, would be if you wanted to use a | ||
6589 | different notification method for each project. However, normal email | ||
6590 | is a perfectly good notification mechanism, so most projects just use | ||
6591 | that. | ||
6592 | |||
6593 | <p>To specify email notification, the line | ||
6594 | |||
6595 | <pre>ALL mail %s -s "CVS notification" | ||
6596 | </pre> | ||
6597 | |||
6598 | <p>should work on any standard Unix machine. This command causes | ||
6599 | notifications to be sent as emails with the subject line <code>CVS | ||
6600 | notification</code> (the special expression ALL matches any directory, as | ||
6601 | usual). Having uncommented that line, commit the notify file so the | ||
6602 | repository is aware of the change: | ||
6603 | |||
6604 | <pre>floss$ cvs ci -m "turned on watch notification" | ||
6605 | cvs commit: Examining . | ||
6606 | Checking in notify; | ||
6607 | /usr/local/newrepos/CVSROOT/notify,v <-- notify | ||
6608 | new revision: 1.2; previous revision: 1.1 | ||
6609 | done | ||
6610 | cvs commit: Rebuilding administrative file database | ||
6611 | floss$ | ||
6612 | </pre> | ||
6613 | |||
6614 | <p>Editing the notify file in this way may be all that you'll need to do | ||
6615 | for watches in the repository. However, if there are remote developers | ||
6616 | working on the project, you may need to edit the <code>CVSROOT/users</code> | ||
6617 | file, too. The purpose of the users file is to tell CVS where to send | ||
6618 | email notifications for those users who have external email addresses. | ||
6619 | The format of each line in the users file is: | ||
6620 | |||
6621 | <pre>CVS_USERNAME:EMAIL_ADDRESS | ||
6622 | </pre> | ||
6623 | |||
6624 | <p>For example, | ||
6625 | |||
6626 | <pre>qsmith:quentinsmith@farawayplace.com | ||
6627 | </pre> | ||
6628 | |||
6629 | <p>The CVS username at the beginning of the line corresponds to a CVS | ||
6630 | username in <code>CVSROOT/password</code> (if present and the pserver access | ||
6631 | method is being used), or failing that, the server-side system username | ||
6632 | of the person running CVS. Following the colon is an external email | ||
6633 | address to which CVS should send watch notifications for that user. | ||
6634 | |||
6635 | <p>Unfortunately, as of this writing, the users file does not exist in the | ||
6636 | stock CVS distribution. Because it's an administrative file, you must | ||
6637 | not only create, cvs add, and commit it in the usual way, but also add | ||
6638 | it to <code>CVSROOT/checkoutlist</code> so that a checked-out copy is always | ||
6639 | maintained in the repository. | ||
6640 | |||
6641 | <p>Here is a sample session demonstrating this: | ||
6642 | |||
6643 | <pre>floss$ emacs checkoutlist | ||
6644 | ... (add the line for the users file) ... | ||
6645 | floss$ emacs users | ||
6646 | ... (add the line for qsmith) ... | ||
6647 | floss$ cvs add users | ||
6648 | floss$ cvs ci -m "added users to checkoutlist, qsmith to users" | ||
6649 | cvs commit: Examining . | ||
6650 | Checking in checkoutlist; | ||
6651 | /usr/local/newrepos/CVSROOT/checkoutlist,v <-- checkoutlist | ||
6652 | new revision: 1.2; previous revision: 1.1 | ||
6653 | done | ||
6654 | Checking in users; | ||
6655 | /usr/local/newrepos/CVSROOT/users,v <-- users | ||
6656 | new revision: 1.2; previous revision: 1.1 | ||
6657 | done | ||
6658 | cvs commit: Rebuilding administrative file database | ||
6659 | floss$ | ||
6660 | </pre> | ||
6661 | |||
6662 | <p>It's possible to use expanded-format email addresses in | ||
6663 | <code>CVSROOT/users</code>, but you have to be careful to encapsulate all | ||
6664 | whitespace within quotes. For example, the following will work | ||
6665 | |||
6666 | <pre>qsmith:"Quentin Q. Smith <quentinsmith@farawayplace.com>" | ||
6667 | </pre> | ||
6668 | |||
6669 | <p>or | ||
6670 | |||
6671 | <pre>qsmith:'Quentin Q. Smith <quentinsmith@farawayplace.com>' | ||
6672 | </pre> | ||
6673 | |||
6674 | <p>However, this will not work: | ||
6675 | |||
6676 | <pre>qsmith:"Quentin Q. Smith" <quentinsmith@farawayplace.com> | ||
6677 | </pre> | ||
6678 | |||
6679 | <p>When in doubt, you should test by running the command line given in the | ||
6680 | notify file manually. Just replace the <code>%s</code> in | ||
6681 | |||
6682 | <pre>mail %s -s "CVS notification" | ||
6683 | </pre> | ||
6684 | |||
6685 | <p>with what you have following the colon in users. If it works when you | ||
6686 | run it at a command prompt, it should work in the users file, too. | ||
6687 | |||
6688 | <p>When it's over, the checkout file will look like this: | ||
6689 | |||
6690 | <pre># The "checkoutlist" file is used to support additional version controlled | ||
6691 | # administrative files in $CVSROOT/CVSROOT, such as template files. | ||
6692 | # | ||
6693 | # The first entry on a line is a filename which will be checked out from | ||
6694 | # the corresponding RCS file in the $CVSROOT/CVSROOT directory. | ||
6695 | # The remainder of the line is an error message to use if the file cannot | ||
6696 | # be checked out. | ||
6697 | # | ||
6698 | # File format: | ||
6699 | # | ||
6700 | # [<whitespace>]<filename><whitespace><error message><end-of-line> | ||
6701 | # | ||
6702 | # comment lines begin with '#' | ||
6703 | |||
6704 | users Unable to check out 'users' file in CVSROOT. | ||
6705 | </pre> | ||
6706 | |||
6707 | <p>The users file will look like this: | ||
6708 | |||
6709 | <pre>qsmith:quentinsmith@farawayplace.com | ||
6710 | </pre> | ||
6711 | |||
6712 | <p>Now that the repository is set up for watches, let's look at what | ||
6713 | developers need to do in their working copies. | ||
6714 | |||
6715 | <p><hr> | ||
6716 | Node:<a name="Using_Watches_In_Development">Using Watches In Development</a>, | ||
6717 | Next:<a rel=next href="#Ending_An_Editing_Session">Ending An Editing Session</a>, | ||
6718 | Previous:<a rel=previous href="#Enabling_Watches_In_The_Repository">Enabling Watches In The Repository</a>, | ||
6719 | Up:<a rel=up href="#Watches__CVS_As_Telephone_">Watches (CVS As Telephone)</a> | ||
6720 | <br> | ||
6721 | |||
6722 | <h3>Using Watches In Development</h3> | ||
6723 | |||
6724 | <p>First, a developer checks out a working copy and adds herself to the | ||
6725 | list of watchers for one of the files in the project: | ||
6726 | |||
6727 | <pre>floss$ whoami | ||
6728 | jrandom | ||
6729 | floss$ cvs -q co myproj | ||
6730 | U myproj/README.txt | ||
6731 | U myproj/foo.gif | ||
6732 | U myproj/hello.c | ||
6733 | U myproj/a-subdir/whatever.c | ||
6734 | U myproj/a-subdir/subsubdir/fish.c | ||
6735 | U myproj/b-subdir/random.c | ||
6736 | floss$ cd myproj | ||
6737 | floss$ cvs watch add hello.c | ||
6738 | floss$ | ||
6739 | </pre> | ||
6740 | |||
6741 | <p>The last command, cvs watch add hello.c, tells CVS to notify jrandom if | ||
6742 | anyone else starts working on hello.c (that is, it adds jrandom to | ||
6743 | hello.c's watch list). For CVS to send notifications as soon as a file | ||
6744 | is being edited, the user who is editing it has to announce the fact by | ||
6745 | running cvs edit on the file first. CVS has no other way of knowing | ||
6746 | when someone starts working on a file. Once checkout is done, CVS isn't | ||
6747 | usually invoked until the next update or commit, which happens after the | ||
6748 | file has already been edited: | ||
6749 | |||
6750 | <pre>paste$ whoami | ||
6751 | qsmith | ||
6752 | paste$ cvs -q co myproj | ||
6753 | U myproj/README.txt | ||
6754 | U myproj/foo.gif | ||
6755 | U myproj/hello.c | ||
6756 | U myproj/a-subdir/whatever.c | ||
6757 | U myproj/a-subdir/subsubdir/fish.c | ||
6758 | U myproj/b-subdir/random.c | ||
6759 | paste$ cd myproj | ||
6760 | paste$ cvs edit hello.c | ||
6761 | paste$ emacs hello.c | ||
6762 | ... | ||
6763 | </pre> | ||
6764 | |||
6765 | <p>When qsmith runs cvs edit hello.c, CVS looks at the watch list for | ||
6766 | hello.c, sees that jrandom is on it, and sends email to jrandom telling | ||
6767 | her that qsmith has started editing the file. The email even appears to | ||
6768 | come from qsmith: | ||
6769 | |||
6770 | <pre>From: qsmith | ||
6771 | Subject: CVS notification | ||
6772 | To: jrandom | ||
6773 | Date: Sat, 17 Jul 1999 22:14:43 -0500 | ||
6774 | |||
6775 | myproj hello.c | ||
6776 | -- | ||
6777 | Triggered edit watch on /usr/local/newrepos/myproj | ||
6778 | By qsmith | ||
6779 | |||
6780 | Furthermore, every time that qsmith (or anyone) commits a new revision of hello.c, jrandom will receive another email: | ||
6781 | |||
6782 | myproj hello.c | ||
6783 | -- | ||
6784 | Triggered commit watch on /usr/local/newrepos/myproj | ||
6785 | By qsmith | ||
6786 | </pre> | ||
6787 | |||
6788 | <p>After receiving these emails, jrandom may want to update hello.c | ||
6789 | immediately to see what qsmith has done, or perhaps she'll email qsmith | ||
6790 | to find out why he's working on that file. Note that nothing forced | ||
6791 | qsmith to remember to run cvs edit - presumably he did it because he | ||
6792 | wanted jrandom to know what he was up to (anyway, even if he forgot to | ||
6793 | do cvs edit, his commits would still trigger notifications). The reason | ||
6794 | to use cvs edit is that it notifies watchers before you start to work on | ||
6795 | a file. The watchers can contact you if they think there may be a | ||
6796 | conflict, before you've wasted a lot of time. | ||
6797 | |||
6798 | <p>CVS assumes that anyone who runs cvs edit on a file wants to be added to | ||
6799 | the file's watch list, at least temporarily, in case someone else starts | ||
6800 | to edit it. When qsmith ran cvs edit, he became a watcher of hello.c. | ||
6801 | Both he and jrandom would have received notification if a third party | ||
6802 | had run cvs edit on that file (or committed it). | ||
6803 | |||
6804 | <p>However, CVS also assumes that the person editing the file only wants to | ||
6805 | be on its watch list while he or she is editing it. Such users are | ||
6806 | taken off the watch list when they're done editing. If they prefer to | ||
6807 | be permanent watchers of the file, they would have to run cvs watch add. | ||
6808 | CVS makes a default assumption that someone is done editing when he or | ||
6809 | she commits a file (until the next time, anyway). | ||
6810 | |||
6811 | <p>Anyone who gets on a file's watch list solely by virtue of having run | ||
6812 | <code>cvs edit</code> on that file is known as a <dfn>temporary watcher</dfn> | ||
6813 | and is taken off the watch list as soon as she commits a change to the | ||
6814 | file. If she wants to edit it again, she has to rerun <code>cvs edit</code>. | ||
6815 | |||
6816 | <p>CVS's assumption that the first commit ends the editing session is only | ||
6817 | a best guess, of course, because CVS doesn't know how many commits the | ||
6818 | person will need to finish their changes. The guess is probably | ||
6819 | accurate for <dfn>one-off</dfn> changes - changes where someone just needs | ||
6820 | to make one quick fix to a file and commit it. For more prolonged | ||
6821 | editing sessions involving several commits, users should add themselves | ||
6822 | permanently to the file's watch list: | ||
6823 | |||
6824 | <pre>paste$ cvs watch add hello.c | ||
6825 | paste$ cvs edit hello.c | ||
6826 | paste$ emacs hello.c | ||
6827 | ... | ||
6828 | paste$ cvs commit -m "print hello in Sanskrit" | ||
6829 | </pre> | ||
6830 | |||
6831 | <p>Even after the commit, qsmith remains a watcher of hello.c because he | ||
6832 | ran watch add on it. (By the way, qsmith will not receive notification | ||
6833 | of his own edits; only other watchers will. CVS is smart enough not to | ||
6834 | notify you about actions that you took.) | ||
6835 | |||
6836 | <p><hr> | ||
6837 | Node:<a name="Ending_An_Editing_Session">Ending An Editing Session</a>, | ||
6838 | Next:<a rel=next href="#Controlling_What_Actions_Are_Watched">Controlling What Actions Are Watched</a>, | ||
6839 | Previous:<a rel=previous href="#Using_Watches_In_Development">Using Watches In Development</a>, | ||
6840 | Up:<a rel=up href="#Watches__CVS_As_Telephone_">Watches (CVS As Telephone)</a> | ||
6841 | <br> | ||
6842 | |||
6843 | <h3>Ending An Editing Session</h3> | ||
6844 | |||
6845 | <p>If you don't want to commit but want to explicitly end an editing | ||
6846 | session, you can do so by running cvs unedit: | ||
6847 | |||
6848 | <pre>paste$ cvs unedit hello.c | ||
6849 | </pre> | ||
6850 | |||
6851 | <p>But beware! This does more than just notify all watchers that you're | ||
6852 | done editing - it also offers to revert any uncommitted changes that | ||
6853 | you've made to the file: | ||
6854 | |||
6855 | <pre>paste$ cvs unedit hello.c | ||
6856 | hello.c has been modified; revert changes? y | ||
6857 | paste$ | ||
6858 | </pre> | ||
6859 | |||
6860 | <p>If you answer <code>y</code>, CVS undoes all your changes and notifies | ||
6861 | watchers that you're not editing the file anymore. If you answer | ||
6862 | <code>n</code>, CVS keeps your changes and also keeps you registered as an | ||
6863 | editor of the file (so no notification goes out - in fact, it's as if | ||
6864 | you never ran <code>cvs unedit</code> at all). The possibility of CVS | ||
6865 | undoing all of your changes at a single keystroke is a bit scary, but | ||
6866 | the rationale is easy to understand: If you declare to the world that | ||
6867 | you're ending an editing session, then any changes you haven't committed | ||
6868 | are probably changes you don't mean to keep. At least, that's the way | ||
6869 | CVS sees it. Needless to say, be careful! | ||
6870 | |||
6871 | <p><hr> | ||
6872 | Node:<a name="Controlling_What_Actions_Are_Watched">Controlling What Actions Are Watched</a>, | ||
6873 | Next:<a rel=next href="#Finding_Out_Who_Is_Watching_What">Finding Out Who Is Watching What</a>, | ||
6874 | Previous:<a rel=previous href="#Ending_An_Editing_Session">Ending An Editing Session</a>, | ||
6875 | Up:<a rel=up href="#Watches__CVS_As_Telephone_">Watches (CVS As Telephone)</a> | ||
6876 | <br> | ||
6877 | |||
6878 | <h3>Controlling What Actions Are Watched</h3> | ||
6879 | |||
6880 | <p>By default, watchers are notified about three kinds of action: edits, | ||
6881 | commits, and unedits. However, if you only want to be notified about, | ||
6882 | say, commits, you can restrict notifications by adjusting your watch | ||
6883 | with the -a flag (a for action): | ||
6884 | |||
6885 | <pre>floss$ cvs watch add -a commit hello.c | ||
6886 | </pre> | ||
6887 | |||
6888 | <p>Or if you want to watch edits and commits but don't care about unedits, | ||
6889 | you could pass the -a flag twice: | ||
6890 | |||
6891 | <pre>floss$ cvs watch add -a edit -a commit hello.c | ||
6892 | </pre> | ||
6893 | |||
6894 | <p>Adding a watch with the -a flag will never cause any of your existing | ||
6895 | watches to be removed. If you were watching for all three kinds of | ||
6896 | actions on hello.c, running | ||
6897 | |||
6898 | <pre>floss$ cvs watch add -a commit hello.c | ||
6899 | </pre> | ||
6900 | |||
6901 | <p>has no effect - you'll still be a watcher for all three actions. To | ||
6902 | remove watches, you should run | ||
6903 | |||
6904 | <pre>floss$ cvs watch remove hello.c | ||
6905 | </pre> | ||
6906 | |||
6907 | <p>which is similar to add in that, by default, it removes your watches for | ||
6908 | all three actions. If you pass -a arguments, it removes only the | ||
6909 | watches you specify: | ||
6910 | |||
6911 | <pre>floss$ cvs watch remove -a commit hello.c | ||
6912 | </pre> | ||
6913 | |||
6914 | <p>This means that you want to stop receiving notifications about commits | ||
6915 | but continue to receive notifications about edits and unedits (assuming | ||
6916 | you were watching edits and unedits to begin with, that is). | ||
6917 | |||
6918 | <p>There are two special actions you can pass to the -a flag: all or none. | ||
6919 | The former means all actions that are eligible for watching (edits, | ||
6920 | commits, and unedits, as of this writing), and the latter means none of | ||
6921 | these. Because CVS's default behavior, in the absence of -a, is to | ||
6922 | watch all actions, and because watching none is the same as removing | ||
6923 | yourself from the watch list entirely, it's hard to imagine a situation | ||
6924 | in which it would be useful to specify either of these two special | ||
6925 | actions. However, cvs edit also takes the -a option, and in this case, | ||
6926 | it can be useful to specify all or none. For example, someone working | ||
6927 | on a file very briefly may not want to receive any notifications about | ||
6928 | what other people do with the file. Thus, this command | ||
6929 | |||
6930 | <pre>paste$ whoami | ||
6931 | qsmith | ||
6932 | paste$ cvs edit -a none README.txt | ||
6933 | </pre> | ||
6934 | |||
6935 | <p>causes watchers of README.txt to be notified that qsmith is about to | ||
6936 | work on it, but qsmith would not be added as a temporary watcher of | ||
6937 | README.txt during his editing session (which he normally would have | ||
6938 | been), because he asked not to watch any actions. | ||
6939 | |||
6940 | <p>Remember that you can only affect your own watches with the cvs watch | ||
6941 | command. You may stop watching a certain file yourself, but that won't | ||
6942 | change anyone else's watches. | ||
6943 | |||
6944 | <p><hr> | ||
6945 | Node:<a name="Finding_Out_Who_Is_Watching_What">Finding Out Who Is Watching What</a>, | ||
6946 | Next:<a rel=next href="#Reminding_People_To_Use_Watches">Reminding People To Use Watches</a>, | ||
6947 | Previous:<a rel=previous href="#Controlling_What_Actions_Are_Watched">Controlling What Actions Are Watched</a>, | ||
6948 | Up:<a rel=up href="#Watches__CVS_As_Telephone_">Watches (CVS As Telephone)</a> | ||
6949 | <br> | ||
6950 | |||
6951 | <h3>Finding Out Who Is Watching What</h3> | ||
6952 | |||
6953 | <p>Sometimes you may want to know who's watching before you even run cvs | ||
6954 | edit or want to see who is editing what without adding yourself to any | ||
6955 | watch lists. Or you may have forgotten exactly what your own status is. | ||
6956 | After setting and unsetting a few watches and committing some files, | ||
6957 | it's easy to lose track of what you're watching and editing. | ||
6958 | |||
6959 | <p>CVS provides two commands to show who's watching and who's editing files | ||
6960 | - cvs watchers and cvs editors: | ||
6961 | |||
6962 | <pre>floss$ whoami | ||
6963 | jrandom | ||
6964 | floss$ cvs watch add hello.c | ||
6965 | floss$ cvs watchers hello.c | ||
6966 | hello.c jrandom edit unedit commit | ||
6967 | floss$ cvs watch remove -a unedit hello.c | ||
6968 | floss$ cvs watchers hello.c | ||
6969 | hello.c jrandom edit commit | ||
6970 | floss$ cvs watch add README.txt | ||
6971 | floss$ cvs watchers | ||
6972 | README.txt jrandom edit unedit commit | ||
6973 | hello.c jrandom edit commit | ||
6974 | floss$ | ||
6975 | </pre> | ||
6976 | |||
6977 | <p>Notice that the last cvs watchers command doesn't specify any files and, | ||
6978 | therefore, shows watchers for all files (all those that have watchers, | ||
6979 | that is). | ||
6980 | |||
6981 | <p>All of the watch and edit commands have this behavior in common with | ||
6982 | other CVS commands. If you specify file names, they act on those files. | ||
6983 | If you specify directory names, they act on everything in that directory | ||
6984 | and its subdirectories. If you don't specify anything, they act on the | ||
6985 | current directory and everything underneath it, to as many levels of | ||
6986 | depth as are available. For example (continuing with the same session): | ||
6987 | |||
6988 | <pre>floss$ cvs watch add a-subdir/whatever.c | ||
6989 | floss$ cvs watchers | ||
6990 | README.txt jrandom edit unedit commit | ||
6991 | hello.c jrandom edit commit | ||
6992 | a-subdir/whatever.c jrandom edit unedit commit | ||
6993 | floss$ cvs watch add | ||
6994 | floss$ cvs watchers | ||
6995 | README.txt jrandom edit unedit commit | ||
6996 | foo.gif jrandom edit unedit commit | ||
6997 | hello.c jrandom edit commit unedit | ||
6998 | a-subdir/whatever.c jrandom edit unedit commit | ||
6999 | a-subdir/subsubdir/fish.c jrandom edit unedit commit | ||
7000 | b-subdir/random.c jrandom edit unedit commit | ||
7001 | floss$ | ||
7002 | </pre> | ||
7003 | |||
7004 | <p>The last two commands made jrandom a watcher of every file in the | ||
7005 | project and then showed the watch list for every file in the project, | ||
7006 | respectively. The output of <code>cvs watchers</code> doesn't always line | ||
7007 | up perfectly in columns because it mixes tab stops with information of | ||
7008 | varying length, but the lines are consistently formatted: | ||
7009 | |||
7010 | <pre>[FILENAME] [whitespace] WATCHER [whitespace] ACTIONS-BEING-WATCHED... | ||
7011 | </pre> | ||
7012 | |||
7013 | <p>Now watch what happens when qsmith starts to edit one of the files: | ||
7014 | |||
7015 | <pre>paste$ cvs edit hello.c | ||
7016 | paste$ cvs watchers | ||
7017 | README.txt jrandom edit unedit commit | ||
7018 | foo.gif jrandom edit unedit commit | ||
7019 | hello.c jrandom edit commit unedit | ||
7020 | qsmith tedit tunedit tcommit | ||
7021 | a-subdir/whatever.c jrandom edit unedit commit | ||
7022 | a-subdir/subsubdir/fish.c jrandom edit unedit commit | ||
7023 | b-subdir/random.c jrandom edit unedit commit | ||
7024 | </pre> | ||
7025 | |||
7026 | <p>The file hello.c has acquired another watcher: qsmith himself (note that | ||
7027 | the file name is not repeated but is left as white space at the | ||
7028 | beginning of the line - this would be important if you ever wanted to | ||
7029 | write a program that parses watchers output). Because he's editing | ||
7030 | hello.c, qsmith has a <dfn>temporary watch</dfn> on the file; it goes away as | ||
7031 | soon as he commits a new revision of hello.c. The prefix <code>t</code> in | ||
7032 | front of each of the actions indicates that these are temporary watches. | ||
7033 | If qsmith adds himself as a regular watcher of hello.c as well | ||
7034 | |||
7035 | <pre>paste$ cvs watch add hello.c | ||
7036 | README.txt jrandom edit unedit commit | ||
7037 | foo.gif jrandom edit unedit commit | ||
7038 | hello.c jrandom edit commit unedit | ||
7039 | qsmith tedit tunedit tcommit edit unedit commit | ||
7040 | a-subdir/whatever.c jrandom edit unedit commit | ||
7041 | a-subdir/subsubdir/fish.c jrandom edit unedit commit | ||
7042 | b-subdir/random.c jrandom edit unedit commit | ||
7043 | </pre> | ||
7044 | |||
7045 | <p>he is listed as both a temporary watcher and a permanent watcher. You | ||
7046 | may think that the permanent watch status would simply override the | ||
7047 | temporary, so that the line would look like this: | ||
7048 | |||
7049 | <pre> qsmith edit unedit commit | ||
7050 | </pre> | ||
7051 | |||
7052 | <p>However, CVS can't just replace the temporary watches because it doesn't | ||
7053 | know in what order things happen. Will qsmith remove himself from the | ||
7054 | permanent watch list before ending his editing session, or will he | ||
7055 | finish the edits while still remaining a watcher? If the former, the | ||
7056 | edit/unedit/commit actions disappear while the tedit/tunedit/tcommit | ||
7057 | ones remain; if the latter, the reverse would happen. | ||
7058 | |||
7059 | <p>Anyway, that side of the watch list is usually not of great concern. | ||
7060 | Most of the time, what you want to do is run | ||
7061 | |||
7062 | <pre>floss$ cvs watchers | ||
7063 | </pre> | ||
7064 | |||
7065 | <p>or | ||
7066 | |||
7067 | <pre>floss$ cvs editors | ||
7068 | </pre> | ||
7069 | |||
7070 | <p>from the top level of a project and see who's doing what. You don't | ||
7071 | really need to know the details of who cares about what actions: the | ||
7072 | important things are people and files. | ||
7073 | |||
7074 | <p><hr> | ||
7075 | Node:<a name="Reminding_People_To_Use_Watches">Reminding People To Use Watches</a>, | ||
7076 | Next:<a rel=next href="#What_Watches_Look_Like_In_The_Repository">What Watches Look Like In The Repository</a>, | ||
7077 | Previous:<a rel=previous href="#Finding_Out_Who_Is_Watching_What">Finding Out Who Is Watching What</a>, | ||
7078 | Up:<a rel=up href="#Watches__CVS_As_Telephone_">Watches (CVS As Telephone)</a> | ||
7079 | <br> | ||
7080 | |||
7081 | <h3>Reminding People To Use Watches</h3> | ||
7082 | |||
7083 | <p>You've probably noticed that the watch features are utterly dependent on | ||
7084 | the cooperation of all the developers. If someone just starts editing a | ||
7085 | file without first running cvs edit, no one else will know about it | ||
7086 | until the changes get committed. Because cvs edit is an additional | ||
7087 | step, not part of the normal development routine, people can easily | ||
7088 | forget to do it. | ||
7089 | |||
7090 | <p>Although CVS can't force someone to use cvs edit, it does have a | ||
7091 | mechanism for reminding people to do so - the watch on command: | ||
7092 | |||
7093 | <pre>floss$ cvs -q co myproj | ||
7094 | U myproj/README.txt | ||
7095 | U myproj/foo.gif | ||
7096 | U myproj/hello.c | ||
7097 | U myproj/a-subdir/whatever.c | ||
7098 | U myproj/a-subdir/subsubdir/fish.c | ||
7099 | U myproj/b-subdir/random.c | ||
7100 | floss$ cd myproj | ||
7101 | floss$ cvs watch on hello.c | ||
7102 | floss$ | ||
7103 | </pre> | ||
7104 | |||
7105 | <p>By running cvs watch on hello.c, jrandom causes future checkouts of | ||
7106 | myproj to create hello.c read-only in the working copy. When qsmith | ||
7107 | tries to work on it, he'll discover that it's read-only and be reminded | ||
7108 | to run cvs edit first: | ||
7109 | |||
7110 | <pre>paste$ cvs -q co myproj | ||
7111 | U myproj/README.txt | ||
7112 | U myproj/foo.gif | ||
7113 | U myproj/hello.c | ||
7114 | U myproj/a-subdir/whatever.c | ||
7115 | U myproj/a-subdir/subsubdir/fish.c | ||
7116 | U myproj/b-subdir/random.c | ||
7117 | paste$ cd myproj | ||
7118 | paste$ ls -l | ||
7119 | total 6 | ||
7120 | drwxr-xr-x 2 qsmith users 1024 Jul 19 01:06 CVS/ | ||
7121 | -rw-r--r-- 1 qsmith users 38 Jul 12 11:28 README.txt | ||
7122 | drwxr-xr-x 4 qsmith users 1024 Jul 19 01:06 a-subdir/ | ||
7123 | drwxr-xr-x 3 qsmith users 1024 Jul 19 01:06 b-subdir/ | ||
7124 | -rw-r--r-- 1 qsmith users 673 Jun 20 22:47 foo.gif | ||
7125 | -r--r--r-- 1 qsmith users 188 Jul 18 01:20 hello.c | ||
7126 | paste$ | ||
7127 | </pre> | ||
7128 | |||
7129 | <p>When he does so, the file becomes read-write. He can then edit it, and | ||
7130 | when he commits, it becomes read-only again: | ||
7131 | |||
7132 | <pre>paste$ cvs edit hello.c | ||
7133 | paste$ ls -l hello.c | ||
7134 | -rw-r--r-- 1 qsmith users 188 Jul 18 01:20 hello.c | ||
7135 | paste$ emacs hello.c | ||
7136 | ... | ||
7137 | paste$ cvs commit -m "say hello in Aramaic" hello.c | ||
7138 | Checking in hello.c; | ||
7139 | /usr/local/newrepos/myproj/hello.c,v <-- hello.c | ||
7140 | new revision: 1.12; previous revision: 1.11 | ||
7141 | done | ||
7142 | paste$ ls -l hello.c | ||
7143 | -r--r--r-- 1 qsmith users 210 Jul 19 01:12 hello.c | ||
7144 | paste$ | ||
7145 | </pre> | ||
7146 | |||
7147 | <p>His edit and commit will send notification to all watchers of hello.c. | ||
7148 | Note that jrandom isn't necessarily one of them. By running cvs watch | ||
7149 | on hello.c, jrandom did not add herself to the watch list for that file; | ||
7150 | she merely specified that it should be checked out read-only. People | ||
7151 | who want to watch a file must remember to add themselves to its watch | ||
7152 | list - CVS cannot help them with that. | ||
7153 | |||
7154 | <p>Turning on watches for a single file may be the exception. Generally, | ||
7155 | it's more common to turn on watches project-wide: | ||
7156 | |||
7157 | <pre>floss$ cvs -q co myproj | ||
7158 | U myproj/README.txt | ||
7159 | U myproj/foo.gif | ||
7160 | U myproj/hello.c | ||
7161 | U myproj/a-subdir/whatever.c | ||
7162 | U myproj/a-subdir/subsubdir/fish.c | ||
7163 | U myproj/b-subdir/random.c | ||
7164 | floss$ cd myproj | ||
7165 | floss$ cvs watch on | ||
7166 | floss$ | ||
7167 | </pre> | ||
7168 | |||
7169 | <p>This action amounts to announcing a policy decision for the entire | ||
7170 | project: "Please use cvs edit to tell watchers what you're working on, | ||
7171 | and feel free to watch any file you're interested in or responsible | ||
7172 | for." Every file in the project will be checked out read-only, and thus | ||
7173 | people will be reminded that they're expected to use cvs edit before | ||
7174 | working on anything. | ||
7175 | |||
7176 | <p>Curiously, although checkouts of watched files make them read-only, | ||
7177 | updates do not. If qsmith had checked out his working copy before | ||
7178 | jrandom ran cvs watch on, his files would have stayed read-write, | ||
7179 | remaining so even after updates. However, any file he commits after | ||
7180 | jrandom turns watching on will become read-only. If jrandom turns off | ||
7181 | watches | ||
7182 | |||
7183 | <pre>floss$ cvs watch off | ||
7184 | </pre> | ||
7185 | |||
7186 | <p>qsmith's read-only files do not magically become read-write. On the | ||
7187 | other hand, after he commits one, it will not revert to read-only again | ||
7188 | (as it would have if watches were still on). | ||
7189 | |||
7190 | <p>It's worth noting that qsmith could, were he truly devious, make files | ||
7191 | in his working copy writeable by using the standard Unix <code>chmod</code> | ||
7192 | command, bypassing <code>cvs edit</code> entirely | ||
7193 | |||
7194 | <pre>paste$ chmod u+w hello.c | ||
7195 | </pre> | ||
7196 | |||
7197 | <p>or if he wanted to get everything in one fell swoop: | ||
7198 | |||
7199 | <pre>paste$ chmod -R u+w . | ||
7200 | </pre> | ||
7201 | |||
7202 | <p>There is nothing CVS can do about this. Working copies by their nature | ||
7203 | are private sandboxes - the watch features can open them up to public | ||
7204 | scrutiny a little bit, but only as far as the developer permits. Only | ||
7205 | when a developer does something that affects the repository (such as | ||
7206 | commits) is her privacy unconditionally lost. | ||
7207 | |||
7208 | <p>The relationship among watch add, watch remove, watch on, and watch off | ||
7209 | probably seems a bit confusing. It may help to summarize the overall | ||
7210 | scheme: <code>add</code> and <code>remove</code> are about adding or removing users | ||
7211 | from a file's watch list; they don't have anything to do with whether | ||
7212 | files are read-only on checkout or after commits. <code>on</code> and | ||
7213 | <code>off</code> are only about file permissions. They don't have anything to | ||
7214 | do with who is on a file's watch list; rather, they are tools to help | ||
7215 | remind developers of the watch policy by causing working-copy files to | ||
7216 | become read-only. | ||
7217 | |||
7218 | <p>All of this may seem a little inconsistent. In a sense, using watches | ||
7219 | works against the grain of CVS. It deviates from the idealized universe | ||
7220 | of multiple developers editing freely in their working copies, hidden | ||
7221 | from each other until they choose to commit. With watches, CVS gives | ||
7222 | developers convenient shortcuts for informing each other of what's going | ||
7223 | on in their working copies; however, it has no way to enforce | ||
7224 | observation policies, nor does it have a definitive concept of what | ||
7225 | constitutes an editing session. Nevertheless, watches can be helpful in | ||
7226 | certain circumstances if developers work with them. | ||
7227 | |||
7228 | <p><hr> | ||
7229 | Node:<a name="What_Watches_Look_Like_In_The_Repository">What Watches Look Like In The Repository</a>, | ||
7230 | Previous:<a rel=previous href="#Reminding_People_To_Use_Watches">Reminding People To Use Watches</a>, | ||
7231 | Up:<a rel=up href="#Watches__CVS_As_Telephone_">Watches (CVS As Telephone)</a> | ||
7232 | <br> | ||
7233 | |||
7234 | <h3>What Watches Look Like In The Repository</h3> | ||
7235 | |||
7236 | <p>In the interests of stamping out black boxes and needless mystery, let's | ||
7237 | take a quick look at how watches are implemented in the repository. | ||
7238 | We'll only take a quick look, though, because it's not pretty. | ||
7239 | |||
7240 | <p>When you set a watch | ||
7241 | |||
7242 | <pre>floss$ pwd | ||
7243 | /home/jrandom/myproj | ||
7244 | floss$ cvs watch add hello.c | ||
7245 | floss$ cvs watchers | ||
7246 | hello.c jrandom edit unedit commit | ||
7247 | floss$ | ||
7248 | </pre> | ||
7249 | |||
7250 | <p>CVS records it in the special file, <code>CVS/fileattr</code>, in the | ||
7251 | appropriate repository subdirectory: | ||
7252 | |||
7253 | <pre>floss$ cd /usr/local/newrepos | ||
7254 | floss$ ls | ||
7255 | CVSROOT/ myproj/ | ||
7256 | floss$ cd myproj | ||
7257 | floss$ ls | ||
7258 | CVS/ a-subdir/ foo.gif,v | ||
7259 | README.txt,v b-subdir/ hello.c,v | ||
7260 | floss$ cd CVS | ||
7261 | floss$ ls | ||
7262 | fileattr | ||
7263 | floss$ cat fileattr | ||
7264 | Fhello.c _watchers=jrandom>edit+unedit+commit | ||
7265 | floss$ | ||
7266 | </pre> | ||
7267 | |||
7268 | <p>The fact that fileattr is stored in a CVS subdirectory in the repository | ||
7269 | does not mean that the repository has become a working copy. It's | ||
7270 | simply that the name <code>CVS</code> was already reserved for bookkeeping in | ||
7271 | the working copy, so CVS can be sure no project will ever need a | ||
7272 | subdirectory of that name in the repository. | ||
7273 | |||
7274 | <p>I won't describe the format of <code>fileattr</code> formally; you can | ||
7275 | probably grok it pretty well just by watching it change from command to | ||
7276 | command: | ||
7277 | |||
7278 | <pre>floss$ cvs watch add hello.c | ||
7279 | floss$ cat /usr/local/newrepos/myproj/CVS/fileattr | ||
7280 | Fhello.c _watchers=jrandom>edit+unedit+commit | ||
7281 | floss$ cvs watch add README.txt | ||
7282 | floss$ cat /usr/local/newrepos/myproj/CVS/fileattr | ||
7283 | Fhello.c _watchers=jrandom>edit+unedit+commit | ||
7284 | FREADME.txt _watchers=jrandom>edit+unedit+commit | ||
7285 | floss$ cvs watch on hello.c | ||
7286 | floss$ cat /usr/local/newrepos/myproj/CVS/fileattr | ||
7287 | Fhello.c _watchers=jrandom>edit+unedit+commit;_watched= | ||
7288 | FREADME.txt _watchers=jrandom>edit+unedit+commit | ||
7289 | floss$ cvs watch remove hello.c | ||
7290 | floss$ cat /usr/local/newrepos/myproj/CVS/fileattr | ||
7291 | Fhello.c _watched= | ||
7292 | FREADME.txt _watchers=jrandom>edit+unedit+commit | ||
7293 | floss$ cvs watch off hello.c | ||
7294 | floss$ cat /usr/local/newrepos/myproj/CVS/fileattr | ||
7295 | FREADME.txt _watchers=jrandom>edit+unedit+commit | ||
7296 | floss$ | ||
7297 | </pre> | ||
7298 | |||
7299 | <p>Edit records are stored in fileattr, too. Here's what happens when | ||
7300 | qsmith adds himself as an editor: | ||
7301 | |||
7302 | <pre>paste$ cvs edit hello.c | ||
7303 | |||
7304 | floss$ cat /usr/local/newrepos/myproj/CVS/fileattr | ||
7305 | Fhello.c _watched=;_editors=qsmith>Tue Jul 20 04:53:23 1999 GMT+floss\ | ||
7306 | +/home/qsmith/myproj;_watchers=qsmith>tedit+tunedit+tcommit | ||
7307 | FREADME.txt _watchers=jrandom>edit+unedit+commit | ||
7308 | </pre> | ||
7309 | |||
7310 | <p>Finally, note that CVS removes fileattr and the CVS subdirectory when | ||
7311 | there are no more watchers or editors for any of the files in that | ||
7312 | directory: | ||
7313 | |||
7314 | <pre>paste$ cvs unedit | ||
7315 | |||
7316 | floss$ cvs watch off | ||
7317 | floss$ cvs watch remove | ||
7318 | floss$ cat /usr/local/newrepos/myproj/CVS/fileattr | ||
7319 | cat: /usr/local/newrepos/myproj/CVS/fileattr: No such file or directory | ||
7320 | floss$ | ||
7321 | </pre> | ||
7322 | |||
7323 | <p>It should be clear after this brief exposure that the details of parsing | ||
7324 | fileattr format are better left to CVS. The main reason to have a basic | ||
7325 | understanding of the format - aside from the inherent satisfaction of | ||
7326 | knowing what's going on behind the curtain - is if you try to write an | ||
7327 | extension to the CVS watch features or debug some problem in them. It's | ||
7328 | sufficient to know that you shouldn't be alarmed if you see CVS/ | ||
7329 | subdirectories popping up in your repository. They're the only safe | ||
7330 | place CVS has to store meta-information such as watch lists. | ||
7331 | |||
7332 | <p><hr> | ||
7333 | Node:<a name="Log_Messages_And_Commit_Emails">Log Messages And Commit Emails</a>, | ||
7334 | Next:<a rel=next href="#Changing_A_Log_Message_After_Commit">Changing A Log Message After Commit</a>, | ||
7335 | Previous:<a rel=previous href="#Watches__CVS_As_Telephone_">Watches (CVS As Telephone)</a>, | ||
7336 | Up:<a rel=up href="#Advanced_CVS">Advanced CVS</a> | ||
7337 | <br> | ||
7338 | |||
7339 | <h2>Log Messages And Commit Emails</h2> | ||
7340 | |||
7341 | <p>Commit emails are notices sent out at commit time, showing the log | ||
7342 | message and files involved in the commit. They usually go to all | ||
7343 | project participants and sometimes to other interested parties. The | ||
7344 | details of setting up commit emails were covered in <a href="#Repository_Administration">Repository Administration</a>, so I won't repeat them here. I have noticed, however, | ||
7345 | that commit emails can sometimes result in unexpected side effects to | ||
7346 | projects, effects that you may want to take into account if you set up | ||
7347 | commit emails for your project. | ||
7348 | |||
7349 | <p>First, be prepared for the messages to be mostly ignored. Whether | ||
7350 | people read them depends, at least partly, on the frequency of commits | ||
7351 | in your project. Do developers tend to commit one big change at the end | ||
7352 | of the day, or many small changes throughout the day? The closer your | ||
7353 | project is to the latter, the thicker the barrage of tiny commit notices | ||
7354 | raining down on the developers all day long, and the less inclined they | ||
7355 | will be to pay attention to each message. | ||
7356 | |||
7357 | <p>This doesn't mean the notices aren't useful, just that you shouldn't | ||
7358 | count on every person reading every message. It's still a convenient | ||
7359 | way for people to keep tabs on who's doing what (without the | ||
7360 | intrusiveness of watches). When the emails go to a publicly | ||
7361 | subscribable mailing list, they are a wonderful mechanism for giving | ||
7362 | interested users (and future developers!) a chance to see what happens | ||
7363 | in the code on a daily basis. | ||
7364 | |||
7365 | <p>You may want to consider having a designated developer who watches all | ||
7366 | log messages and has an overview of activity across the entire project | ||
7367 | (of course, a good project leader will probably be doing this anyway). | ||
7368 | If there are clear divisions of responsibility - say, certain | ||
7369 | developers are "in charge of" certain subdirectories of the project - | ||
7370 | you could do some fancy scripting in CVSROOT/loginfo to see that each | ||
7371 | responsible party receives specially marked notices of changes made in | ||
7372 | their area. This will help ensure that the developers will at least | ||
7373 | read the email that pertains to their subdirectories. | ||
7374 | |||
7375 | <p>A more interesting side effect happens when commit emails aren't | ||
7376 | ignored. People start to use them as a realtime communications method. | ||
7377 | Here's the kind of log message that can result: | ||
7378 | |||
7379 | <pre>Finished feedback form; fixed the fonts and background colors on the | ||
7380 | home page. Whew! Anyone want to go to Mon Lung for lunch? | ||
7381 | </pre> | ||
7382 | |||
7383 | <p>There's nothing wrong with this, and it makes the logs more fun to read | ||
7384 | over later. However, people need to be aware that log messages, such as | ||
7385 | the following, are not only distributed by email but is also preserved | ||
7386 | forever in the project's history. For example, griping about customer | ||
7387 | specifications is a frequent pastime among programmers; it's not hard to | ||
7388 | imagine someone committing a log message like this one, knowing that the | ||
7389 | other programmers will soon see it in their email: | ||
7390 | |||
7391 | <pre>Truncate four-digit years to two-digits in input. What the customer | ||
7392 | wants, the customer gets, no matter how silly & wrong. Sigh. | ||
7393 | </pre> | ||
7394 | |||
7395 | <p>This makes for an amusing email, but what happens if the customer | ||
7396 | reviews the logs someday? (I'll bet similar concerns have led more than | ||
7397 | one site to set up CVSROOT/loginfo so that it invokes scripts to guard | ||
7398 | against offensive words in log messages!) | ||
7399 | |||
7400 | <p>The overall effect of commit emails seems to be that people become less | ||
7401 | willing to write short or obscure log messages, which is probably a good | ||
7402 | thing. However, they may need to be reminded that their audience is | ||
7403 | anyone who might ever read the logs, not just the people receiving | ||
7404 | commit emails. | ||
7405 | |||
7406 | <p><hr> | ||
7407 | Node:<a name="Changing_A_Log_Message_After_Commit">Changing A Log Message After Commit</a>, | ||
7408 | Next:<a rel=next href="#Getting_Rid_Of_A_Working_Copy">Getting Rid Of A Working Copy</a>, | ||
7409 | Previous:<a rel=previous href="#Log_Messages_And_Commit_Emails">Log Messages And Commit Emails</a>, | ||
7410 | Up:<a rel=up href="#Advanced_CVS">Advanced CVS</a> | ||
7411 | <br> | ||
7412 | |||
7413 | <h2>Changing A Log Message After Commit</h2> | ||
7414 | |||
7415 | <p>Just in case someone does commit a regrettable log message, CVS enables | ||
7416 | you to rewrite logs after they've been committed. It's done with the -m | ||
7417 | option to the admin command (this command is covered in more detail | ||
7418 | later in this chapter) and allows you to change one log message (per | ||
7419 | revision, per file) at a time. Here's how it works: | ||
7420 | |||
7421 | <pre>floss$ cvs admin -m 1.7:"Truncate four-digit years to two in input." date.c | ||
7422 | RCS file: /usr/local/newrepos/someproj/date.c,v | ||
7423 | done | ||
7424 | floss$ | ||
7425 | </pre> | ||
7426 | |||
7427 | <p>The original, offensive log message that was committed with revision 1.7 | ||
7428 | has been replaced with a perfectly innocent - albeit duller - message. | ||
7429 | Don't forget the colon separating the revision number from the new log | ||
7430 | message. | ||
7431 | |||
7432 | <p>If the new log message consists of multiple lines, put it in a file and | ||
7433 | do this: | ||
7434 | |||
7435 | <pre>floss$ cvs admin -m 1.7:"`cat new-log-message.txt`" date.c | ||
7436 | </pre> | ||
7437 | |||
7438 | <p>(This example was sent in by Peter Ross <peter.ross@miscrit.be>; note | ||
7439 | that it only works for Unix users.) | ||
7440 | |||
7441 | <p>If the bad message was committed into multiple files, you'll have to run | ||
7442 | cvs admin separately for each one, because the revision number is | ||
7443 | different for each file. Therefore, this is one of the few commands in | ||
7444 | CVS that requires you to pass a single file name as argument: | ||
7445 | |||
7446 | <pre>floss$ cvs admin -m 1.2:"very boring log message" hello.c README.txt foo.gif | ||
7447 | cvs admin: while processing more than one file: | ||
7448 | cvs [admin aborted]: attempt to specify a numeric revision | ||
7449 | floss$ | ||
7450 | </pre> | ||
7451 | |||
7452 | <p>Confusingly, you get the same error if you pass no file names (because | ||
7453 | CVS then assumes all the files in the current directory and below are | ||
7454 | implied arguments): | ||
7455 | |||
7456 | <pre>floss$ cvs admin -m 1.2:"very boring log message" | ||
7457 | cvs admin: while processing more than one file: | ||
7458 | cvs [admin aborted]: attempt to specify a numeric revision | ||
7459 | floss$ | ||
7460 | </pre> | ||
7461 | |||
7462 | <p>(As is unfortunately often the case with CVS error messages, you have to | ||
7463 | see things from CVS's point of view before the message makes sense!) | ||
7464 | |||
7465 | <p>Invoking <code>admin -m</code> actually changes the project's history, so | ||
7466 | use it with care. There will be no record that the log message was ever | ||
7467 | changed - it will simply appear as if that revision had been originally | ||
7468 | committed with the new log message. No trace of the old message will be | ||
7469 | left anywhere (unless you saved the original commit email). | ||
7470 | |||
7471 | <p>Although its name might seem to imply that only the designated CVS | ||
7472 | administrator can use it, in fact anyone can run <code>cvs admin</code>, | ||
7473 | as long as they have write access to the project in question. | ||
7474 | Nevertheless, it is best used with caution; the ability to change log | ||
7475 | messages is mild compared with other potentially damaging things it can | ||
7476 | do. See <a href="#CVS_Reference">CVS Reference</a> for more about <code>admin</code>, as well as a | ||
7477 | way to restrict its use. | ||
7478 | |||
7479 | <p><hr> | ||
7480 | Node:<a name="Getting_Rid_Of_A_Working_Copy">Getting Rid Of A Working Copy</a>, | ||
7481 | Next:<a rel=next href="#History_--_A_Summary_Of_Repository_Activity">History -- A Summary Of Repository Activity</a>, | ||
7482 | Previous:<a rel=previous href="#Changing_A_Log_Message_After_Commit">Changing A Log Message After Commit</a>, | ||
7483 | Up:<a rel=up href="#Advanced_CVS">Advanced CVS</a> | ||
7484 | <br> | ||
7485 | |||
7486 | <h2>Getting Rid Of A Working Copy</h2> | ||
7487 | |||
7488 | <p>In typical CVS usage, the way to get rid of a working copy directory | ||
7489 | tree is to remove it like any other directory tree: | ||
7490 | |||
7491 | <pre>paste$ rm -rf myproj | ||
7492 | </pre> | ||
7493 | |||
7494 | <p>However, if you eliminate your working copy this way, other developers | ||
7495 | will not know that you have stopped using it. CVS provides a command to | ||
7496 | relinquish a working copy explicitly. Think of release as the opposite | ||
7497 | of checkout - you're telling the repository that you're done with the | ||
7498 | working copy now. Like checkout, release is invoked from the parent | ||
7499 | directory of the tree: | ||
7500 | |||
7501 | <pre>paste$ pwd | ||
7502 | /home/qsmith/myproj | ||
7503 | paste$ cd .. | ||
7504 | paste$ ls | ||
7505 | myproj | ||
7506 | paste$ cvs release myproj | ||
7507 | You have [0] altered files in this repository. | ||
7508 | Are you sure you want to release directory 'myproj': y | ||
7509 | paste$ | ||
7510 | </pre> | ||
7511 | |||
7512 | <p>If there are any uncommitted changes in the repository, the release | ||
7513 | fails, meaning that it just lists the modified files and otherwise has | ||
7514 | no effect. Assuming the tree is clean (totally up to date), release | ||
7515 | records in the repository that the working copy has been released. | ||
7516 | |||
7517 | <p>You can also have release automatically delete the working tree for you, | ||
7518 | by passing the -d flag: | ||
7519 | |||
7520 | <pre>paste$ ls | ||
7521 | myproj | ||
7522 | paste$ cvs release -d myproj | ||
7523 | You have [0] altered files in this repository. | ||
7524 | Are you sure you want to release (and delete) directory 'myproj: y | ||
7525 | paste$ ls | ||
7526 | paste$ | ||
7527 | </pre> | ||
7528 | |||
7529 | <p>As of CVS version 1.10.6, the release command is not able to deduce the | ||
7530 | repository's location by examining the working copy (this is because | ||
7531 | release is invoked from above the working copy, not within it). You | ||
7532 | must pass the <code>-d <REPOS></code> global option or make sure that your | ||
7533 | CVSROOT environment variable is set correctly. (This bug may be fixed | ||
7534 | in future versions of CVS.) | ||
7535 | |||
7536 | <p>The Cederqvist claims that if you use release instead of just deleting | ||
7537 | the working tree, people with watches set on the released files will be | ||
7538 | notified just as if you had run <code>unedit</code>. However, I tried to | ||
7539 | verify this experimentally, and it does not seem to be true. | ||
7540 | |||
7541 | <p><hr> | ||
7542 | Node:<a name="History_--_A_Summary_Of_Repository_Activity">History -- A Summary Of Repository Activity</a>, | ||
7543 | Next:<a rel=next href="#Annotations_--_A_Detailed_View_Of_Project_Activity">Annotations -- A Detailed View Of Project Activity</a>, | ||
7544 | Previous:<a rel=previous href="#Getting_Rid_Of_A_Working_Copy">Getting Rid Of A Working Copy</a>, | ||
7545 | Up:<a rel=up href="#Advanced_CVS">Advanced CVS</a> | ||
7546 | <br> | ||
7547 | |||
7548 | <h2>History - A Summary Of Repository Activity</h2> | ||
7549 | |||
7550 | <p>In <a href="#Repository_Administration">Repository Administration</a>, I briefly mentioned the cvs history | ||
7551 | command. This command displays a summary of all checkouts, commits, | ||
7552 | updates, rtags, and releases done in the repository (at least, since | ||
7553 | logging was enabled by the creation of the CVSROOT/history file in the | ||
7554 | repository). You can control the format and contents of the summary | ||
7555 | with various options. | ||
7556 | |||
7557 | <p>The first step is to make sure that logging is enabled in your | ||
7558 | repository. The repository administrator should first make sure there | ||
7559 | is a history file | ||
7560 | |||
7561 | <pre>floss$ cd /usr/local/newrepos/CVSROOT | ||
7562 | floss$ ls -l history | ||
7563 | ls: history: No such file or directory | ||
7564 | floss$ | ||
7565 | </pre> | ||
7566 | |||
7567 | <p>and if there isn't one, create it, as follows: | ||
7568 | |||
7569 | <pre>floss$ touch history | ||
7570 | floss$ ls -l history | ||
7571 | -rw-r--r-- 1 jrandom cvs 0 Jul 22 14:57 history | ||
7572 | floss$ | ||
7573 | </pre> | ||
7574 | |||
7575 | <p>This history file also needs to be writeable by everyone who uses the | ||
7576 | repository, otherwise they'll get an error every time they try to run a | ||
7577 | CVS command that modifies that file. The easiest way is simply to make | ||
7578 | the file world-writeable: | ||
7579 | |||
7580 | <pre>floss$ chmod a+rw history | ||
7581 | floss$ ls -l history | ||
7582 | -rw-rw-rw- 1 jrandom cvs 0 Jul 22 14:57 history | ||
7583 | floss$ | ||
7584 | </pre> | ||
7585 | |||
7586 | <p>If the repository was created with the <code>cvs init</code> command, the | ||
7587 | history file already exists. You may still have to fix its permissions, | ||
7588 | however. | ||
7589 | |||
7590 | <p>The rest of these examples assume that history logging has been enabled | ||
7591 | for a while, so that data has had time to accumulate in the history | ||
7592 | file. | ||
7593 | |||
7594 | <p>The output of cvs history is somewhat terse (it's probably intended to | ||
7595 | be parsed by programs rather than humans, although it is readable with a | ||
7596 | little study). Let's run it once and see what we get: | ||
7597 | |||
7598 | <pre>paste$ pwd | ||
7599 | /home/qsmith/myproj | ||
7600 | paste$ cvs history -e -a | ||
7601 | O 07/25 15:14 +0000 qsmith myproj =mp= ~/* | ||
7602 | M 07/25 15:16 +0000 qsmith 1.14 hello.c myproj == ~/mp | ||
7603 | U 07/25 15:21 +0000 qsmith 1.14 README.txt myproj == ~/mp | ||
7604 | G 07/25 15:21 +0000 qsmith 1.15 hello.c myproj == ~/mp | ||
7605 | A 07/25 15:22 +0000 qsmith 1.1 goodbye.c myproj == ~/mp | ||
7606 | M 07/25 15:23 +0000 qsmith 1.16 hello.c myproj == ~/mp | ||
7607 | M 07/25 15:26 +0000 qsmith 1.17 hello.c myproj == ~/mp | ||
7608 | U 07/25 15:29 +0000 qsmith 1.2 goodbye.c myproj == ~/mp | ||
7609 | G 07/25 15:29 +0000 qsmith 1.18 hello.c myproj == ~/mp | ||
7610 | M 07/25 15:30 +0000 qsmith 1.19 hello.c myproj == ~/mp | ||
7611 | O 07/23 03:45 +0000 jrandom myproj =myproj= ~/src/* | ||
7612 | F 07/23 03:48 +0000 jrandom =myproj= ~/src/* | ||
7613 | F 07/23 04:06 +0000 jrandom =myproj= ~/src/* | ||
7614 | M 07/25 15:12 +0000 jrandom 1.13 README.txt myproj == ~/src/myproj | ||
7615 | U 07/25 15:17 +0000 jrandom 1.14 hello.c myproj == ~/src/myproj | ||
7616 | M 07/25 15:18 +0000 jrandom 1.14 README.txt myproj == ~/src/myproj | ||
7617 | M 07/25 15:18 +0000 jrandom 1.15 hello.c myproj == ~/src/myproj | ||
7618 | U 07/25 15:23 +0000 jrandom 1.1 goodbye.c myproj == ~/src/myproj | ||
7619 | U 07/25 15:23 +0000 jrandom 1.16 hello.c myproj == ~/src/myproj | ||
7620 | U 07/25 15:26 +0000 jrandom 1.1 goodbye.c myproj == ~/src/myproj | ||
7621 | G 07/25 15:26 +0000 jrandom 1.17 hello.c myproj == ~/src/myproj | ||
7622 | M 07/25 15:27 +0000 jrandom 1.18 hello.c myproj == ~/src/myproj | ||
7623 | C 07/25 15:30 +0000 jrandom 1.19 hello.c myproj == ~/src/myproj | ||
7624 | M 07/25 15:31 +0000 jrandom 1.20 hello.c myproj == ~/src/myproj | ||
7625 | M 07/25 16:29 +0000 jrandom 1.3 whatever.c myproj/a-subdir == ~/src/myproj | ||
7626 | paste$ | ||
7627 | </pre> | ||
7628 | |||
7629 | <p>There, isn't that clear? | ||
7630 | |||
7631 | <p>Before we examine the output, notice that the invocation included two | ||
7632 | options: -e and -a. When you run history, you almost always want to | ||
7633 | pass options telling it what data to report and how to report it. In | ||
7634 | this respect, it differs from most other CVS commands, which usually do | ||
7635 | something useful when invoked without any options. In this example, the | ||
7636 | two flags meant "everything" (show every kind of event that happened) | ||
7637 | and "all" (for all users), respectively. | ||
7638 | |||
7639 | <p>Another way that history differs from other commands is that, although | ||
7640 | it is usually invoked from within a working copy, it does not restrict | ||
7641 | its output to that working copy's project. Instead, it shows all | ||
7642 | history events from all projects in the repository - the working copy | ||
7643 | merely serves to tell CVS from which repository to retrieve the history | ||
7644 | data. (In the preceding example, the only history data in that | ||
7645 | repository is for the <code>myproj</code> project, so that's all we see.) | ||
7646 | |||
7647 | <p>The general format of the output is: | ||
7648 | |||
7649 | <pre>CODE DATE USER [REVISION] [FILE] PATH_IN_REPOSITORY ACTUAL_WORKING_COPY_NAME | ||
7650 | </pre> | ||
7651 | |||
7652 | <p>The code letters refer to various CVS operations, as shown in Table 6.1. | ||
7653 | |||
7654 | <p>For operations (such as checkout) that are about the project as a whole | ||
7655 | rather than about individual files, the revision and file are omitted, | ||
7656 | and the repository path is placed between the equal signs. | ||
7657 | |||
7658 | <p>Although the output of the history command was designed to be compact, | ||
7659 | parseable input for other programs, CVS still gives you a lot of control | ||
7660 | over its scope and content. The options shown in Table 6.2 control what | ||
7661 | types of events get reported. | ||
7662 | |||
7663 | <pre>Table 6.1 The meaning of the code letters. | ||
7664 | |||
7665 | Letter Meaning | ||
7666 | ====== ========================================================= | ||
7667 | O Checkout | ||
7668 | T Tag | ||
7669 | F Release | ||
7670 | W Update (no user file, remove from entries file) | ||
7671 | U Update (file overwrote unmodified user file) | ||
7672 | G Update (file was merged successfully into modified user file) | ||
7673 | C Update (file was merged, but conflicts w/ modified user file) | ||
7674 | M Commit (from modified file) | ||
7675 | A Commit (an added file) | ||
7676 | R Commit (the removal of a file) | ||
7677 | E Export | ||
7678 | </pre> | ||
7679 | |||
7680 | <pre>Table 6.2 Options to filter by event type. | ||
7681 | |||
7682 | Option Meaning | ||
7683 | ========== ========================================================= | ||
7684 | -m MODULEShow historical events affecting MODULE. | ||
7685 | -c Show commit events. | ||
7686 | -o Show checkout events. | ||
7687 | -T Show tag events. | ||
7688 | -x CODE(S)Show all events of type CODE (one or more of OTFWUGCMARE). | ||
7689 | -e Show all types of events, period. Once you have | ||
7690 | selected what type of events you want reported, you can | ||
7691 | filter further with the options shown in Table 6.3. | ||
7692 | </pre> | ||
7693 | |||
7694 | <pre>Table 6.3 Options to filter by user. | ||
7695 | |||
7696 | Option Meaning | ||
7697 | ========== ========================================================= | ||
7698 | -a Show actions taken by all users | ||
7699 | -w Show only actions taken from within this working copy | ||
7700 | -l Show only the last time this user took the action | ||
7701 | -u USER Show records for USER | ||
7702 | </pre> | ||
7703 | |||
7704 | <p><hr> | ||
7705 | Node:<a name="Annotations_--_A_Detailed_View_Of_Project_Activity">Annotations -- A Detailed View Of Project Activity</a>, | ||
7706 | Next:<a rel=next href="#Annotations_And_Branches">Annotations And Branches</a>, | ||
7707 | Previous:<a rel=previous href="#History_--_A_Summary_Of_Repository_Activity">History -- A Summary Of Repository Activity</a>, | ||
7708 | Up:<a rel=up href="#Advanced_CVS">Advanced CVS</a> | ||
7709 | <br> | ||
7710 | |||
7711 | <h2>Annotations - A Detailed View Of Project Activity</h2> | ||
7712 | |||
7713 | <h2>The annotate Command</h2> | ||
7714 | |||
7715 | <p>If the history command gives an overview of project activity, the | ||
7716 | <dfn>annotate</dfn> command is a way of attaching a zoom lens to the view. | ||
7717 | With <code>annotate</code>, you can see who was the last person to touch each | ||
7718 | line of a file, and at what revision they touched it: | ||
7719 | |||
7720 | <pre>floss$ cvs annotate | ||
7721 | Annotations for README.txt | ||
7722 | *************** | ||
7723 | 1.14 (jrandom 25-Jul-99): blah | ||
7724 | 1.13 (jrandom 25-Jul-99): test 3 for history | ||
7725 | 1.12 (qsmith 19-Jul-99): test 2 | ||
7726 | 1.11 (qsmith 19-Jul-99): test | ||
7727 | 1.10 (jrandom 12-Jul-99): blah | ||
7728 | 1.1 (jrandom 20-Jun-99): Just a test project. | ||
7729 | 1.4 (jrandom 21-Jun-99): yeah. | ||
7730 | 1.5 (jrandom 21-Jun-99): nope. | ||
7731 | Annotations for hello.c | ||
7732 | *************** | ||
7733 | 1.1 (jrandom 20-Jun-99): #include <stdio.h> | ||
7734 | 1.1 (jrandom 20-Jun-99): | ||
7735 | 1.1 (jrandom 20-Jun-99): void | ||
7736 | 1.1 (jrandom 20-Jun-99): main () | ||
7737 | 1.1 (jrandom 20-Jun-99): { | ||
7738 | 1.15 (jrandom 25-Jul-99): /* another test for history */ | ||
7739 | 1.13 (qsmith 19-Jul-99): /* random change number two */ | ||
7740 | 1.10 (jrandom 12-Jul-99): /* test */ | ||
7741 | 1.21 (jrandom 25-Jul-99): printf ("Hellooo, world!\n"); | ||
7742 | 1.3 (jrandom 21-Jun-99): printf ("hmmm\n"); | ||
7743 | 1.4 (jrandom 21-Jun-99): printf ("double hmmm\n"); | ||
7744 | 1.11 (qsmith 18-Jul-99): /* added this comment */ | ||
7745 | 1.16 (qsmith 25-Jul-99): /* will merge these changes */ | ||
7746 | 1.18 (jrandom 25-Jul-99): /* will merge these changes too */ | ||
7747 | 1.2 (jrandom 21-Jun-99): printf ("Goodbye, world!\n"); | ||
7748 | 1.1 (jrandom 20-Jun-99): } | ||
7749 | Annotations for a-subdir/whatever.c | ||
7750 | *************** | ||
7751 | 1.3 (jrandom 25-Jul-99): /* A completely non-empty C file. */ | ||
7752 | Annotations for a-subdir/subsubdir/fish.c | ||
7753 | *************** | ||
7754 | 1.2 (jrandom 25-Jul-99): /* An almost completely empty C file. */ | ||
7755 | Annotations for b-subdir/random.c | ||
7756 | *************** | ||
7757 | 1.1 (jrandom 20-Jun-99): /* A completely empty C file. */ | ||
7758 | floss$ | ||
7759 | </pre> | ||
7760 | |||
7761 | <p>The output of annotate is pretty intuitive. On the left are the | ||
7762 | revision number, developer, and date on which the line in question was | ||
7763 | added or last modified. On the right is the line itself, as of the | ||
7764 | current revision. Because every line is annotated, you can actually see | ||
7765 | the entire contents of the file, pushed over to the right by the | ||
7766 | annotation information. | ||
7767 | |||
7768 | <p>If you specify a revision number or tag, the annotations are given as of | ||
7769 | that revision, meaning that it shows the most recent modification to | ||
7770 | each line at or before that revision. This is probably the most common | ||
7771 | way to use annotations - examining a particular revision of a single | ||
7772 | file to determine which developers were active in which parts of the | ||
7773 | file. | ||
7774 | |||
7775 | <p>For example, in the output of the previous example, you can see that the | ||
7776 | most recent revision of hello.c is 1.21, in which jrandom did something | ||
7777 | to the line: | ||
7778 | |||
7779 | <pre>printf ("Hellooo, world!\n"); | ||
7780 | </pre> | ||
7781 | |||
7782 | <p>One way to find out what she did is to diff that revision against the | ||
7783 | previous one: | ||
7784 | |||
7785 | <pre>floss$ cvs diff -r 1.20 -r 1.21 hello.c | ||
7786 | Index: hello.c | ||
7787 | =================================================================== | ||
7788 | RCS file: /usr/local/newrepos/myproj/hello.c,v | ||
7789 | retrieving revision 1.20 | ||
7790 | retrieving revision 1.21 | ||
7791 | diff -r1.20 -r1.21 | ||
7792 | 9c9 | ||
7793 | < printf ("Hello, world!\n"); | ||
7794 | -- | ||
7795 | > printf ("Hellooo, world!\n"); | ||
7796 | floss$ | ||
7797 | </pre> | ||
7798 | |||
7799 | <p>Another way to find out, while still retaining a file-wide view of | ||
7800 | everyone's activity, is to compare the current annotations with the | ||
7801 | annotations from a previous revision: | ||
7802 | |||
7803 | <pre>floss$ cvs annotate -r 1.20 hello.c | ||
7804 | Annotations for hello.c | ||
7805 | *************** | ||
7806 | 1.1 (jrandom 20-Jun-99): #include <stdio.h> | ||
7807 | 1.1 (jrandom 20-Jun-99): | ||
7808 | 1.1 (jrandom 20-Jun-99): void | ||
7809 | 1.1 (jrandom 20-Jun-99): main () | ||
7810 | 1.1 (jrandom 20-Jun-99): { | ||
7811 | 1.15 (jrandom 25-Jul-99): /* another test for history */ | ||
7812 | 1.13 (qsmith 19-Jul-99): /* random change number two */ | ||
7813 | 1.10 (jrandom 12-Jul-99): /* test */ | ||
7814 | 1.1 (jrandom 20-Jun-99): printf ("Hello, world!\n"); | ||
7815 | 1.3 (jrandom 21-Jun-99): printf ("hmmm\n"); | ||
7816 | 1.4 (jrandom 21-Jun-99): printf ("double hmmm\n"); | ||
7817 | 1.11 (qsmith 18-Jul-99): /* added this comment */ | ||
7818 | 1.16 (qsmith 25-Jul-99): /* will merge these changes */ | ||
7819 | 1.18 (jrandom 25-Jul-99): /* will merge these changes too */ | ||
7820 | 1.2 (jrandom 21-Jun-99): printf ("Goodbye, world!\n"); | ||
7821 | 1.1 (jrandom 20-Jun-99): } | ||
7822 | floss$ | ||
7823 | </pre> | ||
7824 | |||
7825 | <p>Although the diff reveals the textual facts of the change more | ||
7826 | concisely, the annotation may be preferable because it places them in | ||
7827 | their historical context by showing how long the previous incarnation of | ||
7828 | the line had been present (in this case, all the way since revision | ||
7829 | 1.1). That knowledge can help you decide whether to look at the logs to | ||
7830 | find out the motivation for the change: | ||
7831 | |||
7832 | <pre>floss$ cvs log -r 1.21 hello.c | ||
7833 | RCS file: /usr/local/newrepos/myproj/hello.c,v | ||
7834 | Working file: hello.c | ||
7835 | head: 1.21 | ||
7836 | branch: | ||
7837 | locks: strict | ||
7838 | access list: | ||
7839 | symbolic names: | ||
7840 | random-tag: 1.20 | ||
7841 | start: 1.1.1.1 | ||
7842 | jrandom: 1.1.1 | ||
7843 | keyword substitution: kv | ||
7844 | total revisions: 22; selected revisions: 1 | ||
7845 | description: | ||
7846 | ---------------------------- | ||
7847 | revision 1.21 | ||
7848 | date: 1999/07/25 20:17:42; author: jrandom; state: Exp; lines: +1 -1 | ||
7849 | say hello with renewed enthusiasm | ||
7850 | ============================================================================ | ||
7851 | floss$ | ||
7852 | </pre> | ||
7853 | |||
7854 | <p>In addition to -r, you can also filter annotations using the -D DATE | ||
7855 | option: | ||
7856 | |||
7857 | <pre>floss$ cvs annotate -D "5 weeks ago" hello.c | ||
7858 | Annotations for hello.c | ||
7859 | *************** | ||
7860 | 1.1 (jrandom 20-Jun-99): #include <stdio.h> | ||
7861 | 1.1 (jrandom 20-Jun-99): | ||
7862 | 1.1 (jrandom 20-Jun-99): void | ||
7863 | 1.1 (jrandom 20-Jun-99): main () | ||
7864 | 1.1 (jrandom 20-Jun-99): { | ||
7865 | 1.1 (jrandom 20-Jun-99): printf ("Hello, world!\n"); | ||
7866 | 1.1 (jrandom 20-Jun-99): } | ||
7867 | floss$ cvs annotate -D "3 weeks ago" hello.c | ||
7868 | Annotations for hello.c | ||
7869 | *************** | ||
7870 | 1.1 (jrandom 20-Jun-99): #include <stdio.h> | ||
7871 | 1.1 (jrandom 20-Jun-99): | ||
7872 | 1.1 (jrandom 20-Jun-99): void | ||
7873 | 1.1 (jrandom 20-Jun-99): main () | ||
7874 | 1.1 (jrandom 20-Jun-99): { | ||
7875 | 1.1 (jrandom 20-Jun-99): printf ("Hello, world!\n"); | ||
7876 | 1.3 (jrandom 21-Jun-99): printf ("hmmm\n"); | ||
7877 | 1.4 (jrandom 21-Jun-99): printf ("double hmmm\n"); | ||
7878 | 1.2 (jrandom 21-Jun-99): printf ("Goodbye, world!\n"); | ||
7879 | 1.1 (jrandom 20-Jun-99): } | ||
7880 | floss$ | ||
7881 | </pre> | ||
7882 | |||
7883 | <p><hr> | ||
7884 | Node:<a name="Annotations_And_Branches">Annotations And Branches</a>, | ||
7885 | Next:<a rel=next href="#Using_Keyword_Expansion">Using Keyword Expansion</a>, | ||
7886 | Previous:<a rel=previous href="#Annotations_--_A_Detailed_View_Of_Project_Activity">Annotations -- A Detailed View Of Project Activity</a>, | ||
7887 | Up:<a rel=up href="#Advanced_CVS">Advanced CVS</a> | ||
7888 | <br> | ||
7889 | |||
7890 | <h2>Annotations And Branches</h2> | ||
7891 | |||
7892 | <p>By default, annotation always shows activity on the main trunk of | ||
7893 | development. Even when invoked from a branch working copy, it shows | ||
7894 | annotations for the trunk unless you specify otherwise. (This tendency | ||
7895 | to favor the trunk is either a bug or a feature, depending on your point | ||
7896 | of view.) You can force CVS to annotate a branch by passing the branch | ||
7897 | tag as an argument to -r. Here is an example from a working copy in | ||
7898 | which hello.c is on a branch named <code>Brancho_Gratuito</code>, with at | ||
7899 | least one change committed on that branch: | ||
7900 | |||
7901 | <pre>floss$ cvs status hello.c | ||
7902 | =================================================================== | ||
7903 | File: hello.c Status: Up-to-date | ||
7904 | |||
7905 | Working revision: 1.10.2.2 Sun Jul 25 21:29:05 1999 | ||
7906 | Repository revision: 1.10.2.2 /usr/local/newrepos/myproj/hello.c,v | ||
7907 | Sticky Tag: Brancho_Gratuito (branch: 1.10.2) | ||
7908 | Sticky Date: (none) | ||
7909 | Sticky Options: (none) | ||
7910 | |||
7911 | floss$ cvs annotate hello.c | ||
7912 | Annotations for hello.c | ||
7913 | *************** | ||
7914 | 1.1 (jrandom 20-Jun-99): #include <stdio.h> | ||
7915 | 1.1 (jrandom 20-Jun-99): | ||
7916 | 1.1 (jrandom 20-Jun-99): void | ||
7917 | 1.1 (jrandom 20-Jun-99): main () | ||
7918 | 1.1 (jrandom 20-Jun-99): { | ||
7919 | 1.10 (jrandom 12-Jul-99): /* test */ | ||
7920 | 1.1 (jrandom 20-Jun-99): printf ("Hello, world!\n"); | ||
7921 | 1.3 (jrandom 21-Jun-99): printf ("hmmm\n"); | ||
7922 | 1.4 (jrandom 21-Jun-99): printf ("double hmmm\n"); | ||
7923 | 1.2 (jrandom 21-Jun-99): printf ("Goodbye, world!\n"); | ||
7924 | 1.1 (jrandom 20-Jun-99): } | ||
7925 | floss$ cvs annotate -r Brancho_Gratuito hello.c | ||
7926 | Annotations for hello.c | ||
7927 | *************** | ||
7928 | 1.1 (jrandom 20-Jun-99): #include <stdio.h> | ||
7929 | 1.1 (jrandom 20-Jun-99): | ||
7930 | 1.1 (jrandom 20-Jun-99): void | ||
7931 | 1.1 (jrandom 20-Jun-99): main () | ||
7932 | 1.1 (jrandom 20-Jun-99): { | ||
7933 | 1.10 (jrandom 12-Jul-99): /* test */ | ||
7934 | 1.1 (jrandom 20-Jun-99): printf ("Hello, world!\n"); | ||
7935 | 1.10.2.2 (jrandom 25-Jul-99): printf ("hmmmmm\n"); | ||
7936 | 1.4 (jrandom 21-Jun-99): printf ("double hmmm\n"); | ||
7937 | 1.10.2.1 (jrandom 25-Jul-99): printf ("added this line"); | ||
7938 | 1.2 (jrandom 21-Jun-99): printf ("Goodbye, world!\n"); | ||
7939 | 1.1 (jrandom 20-Jun-99): } | ||
7940 | floss$ | ||
7941 | </pre> | ||
7942 | |||
7943 | <p>You can also pass the branch number itself: | ||
7944 | |||
7945 | <pre>floss$ cvs annotate -r 1.10.2 hello.c | ||
7946 | Annotations for hello.c | ||
7947 | *************** | ||
7948 | 1.1 (jrandom 20-Jun-99): #include <stdio.h> | ||
7949 | 1.1 (jrandom 20-Jun-99): | ||
7950 | 1.1 (jrandom 20-Jun-99): void | ||
7951 | 1.1 (jrandom 20-Jun-99): main () | ||
7952 | 1.1 (jrandom 20-Jun-99): { | ||
7953 | 1.10 (jrandom 12-Jul-99): /* test */ | ||
7954 | 1.1 (jrandom 20-Jun-99): printf ("Hello, world!\n"); | ||
7955 | 1.10.2.2 (jrandom 25-Jul-99): printf ("hmmmmm\n"); | ||
7956 | 1.4 (jrandom 21-Jun-99): printf ("double hmmm\n"); | ||
7957 | 1.10.2.1 (jrandom 25-Jul-99): printf ("added this line"); | ||
7958 | 1.2 (jrandom 21-Jun-99): printf ("Goodbye, world!\n"); | ||
7959 | 1.1 (jrandom 20-Jun-99): } | ||
7960 | floss$ | ||
7961 | </pre> | ||
7962 | |||
7963 | <p>or a full revision number from the branch: | ||
7964 | |||
7965 | <pre>floss$ cvs annotate -r 1.10.2.1 hello.c | ||
7966 | Annotations for hello.c | ||
7967 | *************** | ||
7968 | 1.1 (jrandom 20-Jun-99): #include <stdio.h> | ||
7969 | 1.1 (jrandom 20-Jun-99): | ||
7970 | 1.1 (jrandom 20-Jun-99): void | ||
7971 | 1.1 (jrandom 20-Jun-99): main () | ||
7972 | 1.1 (jrandom 20-Jun-99): { | ||
7973 | 1.10 (jrandom 12-Jul-99): /* test */ | ||
7974 | 1.1 (jrandom 20-Jun-99): printf ("Hello, world!\n"); | ||
7975 | 1.3 (jrandom 21-Jun-99): printf ("hmmm\n"); | ||
7976 | 1.4 (jrandom 21-Jun-99): printf ("double hmmm\n"); | ||
7977 | 1.10.2.1 (jrandom 25-Jul-99): printf ("added this line"); | ||
7978 | 1.2 (jrandom 21-Jun-99): printf ("Goodbye, world!\n"); | ||
7979 | 1.1 (jrandom 20-Jun-99): } | ||
7980 | floss$ | ||
7981 | </pre> | ||
7982 | |||
7983 | <p>If you do this, remember that the numbers are only valid for that | ||
7984 | particular file. In general, it's probably better to use the branch | ||
7985 | name wherever possible. | ||
7986 | |||
7987 | <p><hr> | ||
7988 | Node:<a name="Using_Keyword_Expansion">Using Keyword Expansion</a>, | ||
7989 | Next:<a rel=next href="#Going_Out_On_A_Limb__How_To_Work_With_Branches_And_Survive_">Going Out On A Limb (How To Work With Branches And Survive)</a>, | ||
7990 | Previous:<a rel=previous href="#Annotations_And_Branches">Annotations And Branches</a>, | ||
7991 | Up:<a rel=up href="#Advanced_CVS">Advanced CVS</a> | ||
7992 | <br> | ||
7993 | |||
7994 | <h2>Using Keyword Expansion</h2> | ||
7995 | |||
7996 | <p>You may recall a brief mention of <code>keyword expansion</code> in <a href="#An_Overview_of_CVS">An Overview of CVS</a>. RCS keywords are special words, surrounded by dollar | ||
7997 | signs, that CVS looks for in text files and expands into | ||
7998 | revision-control information. For example, if a file contains | ||
7999 | |||
8000 | <pre>$Author$ | ||
8001 | </pre> | ||
8002 | |||
8003 | <p>then when updating the file to a given revision, CVS will expand it to | ||
8004 | the username of the person who committed that revision: | ||
8005 | |||
8006 | <pre>$Author$ | ||
8007 | </pre> | ||
8008 | |||
8009 | <p>CVS is also sensitive to keywords in their expanded form, so that once | ||
8010 | expanded, they continue to be updated as appropriate. | ||
8011 | |||
8012 | <p>Although keywords don't actually offer any information that's not | ||
8013 | available by other means, they give people a convenient way to see | ||
8014 | revision control facts embedded in the text of the file itself, rather | ||
8015 | than by invoking some arcane CVS operation. | ||
8016 | |||
8017 | <p>Here are a few other commonly used keywords: | ||
8018 | |||
8019 | <pre>$Date$ ==> date of last commit, expands to ==> | ||
8020 | $Date$ | ||
8021 | |||
8022 | $Id$ ==> filename, revision, date, and author; expands to ==> | ||
8023 | $Id$ | ||
8024 | |||
8025 | $Revision$ ==> exactly what you think it is, expands to ==> | ||
8026 | $Revision$ | ||
8027 | |||
8028 | $Source$ ==> path to corresponding repository file, expands to ==> | ||
8029 | $Source$ | ||
8030 | |||
8031 | $Log$ | ||
8032 | Revision 1.1 2002/06/23 14:32:50 llornkcor | ||
8033 | some dev docs | ||
8034 | ==> accumulating log messages for the file, expands to ==> | ||
8035 | $Log$ | ||
8036 | Revision 1.1 2002/06/23 14:32:50 llornkcor | ||
8037 | some dev docs | ||
8038 | |||
8039 | Revision 1.2 1999/07/26 06:47:52 jrandom | ||
8040 | ...and this is the second log message. | ||
8041 | |||
8042 | Revision 1.1 1999/07/26 06:39:46 jrandom | ||
8043 | This is the first log message... | ||
8044 | </pre> | ||
8045 | |||
8046 | <p>The $Log$ | ||
8047 | <p>The Revision 1.1 2002/06/23 14:32:50 llornkcor | ||
8048 | <p>The some dev docs | ||
8049 | <p>The keyword is the only one of these that expands to cover | ||
8050 | multiple lines, so its behavior is unique. Unlike the others, it does | ||
8051 | not replace the old expansion with the new one, but instead inserts the | ||
8052 | latest expansion, plus an additional blank line, right after the keyword | ||
8053 | (thereby pushing any previous expansions downward). Furthermore, any | ||
8054 | text between the beginning of the line and $Log is used as a prefix for | ||
8055 | the expansions (this is done to ensure that the log messages stay | ||
8056 | commented in program code). For example, if you put this into the file | ||
8057 | |||
8058 | <pre>// $Log$ | ||
8059 | <pre>// Revision 1.1 2002/06/23 14:32:50 llornkcor | ||
8060 | <pre>// some dev docs | ||
8061 | <pre>// | ||
8062 | </pre> | ||
8063 | |||
8064 | <p>it will expand to something like this on the first commit: | ||
8065 | |||
8066 | <pre>// $Log$ | ||
8067 | <pre>// Revision 1.1 2002/06/23 14:32:50 llornkcor | ||
8068 | <pre>// some dev docs | ||
8069 | <pre>// | ||
8070 | // Revision 1.14 1999/07/26 07:03:20 jrandom | ||
8071 | // this is the first log message... | ||
8072 | // | ||
8073 | </pre> | ||
8074 | |||
8075 | <p>this on the second: | ||
8076 | |||
8077 | <pre>// $Log$ | ||
8078 | <pre>// Revision 1.1 2002/06/23 14:32:50 llornkcor | ||
8079 | <pre>// some dev docs | ||
8080 | <pre>// | ||
8081 | // Revision 1.15 1999/07/26 07:04:40 jrandom | ||
8082 | // ...and this is the second log message... | ||
8083 | // | ||
8084 | // Revision 1.14 1999/07/26 07:03:20 jrandom | ||
8085 | // this is the first log message... | ||
8086 | // | ||
8087 | </pre> | ||
8088 | |||
8089 | <p>and so on: | ||
8090 | |||
8091 | <pre>// $Log$ | ||
8092 | <pre>// Revision 1.1 2002/06/23 14:32:50 llornkcor | ||
8093 | <pre>// some dev docs | ||
8094 | <pre>// | ||
8095 | // Revision 1.16 1999/07/26 07:05:34 jrandom | ||
8096 | // ...and this is the third! | ||
8097 | // | ||
8098 | // Revision 1.15 1999/07/26 07:04:40 jrandom | ||
8099 | // ...and this is the second log message... | ||
8100 | // | ||
8101 | // Revision 1.14 1999/07/26 07:03:20 jrandom | ||
8102 | // this is the first log message... | ||
8103 | // | ||
8104 | </pre> | ||
8105 | |||
8106 | <p>You may not want to keep your entire log history in the file all the | ||
8107 | time; if you do, you can always remove the older sections when it starts | ||
8108 | to get too lengthy. It's certainly more convenient than running cvs | ||
8109 | log, and it may be worthwhile in projects where people must constantly | ||
8110 | read over the logs. | ||
8111 | |||
8112 | <p>A more common technique may be to include $Revision$ in a file and use | ||
8113 | it as the version number for the program. This can work if the project | ||
8114 | consists of essentially one file or undergoes frequent releases and has | ||
8115 | at least one file that is guaranteed to be modified between every | ||
8116 | release. You can even use an RCS keyword as a value in program code: | ||
8117 | |||
8118 | <pre>VERSION = "$Revision$"; | ||
8119 | </pre> | ||
8120 | |||
8121 | <p>CVS expands that keyword just like any other; it has no concept of the | ||
8122 | programming language's semantics and does not assume that the double | ||
8123 | quotes protect the string in any way. | ||
8124 | |||
8125 | <p>A complete list of keywords (there are a few more, rather obscure ones) | ||
8126 | is given in <a href="#CVS_Reference">CVS Reference</a>. | ||
8127 | |||
8128 | <p><hr> | ||
8129 | Node:<a name="Going_Out_On_A_Limb__How_To_Work_With_Branches_And_Survive_">Going Out On A Limb (How To Work With Branches And Survive)</a>, | ||
8130 | Next:<a rel=next href="#Tracking_Third-Party_Sources__Vendor_Branches_">Tracking Third-Party Sources (Vendor Branches)</a>, | ||
8131 | Previous:<a rel=previous href="#Using_Keyword_Expansion">Using Keyword Expansion</a>, | ||
8132 | Up:<a rel=up href="#Advanced_CVS">Advanced CVS</a> | ||
8133 | <br> | ||
8134 | |||
8135 | <h2>Going Out On A Limb (How To Work With Branches And Survive)</h2> | ||
8136 | |||
8137 | <p>Branches are simultaneously one of the most important and most easily | ||
8138 | misused features of CVS. Isolating risky or disruptive changes onto a | ||
8139 | separate line of development until they stabilize can be immensely | ||
8140 | helpful. If not properly managed, however, branches can quickly propel | ||
8141 | a project into confusion and cascading chaos, as people lose track of | ||
8142 | what changes have been merged when. | ||
8143 | |||
8144 | <ul> | ||
8145 | <li><a href="#Some_Principles_For_Working_With_Branches">Some Principles For Working With Branches</a>: | ||
8146 | <li><a href="#Merging_Repeatedly_Into_The_Trunk">Merging Repeatedly Into The Trunk</a>: | ||
8147 | <li><a href="#The_Dovetail_Approach_--_Merging_In_And_Out_Of_The_Trunk">The Dovetail Approach -- Merging In And Out Of The Trunk</a>: | ||
8148 | <li><a href="#The_Flying_Fish_Approach_--_A_Simpler_Way_To_Do_It">The Flying Fish Approach -- A Simpler Way To Do It</a>: | ||
8149 | <li><a href="#Branches_And_Keyword_Expansion_--_Natural_Enemies">Branches And Keyword Expansion -- Natural Enemies</a>: | ||
8150 | </ul> | ||
8151 | |||
8152 | <p><hr> | ||
8153 | Node:<a name="Some_Principles_For_Working_With_Branches">Some Principles For Working With Branches</a>, | ||
8154 | Next:<a rel=next href="#Merging_Repeatedly_Into_The_Trunk">Merging Repeatedly Into The Trunk</a>, | ||
8155 | Up:<a rel=up href="#Going_Out_On_A_Limb__How_To_Work_With_Branches_And_Survive_">Going Out On A Limb (How To Work With Branches And Survive)</a> | ||
8156 | <br> | ||
8157 | |||
8158 | <h3>Some Principles For Working With Branches</h3> | ||
8159 | |||
8160 | <p>To work successfully with branches, your development group should adhere | ||
8161 | to these principles: | ||
8162 | |||
8163 | <ul> | ||
8164 | |||
8165 | <li>Minimize the number of branches active at any one time. The more | ||
8166 | branches under development at the same time, the more likely they are to | ||
8167 | conflict when merged into the trunk. In practical terms, the way to | ||
8168 | accomplish this is to merge as frequently as you can (whenever a branch | ||
8169 | is at a stable point) and to move development back onto the trunk as | ||
8170 | soon as feasible. By minimizing the amount of parallel development | ||
8171 | going on, everyone is better able to keep track of what's going on on | ||
8172 | each branch, and the possibility of conflicts on merge is reduced. | ||
8173 | |||
8174 | <p>This does not mean minimizing the absolute number of branches in the | ||
8175 | project, just the number being worked on at any given time. | ||
8176 | |||
8177 | </p><li>Minimize the complexity - that is, the depth - of your branching | ||
8178 | scheme. There are circumstances in which it's appropriate to have | ||
8179 | branches from branches, but they are very rare (you may get through your | ||
8180 | entire programming life without ever encountering one). Just because | ||
8181 | CVS makes it technically possible to have arbitrary levels of nested | ||
8182 | branching, and to merge from any branch to any other branch, doesn't | ||
8183 | mean you actually want to do these things. In most situations, it's | ||
8184 | best to have all your branches rooted at the trunk and to merge from | ||
8185 | branch to trunk and back out again. | ||
8186 | |||
8187 | <li>Use consistently named tags to mark all branch and merge events. | ||
8188 | Ideally, the meaning of each tag and its relationship to other branches | ||
8189 | and tags should be apparent from the tag name. (The point of this will | ||
8190 | become clearer as we go through the examples.) | ||
8191 | |||
8192 | </ul> | ||
8193 | |||
8194 | <p>With those principles in mind, let's take a look at a typical branch | ||
8195 | development scenario. We'll have jrandom on the trunk and qsmith on the | ||
8196 | branch, but note that there could just as well be multiple developers on | ||
8197 | the trunk and/or on the branch. Regular development along either line | ||
8198 | can involve any number of people; however, the tagging and merging are | ||
8199 | best done by one person on each side, as you'll see. | ||
8200 | |||
8201 | <p><hr> | ||
8202 | Node:<a name="Merging_Repeatedly_Into_The_Trunk">Merging Repeatedly Into The Trunk</a>, | ||
8203 | Next:<a rel=next href="#The_Dovetail_Approach_--_Merging_In_And_Out_Of_The_Trunk">The Dovetail Approach -- Merging In And Out Of The Trunk</a>, | ||
8204 | Previous:<a rel=previous href="#Some_Principles_For_Working_With_Branches">Some Principles For Working With Branches</a>, | ||
8205 | Up:<a rel=up href="#Going_Out_On_A_Limb__How_To_Work_With_Branches_And_Survive_">Going Out On A Limb (How To Work With Branches And Survive)</a> | ||
8206 | <br> | ||
8207 | |||
8208 | <h3>Merging Repeatedly Into The Trunk</h3> | ||
8209 | |||
8210 | <p>Let's assume qsmith needs to do development on a branch for a while, to | ||
8211 | avoid destabilizing the trunk that he shares with jrandom. The first | ||
8212 | step is to create the branch. Notice how qsmith creates a regular | ||
8213 | (non-branch) tag at the branch point first, and then creates the branch: | ||
8214 | |||
8215 | <pre>paste$ pwd | ||
8216 | /home/qsmith/myproj | ||
8217 | paste$ cvs tag Root-of-Exotic_Greetings | ||
8218 | cvs tag: Tagging . | ||
8219 | T README.txt | ||
8220 | T foo.gif | ||
8221 | T hello.c | ||
8222 | cvs tag: Tagging a-subdir | ||
8223 | T a-subdir/whatever.c | ||
8224 | cvs tag: Tagging a-subdir/subsubdir | ||
8225 | T a-subdir/subsubdir/fish.c | ||
8226 | cvs tag: Tagging b-subdir | ||
8227 | T b-subdir/random.c | ||
8228 | paste$ cvs tag -b Exotic_Greetings-branch | ||
8229 | cvs tag: Tagging . | ||
8230 | T README.txt | ||
8231 | T foo.gif | ||
8232 | T hello.c | ||
8233 | cvs tag: Tagging a-subdir | ||
8234 | T a-subdir/whatever.c | ||
8235 | cvs tag: Tagging a-subdir/subsubdir | ||
8236 | T a-subdir/subsubdir/fish.c | ||
8237 | cvs tag: Tagging b-subdir | ||
8238 | T b-subdir/random.c | ||
8239 | paste$ | ||
8240 | </pre> | ||
8241 | |||
8242 | <p>The point of tagging the trunk first is that it may be necessary someday | ||
8243 | to retrieve the trunk as it was the moment the branch was created. If | ||
8244 | you ever need to do that, you'll have to have a way of referring to the | ||
8245 | trunk snapshot without referring to the branch itself. Obviously, you | ||
8246 | can't use the branch tag because that would retrieve the branch, not the | ||
8247 | revisions in the trunk that form the root of the branch. The only way | ||
8248 | to do it is to make a regular tag at the same revisions the branch | ||
8249 | sprouts from. (Some people stick to this rule so faithfully that I | ||
8250 | considered listing it as "Branching Principle Number 4: Always create a | ||
8251 | non-branch tag at the branch point." However, many sites don't do it, | ||
8252 | and they generally seem to do okay, so it's really a matter of taste.) | ||
8253 | From here on, I will refer to this non-branch tag as the <dfn>branch | ||
8254 | point tag</dfn>. | ||
8255 | |||
8256 | <p>Notice also that a naming convention is being adhered to: The branch | ||
8257 | point tag begins with <code>Root-of-</code>, then the actual branch name, | ||
8258 | which uses underscores instead of hyphens to separate words. When the | ||
8259 | actual branch is created, its tag ends with the suffix <code>-branch</code> so | ||
8260 | that you can identify it as a branch tag just by looking at the tag | ||
8261 | name. (The branch point tag <code>Root-of-Exotic_Greetings</code> does not | ||
8262 | include the -branch because it is not a branch tag.) You don't have to | ||
8263 | use this particular naming convention, of course, but you should use | ||
8264 | some convention. | ||
8265 | |||
8266 | <p>Of course, I'm being extra pedantic here. In smallish projects, where | ||
8267 | everyone knows who's doing what and confusion is easy to recover from, | ||
8268 | these conventions don't have to be used. Whether you use a branch point | ||
8269 | tag or have a strict naming convention for your tags depends on the | ||
8270 | complexity of the project and the branching scheme. (Also, don't forget | ||
8271 | that you can always go back later and update old tags to use new | ||
8272 | conventions by retrieving an old tagged version, adding the new tag, and | ||
8273 | then deleting the old tag.) | ||
8274 | |||
8275 | <p>Now, qsmith is ready to start working on the branch: | ||
8276 | |||
8277 | <pre>paste$ cvs update -r Exotic_Greetings-branch | ||
8278 | cvs update: Updating . | ||
8279 | cvs update: Updating a-subdir | ||
8280 | cvs update: Updating a-subdir/subsubdir | ||
8281 | cvs update: Updating b-subdir | ||
8282 | paste$ | ||
8283 | </pre> | ||
8284 | |||
8285 | <p>He makes some changes to a couple of files and commits them on the branch: | ||
8286 | |||
8287 | <pre>paste$ emacs README.txt a-subdir/whatever.c b-subdir/random.c | ||
8288 | ... | ||
8289 | paste$ cvs ci -m "print greeting backwards, etc" | ||
8290 | cvs commit: Examining . | ||
8291 | cvs commit: Examining a-subdir | ||
8292 | cvs commit: Examining a-subdir/subsubdir | ||
8293 | cvs commit: Examining b-subdir | ||
8294 | Checking in README.txt; | ||
8295 | /usr/local/newrepos/myproj/README.txt,v <-- README.txt | ||
8296 | new revision: 1.14.2.1; previous revision: 1.14 | ||
8297 | done | ||
8298 | Checking in a-subdir/whatever.c; | ||
8299 | /usr/local/newrepos/myproj/a-subdir/whatever.c,v <-- whatever.c | ||
8300 | new revision: 1.3.2.1; previous revision: 1.3 | ||
8301 | done | ||
8302 | Checking in b-subdir/random.c; | ||
8303 | /usr/local/newrepos/myproj/b-subdir/random.c,v <-- random.c | ||
8304 | new revision: 1.1.1.1.2.1; previous revision: 1.1.1.1 | ||
8305 | done | ||
8306 | paste$ | ||
8307 | </pre> | ||
8308 | |||
8309 | <p>Meanwhile, jrandom is continuing to work on the trunk. She modifies two | ||
8310 | of the three files that qsmith touched. Just for kicks, we'll have her | ||
8311 | make changes that conflict with qsmith's work: | ||
8312 | |||
8313 | <pre>floss$ emacs README.txt whatever.c | ||
8314 | ... | ||
8315 | floss$ cvs ci -m "some very stable changes indeed" | ||
8316 | cvs commit: Examining . | ||
8317 | cvs commit: Examining a-subdir | ||
8318 | cvs commit: Examining a-subdir/subsubdir | ||
8319 | cvs commit: Examining b-subdir | ||
8320 | Checking in README.txt; | ||
8321 | /usr/local/newrepos/myproj/README.txt,v <-- README.txt | ||
8322 | new revision: 1.15; previous revision: 1.14 | ||
8323 | done | ||
8324 | Checking in a-subdir/whatever.c; | ||
8325 | /usr/local/newrepos/myproj/a-subdir/whatever.c,v <-- whatever.c | ||
8326 | new revision: 1.4; previous revision: 1.3 | ||
8327 | done | ||
8328 | floss$ | ||
8329 | </pre> | ||
8330 | |||
8331 | <p>The conflict is not apparent yet, of course, because neither developer | ||
8332 | has tried to merge branch and trunk. Now, jrandom does the merge: | ||
8333 | |||
8334 | <pre>floss$ cvs update -j Exotic_Greetings-branch | ||
8335 | cvs update: Updating . | ||
8336 | RCS file: /usr/local/newrepos/myproj/README.txt,v | ||
8337 | retrieving revision 1.14 | ||
8338 | retrieving revision 1.14.2.1 | ||
8339 | Merging differences between 1.14 and 1.14.2.1 into README.txt | ||
8340 | rcsmerge: warning: conflicts during merge | ||
8341 | cvs update: Updating a-subdir | ||
8342 | RCS file: /usr/local/newrepos/myproj/a-subdir/whatever.c,v | ||
8343 | retrieving revision 1.3 | ||
8344 | retrieving revision 1.3.2.1 | ||
8345 | Merging differences between 1.3 and 1.3.2.1 into whatever.c | ||
8346 | rcsmerge: warning: conflicts during merge | ||
8347 | cvs update: Updating a-subdir/subsubdir | ||
8348 | cvs update: Updating b-subdir | ||
8349 | RCS file: /usr/local/newrepos/myproj/b-subdir/random.c,v | ||
8350 | retrieving revision 1.1.1.1 | ||
8351 | retrieving revision 1.1.1.1.2.1 | ||
8352 | Merging differences between 1.1.1.1 and 1.1.1.1.2.1 into random.c | ||
8353 | floss$ cvs update | ||
8354 | cvs update: Updating . | ||
8355 | C README.txt | ||
8356 | cvs update: Updating a-subdir | ||
8357 | C a-subdir/whatever.c | ||
8358 | cvs update: Updating a-subdir/subsubdir | ||
8359 | cvs update: Updating b-subdir | ||
8360 | M b-subdir/random.c | ||
8361 | floss$ | ||
8362 | </pre> | ||
8363 | |||
8364 | <p>Two of the files conflict. No big deal; with her usual savoir-faire, | ||
8365 | jrandom resolves the conflicts, commits, and tags the trunk as | ||
8366 | successfully merged: | ||
8367 | |||
8368 | <pre>floss$ emacs README.txt a-subdir/whatever.c | ||
8369 | ... | ||
8370 | floss$ cvs ci -m "merged from Exotic_Greetings-branch (conflicts resolved)" | ||
8371 | cvs commit: Examining . | ||
8372 | cvs commit: Examining a-subdir | ||
8373 | cvs commit: Examining a-subdir/subsubdir | ||
8374 | cvs commit: Examining b-subdir | ||
8375 | Checking in README.txt; | ||
8376 | /usr/local/newrepos/myproj/README.txt,v <-- README.txt | ||
8377 | new revision: 1.16; previous revision: 1.15 | ||
8378 | done | ||
8379 | Checking in a-subdir/whatever.c; | ||
8380 | /usr/local/newrepos/myproj/a-subdir/whatever.c,v <-- whatever.c | ||
8381 | new revision: 1.5; previous revision: 1.4 | ||
8382 | done | ||
8383 | Checking in b-subdir/random.c; | ||
8384 | /usr/local/newrepos/myproj/b-subdir/random.c,v <-- random.c | ||
8385 | new revision: 1.2; previous revision: 1.1 | ||
8386 | done | ||
8387 | floss$ cvs tag merged-Exotic_Greetings | ||
8388 | cvs tag: Tagging . | ||
8389 | T README.txt | ||
8390 | T foo.gif | ||
8391 | T hello.c | ||
8392 | cvs tag: Tagging a-subdir | ||
8393 | T a-subdir/whatever.c | ||
8394 | cvs tag: Tagging a-subdir/subsubdir | ||
8395 | T a-subdir/subsubdir/fish.c | ||
8396 | cvs tag: Tagging b-subdir | ||
8397 | T b-subdir/random.c | ||
8398 | floss$ | ||
8399 | </pre> | ||
8400 | |||
8401 | <p>Meanwhile, qsmith needn't wait for the merge to finish before continuing | ||
8402 | development, as long as he makes a tag for the batch of changes from | ||
8403 | which jrandom merged (later, jrandom will need to know this tag name; in | ||
8404 | general, branches depend on frequent and thorough developer | ||
8405 | communications): | ||
8406 | |||
8407 | <pre>paste$ cvs tag Exotic_Greetings-1 | ||
8408 | cvs tag: Tagging . | ||
8409 | T README.txt | ||
8410 | T foo.gif | ||
8411 | T hello.c | ||
8412 | cvs tag: Tagging a-subdir | ||
8413 | T a-subdir/whatever.c | ||
8414 | cvs tag: Tagging a-subdir/subsubdir | ||
8415 | T a-subdir/subsubdir/fish.c | ||
8416 | cvs tag: Tagging b-subdir | ||
8417 | T b-subdir/random.c | ||
8418 | paste$ emacs a-subdir/whatever.c | ||
8419 | ... | ||
8420 | paste$ cvs ci -m "print a randomly capitalized greeting" | ||
8421 | cvs commit: Examining . | ||
8422 | cvs commit: Examining a-subdir | ||
8423 | cvs commit: Examining a-subdir/subsubdir | ||
8424 | cvs commit: Examining b-subdir | ||
8425 | Checking in a-subdir/whatever.c; | ||
8426 | /usr/local/newrepos/myproj/a-subdir/whatever.c,v <-- whatever.c | ||
8427 | new revision: 1.3.2.2; previous revision: 1.3.2.1 | ||
8428 | done | ||
8429 | paste$ | ||
8430 | </pre> | ||
8431 | |||
8432 | <p>And of course, qsmith should tag those changes once he's done: | ||
8433 | |||
8434 | <pre>paste$ cvs -q tag Exotic_Greetings-2 | ||
8435 | T README.txt | ||
8436 | T foo.gif | ||
8437 | T hello.c | ||
8438 | T a-subdir/whatever.c | ||
8439 | T a-subdir/subsubdir/fish.c | ||
8440 | T b-subdir/random.c | ||
8441 | paste$ | ||
8442 | </pre> | ||
8443 | |||
8444 | <p>While all this is going on, jrandom makes a change in a different file, | ||
8445 | one that qsmith hasn't touched in his new batch of edits: | ||
8446 | |||
8447 | <pre>floss$ emacs README.txt | ||
8448 | ... | ||
8449 | floss$ cvs ci -m "Mention new Exotic Greeting features" README.txt | ||
8450 | Checking in README.txt; | ||
8451 | /usr/local/newrepos/myproj/README.txt,v <-- README.txt | ||
8452 | new revision: 1.17; previous revision: 1.16 | ||
8453 | done | ||
8454 | floss$ | ||
8455 | </pre> | ||
8456 | |||
8457 | <p>At this point, qsmith has committed a new change on the branch, and | ||
8458 | jrandom has committed a nonconflicting change in a different file on the | ||
8459 | trunk. Watch what happens when jrandom tries to merge from the branch | ||
8460 | again: | ||
8461 | |||
8462 | <pre>floss$ cvs -q update -j Exotic_Greetings-branch | ||
8463 | RCS file: /usr/local/newrepos/myproj/README.txt,v | ||
8464 | retrieving revision 1.14 | ||
8465 | retrieving revision 1.14.2.1 | ||
8466 | Merging differences between 1.14 and 1.14.2.1 into README.txt | ||
8467 | rcsmerge: warning: conflicts during merge | ||
8468 | RCS file: /usr/local/newrepos/myproj/a-subdir/whatever.c,v | ||
8469 | retrieving revision 1.3 | ||
8470 | retrieving revision 1.3.2.2 | ||
8471 | Merging differences between 1.3 and 1.3.2.2 into whatever.c | ||
8472 | rcsmerge: warning: conflicts during merge | ||
8473 | RCS file: /usr/local/newrepos/myproj/b-subdir/random.c,v | ||
8474 | retrieving revision 1.1 | ||
8475 | retrieving revision 1.1.1.1.2.1 | ||
8476 | Merging differences between 1.1 and 1.1.1.1.2.1 into random.c | ||
8477 | floss$ cvs -q update | ||
8478 | C README.txt | ||
8479 | C a-subdir/whatever.c | ||
8480 | floss$ | ||
8481 | </pre> | ||
8482 | |||
8483 | <p>There are conflicts! Is that what you expected? | ||
8484 | |||
8485 | <p>The problem lies in the semantics of merging. Back in <a href="#An_Overview_of_CVS">An Overview of CVS</a>, I explained that when you run | ||
8486 | |||
8487 | <pre>floss$ cvs update -j BRANCH | ||
8488 | </pre> | ||
8489 | |||
8490 | <p>in a working copy, CVS merges into the working copy the differences | ||
8491 | between BRANCH's root and its tip. The trouble with that behavior, in | ||
8492 | this situation, is that most of those changes had already been | ||
8493 | incorporated into the trunk the first time that jrandom did a merge. | ||
8494 | When CVS tried to merge them in again (over themselves, as it were), it | ||
8495 | naturally registered a conflict. | ||
8496 | |||
8497 | <p>What jrandom really wanted to do was merge into her working copy the | ||
8498 | changes between the branch's most recent merge and its current tip. You | ||
8499 | can do this by using two -j flags to update, as you may recall from | ||
8500 | <a href="#An_Overview_of_CVS">An Overview of CVS</a>, as long as you know what revision to specify | ||
8501 | with each flag. Fortunately, qsmith made a tag at exactly the last | ||
8502 | merge point (hurrah for planning ahead!), so this will be no problem. | ||
8503 | First, let's have jrandom restore her working copy to a clean state, | ||
8504 | from which she can redo the merge: | ||
8505 | |||
8506 | <pre>floss$ rm README.txt a-subdir/whatever.c | ||
8507 | floss$ cvs -q update | ||
8508 | cvs update: warning: README.txt was lost | ||
8509 | U README.txt | ||
8510 | cvs update: warning: a-subdir/whatever.c was lost | ||
8511 | U a-subdir/whatever.c | ||
8512 | floss$ | ||
8513 | </pre> | ||
8514 | |||
8515 | <p>Now she's ready to do the merge, this time using qsmith's conveniently | ||
8516 | placed tag: | ||
8517 | |||
8518 | <pre>floss$ cvs -q update -j Exotic_Greetings-1 -j Exotic_Greetings-branch | ||
8519 | RCS file: /usr/local/newrepos/myproj/a-subdir/whatever.c,v | ||
8520 | retrieving revision 1.3.2.1 | ||
8521 | retrieving revision 1.3.2.2 | ||
8522 | Merging differences between 1.3.2.1 and 1.3.2.2 into whatever.c | ||
8523 | floss$ cvs -q update | ||
8524 | M a-subdir/whatever.c | ||
8525 | floss$ | ||
8526 | </pre> | ||
8527 | |||
8528 | <p>Much better. The change from qsmith has been incorporated into | ||
8529 | whatever.c; jrandom can now commit and tag: | ||
8530 | |||
8531 | <pre>floss$ cvs -q ci -m "merged again from Exotic_Greetings (1)" | ||
8532 | Checking in a-subdir/whatever.c; | ||
8533 | /usr/local/newrepos/myproj/a-subdir/whatever.c,v <-- whatever.c | ||
8534 | new revision: 1.6; previous revision: 1.5 | ||
8535 | done | ||
8536 | floss$ cvs -q tag merged-Exotic_Greetings-1 | ||
8537 | T README.txt | ||
8538 | T foo.gif | ||
8539 | T hello.c | ||
8540 | T a-subdir/whatever.c | ||
8541 | T a-subdir/subsubdir/fish.c | ||
8542 | T b-subdir/random.c | ||
8543 | floss$ | ||
8544 | </pre> | ||
8545 | |||
8546 | <p>Even if qsmith had forgotten to tag at the merge point, all hope would | ||
8547 | not be lost. If jrandom knew approximately when qsmith's first batch of | ||
8548 | changes had been committed, she could try filtering by date: | ||
8549 | |||
8550 | <pre>floss$ cvs update -j Exotic_Greetings-branch:3pm -j Exotic_Greetings_branch | ||
8551 | </pre> | ||
8552 | |||
8553 | <p>Although useful as a last resort, filtering by date is less than ideal | ||
8554 | because it selects the changes based on people's recollections rather | ||
8555 | than dependable developer designations. If qsmith's first mergeable set | ||
8556 | of changes had happened over several commits instead of in one commit, | ||
8557 | jrandom may mistakenly choose a date or time that would catch some of | ||
8558 | the changes, but not all of them. | ||
8559 | |||
8560 | <p>There's no reason why each taggable point in qsmith's changes needs to | ||
8561 | be sent to the repository in a single commit - it just happens to have | ||
8562 | worked out that way in these examples. In real life, qsmith may make | ||
8563 | several commits between tags. He can work on the branch in isolation, | ||
8564 | as he pleases. The point of the tags is to record successive points on | ||
8565 | the branch where he considers the changes to be mergeable into the | ||
8566 | trunk. As long as jrandom always merges using two -j flags and is | ||
8567 | careful to use qsmith's merge tags in the right order and only once | ||
8568 | each, the trunk should never experience the double-merge problem. | ||
8569 | Conflicts may occur, but they will be the unavoidable kind that requires | ||
8570 | human resolution - situations in which both branch and trunk made | ||
8571 | changes to the same area of code. | ||
8572 | |||
8573 | <p><hr> | ||
8574 | Node:<a name="The_Dovetail_Approach_--_Merging_In_And_Out_Of_The_Trunk">The Dovetail Approach -- Merging In And Out Of The Trunk</a>, | ||
8575 | Next:<a rel=next href="#The_Flying_Fish_Approach_--_A_Simpler_Way_To_Do_It">The Flying Fish Approach -- A Simpler Way To Do It</a>, | ||
8576 | Previous:<a rel=previous href="#Merging_Repeatedly_Into_The_Trunk">Merging Repeatedly Into The Trunk</a>, | ||
8577 | Up:<a rel=up href="#Going_Out_On_A_Limb__How_To_Work_With_Branches_And_Survive_">Going Out On A Limb (How To Work With Branches And Survive)</a> | ||
8578 | <br> | ||
8579 | |||
8580 | <h3>The Dovetail Approach - Merging In And Out Of The Trunk</h3> | ||
8581 | |||
8582 | <p>Merging repeatedly from branch to trunk is good for the people on the | ||
8583 | trunk, because they see all of their own changes and all the changes | ||
8584 | from the branch. However, the developer on the branch never gets to | ||
8585 | incorporate any of the work being done on the trunk. | ||
8586 | |||
8587 | <p>To allow that, the branch developer needs to add an extra step every now | ||
8588 | and then (meaning whenever he feels like merging in recent trunk changes | ||
8589 | and dealing with the inevitable conflicts): | ||
8590 | |||
8591 | <pre>paste$ cvs update -j HEAD | ||
8592 | </pre> | ||
8593 | |||
8594 | <p>The special reserved tag <code>HEAD</code> means the tip of the trunk. The | ||
8595 | preceding command merges in all of the trunk changes between the root of | ||
8596 | the current branch (<code>Exotic_Greetings-branch</code>) and the current | ||
8597 | highest revisions of each file on the trunk. Of course, qsmith should | ||
8598 | tag again after doing this, so that the trunk developers can avoid | ||
8599 | accidentally merging in their own changes when they're trying to get | ||
8600 | qsmith's. | ||
8601 | |||
8602 | <p>The branch developer can likewise use the trunk's merge tags as | ||
8603 | boundaries, allowing the branch to merge exactly those trunk changes | ||
8604 | between the last merge and the trunk's current state (the same way the | ||
8605 | trunk does merges). For example, supposing jrandom had made some | ||
8606 | changes to hello.c after merging from the branch: | ||
8607 | |||
8608 | <pre>floss$ emacs hello.c | ||
8609 | ... | ||
8610 | floss$ cvs ci -m "clarify algorithm" hello.c | ||
8611 | Checking in hello.c; | ||
8612 | /usr/local/newrepos/myproj/hello.c,v <-- hello.c | ||
8613 | new revision: 1.22; previous revision: 1.21 | ||
8614 | done | ||
8615 | floss$ | ||
8616 | </pre> | ||
8617 | |||
8618 | <p>Then, qsmith can merge those changes into his branch, commit, and, of | ||
8619 | course, tag: | ||
8620 | |||
8621 | <pre>paste$ cvs -q update -j merged-Exotic_Greetings-1 -j HEAD | ||
8622 | RCS file: /usr/local/newrepos/myproj/hello.c,v | ||
8623 | retrieving revision 1.21 | ||
8624 | retrieving revision 1.22 | ||
8625 | Merging differences between 1.21 and 1.22 into hello.c | ||
8626 | paste$ cvs -q update | ||
8627 | M hello.c | ||
8628 | paste$ cvs -q ci -m "merged trunk, from merged-Exotic_Greetings-1 to HEAD" | ||
8629 | Checking in hello.c; | ||
8630 | /usr/local/newrepos/myproj/hello.c,v <-- hello.c | ||
8631 | new revision: 1.21.2.1; previous revision: 1.21 | ||
8632 | done | ||
8633 | paste$ cvs -q tag merged-merged-Exotic_Greetings-1 | ||
8634 | T README.txt | ||
8635 | T foo.gif | ||
8636 | T hello.c | ||
8637 | T a-subdir/whatever.c | ||
8638 | T a-subdir/subsubdir/fish.c | ||
8639 | T b-subdir/random.c | ||
8640 | paste$ | ||
8641 | </pre> | ||
8642 | |||
8643 | <p>Notice that jrandom did not bother to tag after committing the changes | ||
8644 | to hello.c, but qsmith did. The principle at work here is that although | ||
8645 | you don't need to tag after every little change, you should always tag | ||
8646 | after a merge or after committing your line of development up to a | ||
8647 | mergeable state. That way, other people - perhaps on other branches - | ||
8648 | have a reference point against which to base their own merges. | ||
8649 | |||
8650 | <p><hr> | ||
8651 | Node:<a name="The_Flying_Fish_Approach_--_A_Simpler_Way_To_Do_It">The Flying Fish Approach -- A Simpler Way To Do It</a>, | ||
8652 | Next:<a rel=next href="#Branches_And_Keyword_Expansion_--_Natural_Enemies">Branches And Keyword Expansion -- Natural Enemies</a>, | ||
8653 | Previous:<a rel=previous href="#The_Dovetail_Approach_--_Merging_In_And_Out_Of_The_Trunk">The Dovetail Approach -- Merging In And Out Of The Trunk</a>, | ||
8654 | Up:<a rel=up href="#Going_Out_On_A_Limb__How_To_Work_With_Branches_And_Survive_">Going Out On A Limb (How To Work With Branches And Survive)</a> | ||
8655 | <br> | ||
8656 | |||
8657 | <h3>The Flying Fish Approach - A Simpler Way To Do It</h3> | ||
8658 | |||
8659 | <p>There is a simpler, albeit slightly limiting, variant of the preceding. | ||
8660 | In it, the branch developers freeze while the trunk merges, and then the | ||
8661 | trunk developers create an entirely new branch, which replaces the old | ||
8662 | one. The branch developers move onto that branch and continue working. | ||
8663 | The cycle continues until there is no more need for branch development. | ||
8664 | It goes something like this (in shorthand - we'll assume jrandom@floss | ||
8665 | has the trunk and qsmith@paste has the branch, as usual): | ||
8666 | |||
8667 | <pre>floss$ cvs tag -b BRANCH-1 | ||
8668 | paste$ cvs checkout -r BRANCH-1 myproj | ||
8669 | </pre> | ||
8670 | |||
8671 | <p>Trunk and branch both start working; eventually, the developers confer | ||
8672 | and decide it's time to merge the branch into the trunk: | ||
8673 | |||
8674 | <pre>paste$ cvs ci -m "committing all uncommitted changes" | ||
8675 | floss$ cvs update -j BRANCH-1 | ||
8676 | </pre> | ||
8677 | |||
8678 | <p>All the changes from the branch merge in; the branch developers stop | ||
8679 | working while the trunk developers resolve any conflicts, commit, tag, | ||
8680 | and create a new branch: | ||
8681 | |||
8682 | <pre>floss$ cvs ci -m "merged from BRANCH-1" | ||
8683 | floss$ cvs tag merged-from-BRANCH-1 | ||
8684 | floss$ cvs tag -b BRANCH-2 | ||
8685 | </pre> | ||
8686 | |||
8687 | <p>Now the branch developers switch their working copies over to the new | ||
8688 | branch; they know they won't lose any uncommitted changes by doing so, | ||
8689 | because they were up-to-date when the merge happened, and the new branch | ||
8690 | is coming out of a trunk that has incorporated the changes from the old | ||
8691 | branch: | ||
8692 | |||
8693 | <pre>paste$ cvs update -r BRANCH-2 | ||
8694 | </pre> | ||
8695 | |||
8696 | <p>And the cycle continues in that way, indefinitely; just substitute | ||
8697 | BRANCH-2 for BRANCH-1 and BRANCH-3 for BRANCH-2. | ||
8698 | |||
8699 | <p>I call this the <dfn>Flying Fish</dfn> technique, because the branch is | ||
8700 | constantly emerging from the trunk, traveling a short distance, then | ||
8701 | rejoining it. The advantages of this approach are that it's simple (the | ||
8702 | trunk always merges in all the changes from a given branch) and the | ||
8703 | branch developers never need to resolve conflicts (they're simply handed | ||
8704 | a new, clean branch on which to work each time). The disadvantage, of | ||
8705 | course, is that the branch people must sit idle while the trunk is | ||
8706 | undergoing merge (which can take an arbitrary amount of time, depending | ||
8707 | on how many conflicts need to be resolved). Another minor disadvantage | ||
8708 | is that it results in many little, unused branches laying around instead | ||
8709 | of many unused non-branch tags. However, if having millions of tiny, | ||
8710 | obsolete branches doesn't bother you, and you anticipate fairly | ||
8711 | trouble-free merges, Flying Fish may be the easiest way to go in terms | ||
8712 | of mental bookkeeping. | ||
8713 | |||
8714 | <p>Whichever way you do it, you should try to keep the separations as short | ||
8715 | as possible. If the branch and the trunk go too long without merging, | ||
8716 | they could easily begin to suffer not just from textual drift, but | ||
8717 | semantic drift as well. Changes that conflict textually are the easiest | ||
8718 | ones to resolve. Changes that conflict conceptually, but not textually, | ||
8719 | often prove hardest to find and fix. The isolation of a branch, so | ||
8720 | freeing to the developers, is dangerous precisely because it shields | ||
8721 | each side from the effects of others' changes...for a time. When you | ||
8722 | use branches, communication becomes more vital than ever: Everyone needs | ||
8723 | to make extra sure to review each others' plans and code to ensure that | ||
8724 | they're all staying on the same track. | ||
8725 | |||
8726 | <p><hr> | ||
8727 | Node:<a name="Branches_And_Keyword_Expansion_--_Natural_Enemies">Branches And Keyword Expansion -- Natural Enemies</a>, | ||
8728 | Previous:<a rel=previous href="#The_Flying_Fish_Approach_--_A_Simpler_Way_To_Do_It">The Flying Fish Approach -- A Simpler Way To Do It</a>, | ||
8729 | Up:<a rel=up href="#Going_Out_On_A_Limb__How_To_Work_With_Branches_And_Survive_">Going Out On A Limb (How To Work With Branches And Survive)</a> | ||
8730 | <br> | ||
8731 | |||
8732 | <h3>Branches And Keyword Expansion - Natural Enemies</h3> | ||
8733 | |||
8734 | <p>If your files contain RCS keywords that expand differently on branch and | ||
8735 | trunk, you're almost guaranteed to get spurious conflicts on every | ||
8736 | merge. Even if nothing else changed, the keywords are overlapping, and | ||
8737 | their expansions won't match. For example, if README.txt contains this | ||
8738 | on the trunk | ||
8739 | |||
8740 | <pre>$Revision$ | ||
8741 | </pre> | ||
8742 | |||
8743 | <p>and this on the branch | ||
8744 | |||
8745 | <pre>$Revision$ | ||
8746 | </pre> | ||
8747 | |||
8748 | <p>then when the merge is performed, you'll get the following conflict: | ||
8749 | |||
8750 | <pre>floss$ cvs update -j Exotic_Greetings-branch | ||
8751 | RCS file: /usr/local/newrepos/myproj/README.txt,v | ||
8752 | retrieving revision 1.14 | ||
8753 | retrieving revision 1.14.2.1 | ||
8754 | Merging differences between 1.14 and 1.14.2.1 into README.txt | ||
8755 | rcsmerge: warning: conflicts during merge | ||
8756 | floss$ cat README.txt | ||
8757 | ... | ||
8758 | <<<<<<< README.txt | ||
8759 | key $Revision$ | ||
8760 | ======= | ||
8761 | key $Revision$ | ||
8762 | >>>>>>> 1.14.2.1 | ||
8763 | ... | ||
8764 | floss$ | ||
8765 | </pre> | ||
8766 | |||
8767 | <p>To avoid this, you can temporarily disable expansion by passing the -kk | ||
8768 | option (I don't know what it stands for; "kill keywords" maybe?) when | ||
8769 | you do the merge: | ||
8770 | |||
8771 | <pre>floss$ cvs update -kk -j Exotic_Greetings-branch | ||
8772 | RCS file: /usr/local/newrepos/myproj/README.txt,v | ||
8773 | retrieving revision 1.14 | ||
8774 | retrieving revision 1.14.2.1 | ||
8775 | Merging differences between 1.14 and 1.14.2.1 into README.txt | ||
8776 | floss$ cat README.txt | ||
8777 | ... | ||
8778 | $Revision$ | ||
8779 | ... | ||
8780 | floss$ | ||
8781 | </pre> | ||
8782 | |||
8783 | <p>There is one thing to be careful of, however: If you use -kk, it | ||
8784 | overrides whatever other keyword expansion mode you may have set for | ||
8785 | that file. Specifically, this is a problem for binary files, which are | ||
8786 | normally -kb (which suppresses all keyword expansion and line-end | ||
8787 | conversion). So if you have to merge binary files in from a branch, | ||
8788 | don't use -kk. Just deal with the conflicts by hand instead. | ||
8789 | |||
8790 | <p><hr> | ||
8791 | Node:<a name="Tracking_Third-Party_Sources__Vendor_Branches_">Tracking Third-Party Sources (Vendor Branches)</a>, | ||
8792 | Next:<a rel=next href="#Exporting_For_Public_Distribution">Exporting For Public Distribution</a>, | ||
8793 | Previous:<a rel=previous href="#Going_Out_On_A_Limb__How_To_Work_With_Branches_And_Survive_">Going Out On A Limb (How To Work With Branches And Survive)</a>, | ||
8794 | Up:<a rel=up href="#Advanced_CVS">Advanced CVS</a> | ||
8795 | <br> | ||
8796 | |||
8797 | <h2>Tracking Third-Party Sources (Vendor Branches)</h2> | ||
8798 | |||
8799 | <p>Sometimes a site will make local changes to a piece of software received | ||
8800 | from an outside source. If the outside source does not incorporate the | ||
8801 | local changes (and there might be many legitimate reasons why it can't), | ||
8802 | the site has to maintain its changes in each received upgrade of the | ||
8803 | software. | ||
8804 | |||
8805 | <p>CVS can help with this task, via a feature known as <dfn>vendor | ||
8806 | branches</dfn>. In fact, vendor branches are the explanation behind the | ||
8807 | puzzling (until now) final two arguments to cvs import: the vendor tag | ||
8808 | and release tag that I glossed over in <a href="#An_Overview_of_CVS">An Overview of CVS</a>. | ||
8809 | |||
8810 | <p>Here's how it works. The initial import is just like any other initial | ||
8811 | import of a CVS project (except that you'll want to choose the vendor | ||
8812 | tag and release tag with a little care): | ||
8813 | |||
8814 | <pre>floss$ pwd | ||
8815 | /home/jrandom/theirproj-1.0 | ||
8816 | floss$ cvs import -m "Import of TheirProj 1.0" theirproj Them THEIRPROJ_1_0 | ||
8817 | N theirproj/INSTALL | ||
8818 | N theirproj/README | ||
8819 | N theirproj/src/main.c | ||
8820 | N theirproj/src/parse.c | ||
8821 | N theirproj/src/digest.c | ||
8822 | N theirproj/doc/random.c | ||
8823 | N theirproj/doc/manual.txt | ||
8824 | |||
8825 | No conflicts created by this import | ||
8826 | |||
8827 | floss$ | ||
8828 | </pre> | ||
8829 | |||
8830 | <p>Then you check out a working copy somewhere, make your local | ||
8831 | modifications, and commit: | ||
8832 | |||
8833 | <pre>floss$ cvs -q co theirproj | ||
8834 | U theirproj/INSTALL | ||
8835 | U theirproj/README | ||
8836 | U theirproj/doc/manual.txt | ||
8837 | U theirproj/doc/random.c | ||
8838 | U theirproj/src/digest.c | ||
8839 | U theirproj/src/main.c | ||
8840 | U theirproj/src/parse.c | ||
8841 | floss$ cd theirproj | ||
8842 | floss$ emacs src/main.c src/digest.c | ||
8843 | ... | ||
8844 | floss$ cvs -q update | ||
8845 | M src/digest.c | ||
8846 | M src/main.c | ||
8847 | floss$ cvs -q ci -m "changed digestion algorithm; added comment to main" | ||
8848 | Checking in src/digest.c; | ||
8849 | /usr/local/newrepos/theirproj/src/digest.c,v <-- digest.c | ||
8850 | new revision: 1.2; previous revision: 1.1 | ||
8851 | done | ||
8852 | Checking in src/main.c; | ||
8853 | /usr/local/newrepos/theirproj/src/main.c,v <-- main.c | ||
8854 | new revision: 1.2; previous revision: 1.1 | ||
8855 | done | ||
8856 | floss$ | ||
8857 | </pre> | ||
8858 | |||
8859 | <p>A year later, the next version of the software arrives from Them, Inc., | ||
8860 | and you must incorporate your local changes into it. Their changes and | ||
8861 | yours overlap slightly. They've added one new file, modified a couple | ||
8862 | of files that you didn't touch, but also modified two files that you | ||
8863 | modified. | ||
8864 | |||
8865 | <p>First you must do another import, this time from the new sources. | ||
8866 | Almost everything is the same as it was in the initial import - you're | ||
8867 | importing to the same project in the repository, and on the same vendor | ||
8868 | branch. The only thing different is the release tag: | ||
8869 | |||
8870 | <pre>floss$ pwd | ||
8871 | /home/jrandom/theirproj-2.0 | ||
8872 | floss$ cvs -q import -m "Import of TheirProj 2.0" theirproj Them THEIRPROJ_2_0 | ||
8873 | U theirproj/INSTALL | ||
8874 | N theirproj/TODO | ||
8875 | U theirproj/README | ||
8876 | cvs import: Importing /usr/local/newrepos/theirproj/src | ||
8877 | C theirproj/src/main.c | ||
8878 | U theirproj/src/parse.c | ||
8879 | C theirproj/src/digest.c | ||
8880 | cvs import: Importing /usr/local/newrepos/theirproj/doc | ||
8881 | U theirproj/doc/random.c | ||
8882 | U theirproj/doc/manual.txt | ||
8883 | |||
8884 | 2 conflicts created by this import. | ||
8885 | Use the following command to help the merge: | ||
8886 | |||
8887 | cvs checkout -jThem:yesterday -jThem theirproj | ||
8888 | |||
8889 | floss$ | ||
8890 | </pre> | ||
8891 | |||
8892 | <p>My goodness - we've never seen CVS try to be so helpful. It's actually | ||
8893 | telling us what command to run to merge the changes. And it's almost | ||
8894 | right, too! Actually, the command as given works (assuming that you | ||
8895 | adjust yesterday to be any time interval that definitely includes the | ||
8896 | first import but not the second), but I mildly prefer to do it by | ||
8897 | release tag instead: | ||
8898 | |||
8899 | <pre>floss$ cvs checkout -j THEIRPROJ_1_0 -j THEIRPROJ_2_0 theirproj | ||
8900 | cvs checkout: Updating theirproj | ||
8901 | U theirproj/INSTALL | ||
8902 | U theirproj/README | ||
8903 | U theirproj/TODO | ||
8904 | cvs checkout: Updating theirproj/doc | ||
8905 | U theirproj/doc/manual.txt | ||
8906 | U theirproj/doc/random.c | ||
8907 | cvs checkout: Updating theirproj/src | ||
8908 | U theirproj/src/digest.c | ||
8909 | RCS file: /usr/local/newrepos/theirproj/src/digest.c,v | ||
8910 | retrieving revision 1.1.1.1 | ||
8911 | retrieving revision 1.1.1.2 | ||
8912 | Merging differences between 1.1.1.1 and 1.1.1.2 into digest.c | ||
8913 | rcsmerge: warning: conflicts during merge | ||
8914 | U theirproj/src/main.c | ||
8915 | RCS file: /usr/local/newrepos/theirproj/src/main.c,v | ||
8916 | retrieving revision 1.1.1.1 | ||
8917 | retrieving revision 1.1.1.2 | ||
8918 | Merging differences between 1.1.1.1 and 1.1.1.2 into main.c | ||
8919 | U theirproj/src/parse.c | ||
8920 | floss$ | ||
8921 | </pre> | ||
8922 | |||
8923 | <p>Notice how the import told us that there were two conflicts, but the | ||
8924 | merge only seems to claim one conflict. It seems that CVS's idea of a | ||
8925 | conflict is a little different when importing than at other times. | ||
8926 | Basically, import reports a conflict if both you and the vendor modified | ||
8927 | a file between the last import and this one. However, when it comes | ||
8928 | time to merge, update sticks with the usual definition of "conflict" - | ||
8929 | overlapping changes. Changes that don't overlap are merged in the usual | ||
8930 | way, and the file is simply marked as modified. | ||
8931 | |||
8932 | <p>A quick diff verifies that only one of the files actually has conflict | ||
8933 | markers: | ||
8934 | |||
8935 | <pre>floss$ cvs -q update | ||
8936 | C src/digest.c | ||
8937 | M src/main.c | ||
8938 | floss$ cvs diff -c | ||
8939 | Index: src/digest.c | ||
8940 | =================================================================== | ||
8941 | RCS file: /usr/local/newrepos/theirproj/src/digest.c,v | ||
8942 | retrieving revision 1.2 | ||
8943 | diff -c -r1.2 digest.c | ||
8944 | *** src/digest.c 1999/07/26 08:02:18 1.2 | ||
8945 | -- src/digest.c 1999/07/26 08:16:15 | ||
8946 | *************** | ||
8947 | *** 3,7 **** | ||
8948 | -- 3,11 ---- | ||
8949 | void | ||
8950 | digest () | ||
8951 | { | ||
8952 | + <<<<<<< digest.c | ||
8953 | printf ("gurgle, slorp\n"); | ||
8954 | + ======= | ||
8955 | + printf ("mild gurgle\n"); | ||
8956 | + >>>>>>> 1.1.1.2 | ||
8957 | } | ||
8958 | Index: src/main.c | ||
8959 | =================================================================== | ||
8960 | RCS file: /usr/local/newrepos/theirproj/src/main.c,v | ||
8961 | retrieving revision 1.2 | ||
8962 | diff -c -r1.2 main.c | ||
8963 | *** src/main.c 1999/07/26 08:02:18 1.2 | ||
8964 | -- src/main.c 1999/07/26 08:16:15 | ||
8965 | *************** | ||
8966 | *** 7,9 **** | ||
8967 | -- 7,11 ---- | ||
8968 | { | ||
8969 | printf ("Goodbye, world!\n"); | ||
8970 | } | ||
8971 | + | ||
8972 | + /* I, the vendor, added this comment for no good reason. */ | ||
8973 | floss$ | ||
8974 | </pre> | ||
8975 | |||
8976 | <p>From here, it's just a matter of resolving the conflicts as with any | ||
8977 | other merge: | ||
8978 | |||
8979 | <pre>floss$ emacs src/digest.c src/main.c | ||
8980 | ... | ||
8981 | floss$ cvs -q update | ||
8982 | M src/digest.c | ||
8983 | M src/main.c | ||
8984 | floss$ cvs diff src/digest.c | ||
8985 | cvs diff src/digest.c | ||
8986 | Index: src/digest.c | ||
8987 | =================================================================== | ||
8988 | RCS file: /usr/local/newrepos/theirproj/src/digest.c,v | ||
8989 | retrieving revision 1.2 | ||
8990 | diff -r1.2 digest.c | ||
8991 | 6c6 | ||
8992 | < printf ("gurgle, slorp\n"); | ||
8993 | -- | ||
8994 | > printf ("mild gurgle, slorp\n"); | ||
8995 | floss$ | ||
8996 | </pre> | ||
8997 | |||
8998 | <p>Then commit the changes | ||
8999 | |||
9000 | <pre>floss$ cvs -q ci -m "Resolved conflicts with import of 2.0" | ||
9001 | Checking in src/digest.c; | ||
9002 | /usr/local/newrepos/theirproj/src/digest.c,v <-- digest.c | ||
9003 | new revision: 1.3; previous revision: 1.2 | ||
9004 | done | ||
9005 | Checking in src/main.c; | ||
9006 | /usr/local/newrepos/theirproj/src/main.c,v <-- main.c | ||
9007 | new revision: 1.3; previous revision: 1.2 | ||
9008 | done | ||
9009 | floss$ | ||
9010 | </pre> | ||
9011 | |||
9012 | <p>and wait for the next release from the vendor. (Of course, you'll also | ||
9013 | want to test that your local modifications still work!) | ||
9014 | |||
9015 | <p>------------------------------------------------------------- | ||
9016 | <p><hr> | ||
9017 | Node:<a name="Exporting_For_Public_Distribution">Exporting For Public Distribution</a>, | ||
9018 | Next:<a rel=next href="#The_Humble_Guru">The Humble Guru</a>, | ||
9019 | Previous:<a rel=previous href="#Tracking_Third-Party_Sources__Vendor_Branches_">Tracking Third-Party Sources (Vendor Branches)</a>, | ||
9020 | Up:<a rel=up href="#Advanced_CVS">Advanced CVS</a> | ||
9021 | <br> | ||
9022 | |||
9023 | <h2>Exporting For Public Distribution</h2> | ||
9024 | |||
9025 | <p>CVS is a good distribution mechanism for developers, but most users will | ||
9026 | obtain the software through a downloadable package instead. This | ||
9027 | package is generally not a CVS working copy - it's just a source tree | ||
9028 | that can be easily configured and compiled on the user's system. | ||
9029 | |||
9030 | <p>However, CVS does offer a mechanism to help you create that package, | ||
9031 | namely the <code>cvs export</code> command. To <dfn>export</dfn> a project is | ||
9032 | just like checking out a working copy of the project, except that it | ||
9033 | checks out the project tree <em>without</em> any <code>CVS</code> administrative | ||
9034 | subdirectories. That is to say, you don't get a working copy, you just | ||
9035 | get a source tree that knows nothing about where it came from or what | ||
9036 | the CVS versions of its files are. Thus, the exported copy is just like | ||
9037 | what the public sees after it downloads and unpacks a distribution. | ||
9038 | Assuming the project is arranged to be directly compilable from a | ||
9039 | working copy (and it certainly should be!), then it will still be | ||
9040 | compilable from the exported copy. | ||
9041 | |||
9042 | <p>The <code>export</code> command works like <code>checkout</code>, except that it | ||
9043 | requires a tag name or date. For example, here we tag the project with | ||
9044 | a release name, and then export based on that: | ||
9045 | |||
9046 | <pre>floss$ pwd | ||
9047 | /home/jrandom/myproj | ||
9048 | floss$ cvs -q tag R_1_0 | ||
9049 | T README.txt | ||
9050 | T hello.c | ||
9051 | T a-subdir/whatever.c | ||
9052 | T a-subdir/subsubdir/fish.c | ||
9053 | T b-subdir/random.c | ||
9054 | floss$ cd .. | ||
9055 | floss$ cvs -d /usr/local/newrepos -q export -r R_1_0 -d myproj-1.0 myproj | ||
9056 | U myproj-1.0/README.txt | ||
9057 | U myproj-1.0/hello.c | ||
9058 | U myproj-1.0/a-subdir/whatever.c | ||
9059 | U myproj-1.0/a-subdir/subsubdir/fish.c | ||
9060 | U myproj-1.0/b-subdir/random.c | ||
9061 | floss$ cd myproj-1.0 | ||
9062 | floss$ ls | ||
9063 | README.txt a-subdir b-subdir hello.c | ||
9064 | </pre> | ||
9065 | |||
9066 | <p>Notice how, since the <code>export</code> command is not invoked from within a | ||
9067 | working copy, it's necessary to use the global <code>-d</code> option to tell | ||
9068 | CVS which repository to use. Also, in this particular example, we | ||
9069 | exported into an explicitly named directory (<code>myproj-1.0</code>) instead | ||
9070 | of defaulting to the project's name (<code>myproj</code>), since there was a | ||
9071 | working copy of that name already present. This situation is not | ||
9072 | uncommon. | ||
9073 | |||
9074 | <p>After the exported copy is created, as in the above example, the | ||
9075 | following might be sufficient to complete the release, if the project is | ||
9076 | a simple one: | ||
9077 | |||
9078 | <pre>floss$ tar cf myproj-1.0.tar myproj-1.0 | ||
9079 | floss$ gzip --best myproj-1.0.tar | ||
9080 | floss$ ls | ||
9081 | myproj/ myproj-1.0/ myproj-1.0.tar.gz | ||
9082 | floss$ rm -rf myproj-1.0 | ||
9083 | floss$ mv myproj-1.0.tar.gz /home/ftp/pub/myproj/ | ||
9084 | </pre> | ||
9085 | |||
9086 | <p>Of course, running all of these commands by hand is rare. More often, | ||
9087 | <code>cvs export</code> is called from within some script that handles all | ||
9088 | aspects of release and packaging process. Given that there are often | ||
9089 | several "test" releases leading up to each public release, it is | ||
9090 | desirable that the procedures for creating a releasable package be | ||
9091 | highly automated. | ||
9092 | |||
9093 | <p><hr> | ||
9094 | Node:<a name="The_Humble_Guru">The Humble Guru</a>, | ||
9095 | Previous:<a rel=previous href="#Exporting_For_Public_Distribution">Exporting For Public Distribution</a>, | ||
9096 | Up:<a rel=up href="#Advanced_CVS">Advanced CVS</a> | ||
9097 | <br> | ||
9098 | |||
9099 | <h2>The Humble Guru</h2> | ||
9100 | |||
9101 | <p>If you read and understood (and better yet, experimented with) | ||
9102 | everything in this chapter, you may rest assured that there are no big | ||
9103 | surprises left for you in CVS - at least until someone adds a major new | ||
9104 | feature to CVS. Everything you need to know to use CVS on a major | ||
9105 | project has been presented. | ||
9106 | |||
9107 | <p>Before that goes to your head, let me reiterate the suggestion, first | ||
9108 | made in Chapter 4, that you subscribe to the <a href="mailto:info-cvs@gnu.org">info-cvs@gnu.org</a> | ||
9109 | mailing list. Despite having the impoverished signal-to-noise ratio | ||
9110 | common to most Internet mailing lists, the bits of signal that do come | ||
9111 | through are almost always worth the wait. I was subscribed during the | ||
9112 | entire time I wrote this chapter (indeed, for all previous chapters as | ||
9113 | well), and you would be amazed to know how many important details I | ||
9114 | learned about CVS's behavior from reading other people's posts. If | ||
9115 | you're going to be using CVS seriously, and especially if you're the CVS | ||
9116 | administrator for a group of developers, you can benefit a lot from the | ||
9117 | shared knowledge of all the other serious users out there. | ||
9118 | |||
9119 | <p><hr> | ||
9120 | Node:<a name="Tips_And_Troubleshooting">Tips And Troubleshooting</a>, | ||
9121 | Next:<a rel=next href="#CVS_Reference">CVS Reference</a>, | ||
9122 | Previous:<a rel=previous href="#Advanced_CVS">Advanced CVS</a>, | ||
9123 | Up:<a rel=up href="#Top">Top</a> | ||
9124 | <br> | ||
9125 | |||
9126 | <h1>Tips And Troubleshooting</h1> | ||
9127 | |||
9128 | <p>I've said in earlier chapters that CVS is not "black box" software. | ||
9129 | Black boxes don't let you peek inside; they don't give you internal | ||
9130 | access so that you can fix (or break) things. The premise is that the | ||
9131 | black box usually doesn't need to be fixed. Most of the time, the | ||
9132 | software should work perfectly, so users don't need internal access. | ||
9133 | But when black boxes do fail, they tend to fail completely. Any problem | ||
9134 | at all is a showstopper, because there aren't many options for repair. | ||
9135 | |||
9136 | <p>CVS is more like a perfectly transparent box - except without the box. | ||
9137 | Its moving parts are exposed directly to the environment, not | ||
9138 | hermetically sealed off, and bits of that environment (unexpected file | ||
9139 | permissions, interrupted commands, competing processes, whatever) can | ||
9140 | sometimes get inside the mechanism and gum up the gears. But even | ||
9141 | though CVS does not always work perfectly, it rarely fails completely, | ||
9142 | either. It has the advantage of graceful degradation; the degree to | ||
9143 | which it doesn't work is usually proportional to the number and severity | ||
9144 | of problems in its environment. If you know enough about what CVS is | ||
9145 | trying to do - and how it's trying to do it - you'll know what to do | ||
9146 | when things go wrong. | ||
9147 | |||
9148 | <p>Although I can't list all of the problems that you might encounter, I've | ||
9149 | included some of the more common ones here. This chapter is divided | ||
9150 | into two sections: The first describes those parts of the environment to | ||
9151 | which CVS is most sensitive (mainly repository permissions and the | ||
9152 | working copy administrative area), and the second describes some of the | ||
9153 | most frequently encountered problems and their solutions. By seeing how | ||
9154 | to handle these common situations, you will get a feeling for how to | ||
9155 | approach any unexpected problem in CVS. | ||
9156 | |||
9157 | <ul> | ||
9158 | <li><a href="#The_Usual_Suspects">The Usual Suspects</a>: Things that often cause trouble. | ||
9159 | <li><a href="#General_Troubleshooting_Tips">General Troubleshooting Tips</a>: General diagnostic techniques. | ||
9160 | <li><a href="#Some_Real_Life_Problems__With_Solutions_">Some Real Life Problems (With Solutions)</a>: A compendium of actual problems. | ||
9161 | </ul> | ||
9162 | |||
9163 | <p><hr> | ||
9164 | Node:<a name="The_Usual_Suspects">The Usual Suspects</a>, | ||
9165 | Next:<a rel=next href="#General_Troubleshooting_Tips">General Troubleshooting Tips</a>, | ||
9166 | Up:<a rel=up href="#Tips_And_Troubleshooting">Tips And Troubleshooting</a> | ||
9167 | <br> | ||
9168 | |||
9169 | <h2>The Usual Suspects</h2> | ||
9170 | |||
9171 | <p>As a CVS administrator (read "field doctor"), you will find that 90 | ||
9172 | percent of your users' problems are caused by inconsistent working | ||
9173 | copies, and the other 90 percent by incorrect repository permissions. | ||
9174 | Therefore, before looking at any specific situations, I'll give a quick | ||
9175 | overview of the working copy administrative area and review a few | ||
9176 | important things about repository permissions. | ||
9177 | |||
9178 | <ul> | ||
9179 | <li><a href="#The_Working_Copy_Administrative_Area">The Working Copy Administrative Area</a>: | ||
9180 | <li><a href="#Repository_Permissions">Repository Permissions</a>: | ||
9181 | </ul> | ||
9182 | |||
9183 | <p><hr> | ||
9184 | Node:<a name="The_Working_Copy_Administrative_Area">The Working Copy Administrative Area</a>, | ||
9185 | Next:<a rel=next href="#Repository_Permissions">Repository Permissions</a>, | ||
9186 | Up:<a rel=up href="#The_Usual_Suspects">The Usual Suspects</a> | ||
9187 | <br> | ||
9188 | |||
9189 | <h3>The Working Copy Administrative Area</h3> | ||
9190 | |||
9191 | <p>You've already seen the basics of working copy structure in <a href="#An_Overview_of_CVS">An Overview of CVS</a>; in this section, we'll go into a bit more detail. | ||
9192 | Most of the details concern the files in the CVS/ administrative | ||
9193 | subdirectories. You already know about Entries, Root, and Repository, | ||
9194 | but the CVS/ subdirectory can also contain other files, depending on the | ||
9195 | circumstances. I'll describe those other files here, partly so they | ||
9196 | don't surprise you when you encounter them, and partly so you can fix | ||
9197 | them if they ever cause trouble. | ||
9198 | |||
9199 | <h2><code>CVS/Entries.Log</code></h2> | ||
9200 | |||
9201 | <p>Sometimes, a file named <code>CVS/Entries.Log</code> will mysteriously appear. | ||
9202 | The sole purpose of this file is to temporarily cache minor changes to | ||
9203 | CVS/Entries, until some operation significant enough to be worth | ||
9204 | rewriting the entire Entries file comes along. CVS has no ability to | ||
9205 | edit the Entries file in place; it must read the entire file in and | ||
9206 | write it back out to make any change. To avoid this effort, CVS | ||
9207 | sometimes records small changes in Entries.Log, until the next time it | ||
9208 | needs to rewrite Entries. | ||
9209 | |||
9210 | <p>The format of Entries.Log is like Entries, except for an extra letter at | ||
9211 | the beginning of each line. <code>A</code> means that the line is to be added | ||
9212 | to the main Entries file, and <code>R</code> means it is to be removed. | ||
9213 | |||
9214 | <p>For the most part, you can ignore Entries.Log; it's rare that a human | ||
9215 | has to understand the information it contains. However, if you're | ||
9216 | reading over an Entries file to debug some problem in a working copy, | ||
9217 | you should also examine Entries.Log. | ||
9218 | |||
9219 | <h2><code>CVS/Entries.Backup</code></h2> | ||
9220 | |||
9221 | <p>The CVS/Entries.Backup file is where CVS actually writes out a new | ||
9222 | Entries file, before renaming it to <code>Entries</code> (similar to the way | ||
9223 | it writes to temporary RCS files in the repository and then moves them | ||
9224 | to their proper name when they're complete). Because it becomes Entries | ||
9225 | when it's complete, you'll rarely see an Entries.Backup file; if you do | ||
9226 | see one, it probably means CVS got interrupted in the middle of some | ||
9227 | operation. | ||
9228 | |||
9229 | <h2><code>CVS/Entries.Static</code></h2> | ||
9230 | |||
9231 | <p>If the CVS/Entries.Static file exists, it means that the entire | ||
9232 | directory has not been fetched from the repository. (When CVS knows a | ||
9233 | working directory is in an incomplete state, it will not bring | ||
9234 | additional files into that directory.) | ||
9235 | |||
9236 | <p>The Entries.Static file is present during checkouts and updates and | ||
9237 | removed immediately when the operation is complete. If you see | ||
9238 | Entries.Static, it means that CVS was interrupted, and its presence | ||
9239 | prevents CVS from creating any new files in the working copy. (Often, | ||
9240 | running <code>cvs update -d</code> solves the problem and removes | ||
9241 | Entries.Static.) | ||
9242 | |||
9243 | <p>The absence of Entries.Static does not necessarily imply that the | ||
9244 | working copy contains all of the project's files. Whenever a new | ||
9245 | directory is created in the project's repository, and someone updates | ||
9246 | their working copy without passing the -d flag to update, the new | ||
9247 | directory will not be created in the working copy. Locally, CVS is | ||
9248 | unaware that there is a new directory in the repository, so it goes | ||
9249 | ahead and removes the Entries.Static file when the update is complete, | ||
9250 | even though the new directory is not present in the working copy. | ||
9251 | |||
9252 | <h2><code>CVS/Tag</code></h2> | ||
9253 | |||
9254 | <p>If the CVS/Tag file is present, it names a tag associated, in some | ||
9255 | sense, with the directory. I say "in some sense" because, as you know, | ||
9256 | CVS does not actually keep any revision history for directories and, | ||
9257 | strictly speaking, cannot attach tags to them. Tags are attached to | ||
9258 | regular files only or, more accurately, to particular revisions in | ||
9259 | regular files. | ||
9260 | |||
9261 | <p>However, if every file in a directory is on a particular tag, CVS likes | ||
9262 | to think of the entire directory as being on the tag, too. For example, | ||
9263 | if you were to check out a working copy on a particular branch: | ||
9264 | |||
9265 | <pre>floss$ cvs co -r Bugfix_Branch_1 | ||
9266 | </pre> | ||
9267 | |||
9268 | <p>and then add a file inside it, you'd want the new file's initial | ||
9269 | revision to be on that branch, too. For similar reasons, CVS also needs | ||
9270 | to know if the directory has a nonbranch sticky tag or date set on it. | ||
9271 | |||
9272 | <p>Tag files contain one line. The first character on the line is a | ||
9273 | single-letter code telling what kind of tag it is, and the rest of the | ||
9274 | line is the tag's name. Currently, CVS uses only these three | ||
9275 | single-letter codes: | ||
9276 | |||
9277 | <ul> | ||
9278 | |||
9279 | <li>T - A branch tag | ||
9280 | |||
9281 | <li>N - A nonbranch (regular) tag | ||
9282 | |||
9283 | <li>D - A sticky date, which occurs if a command such as | ||
9284 | |||
9285 | <pre>floss$ cvs checkout -D 1999-05-15 myproj | ||
9286 | </pre> | ||
9287 | |||
9288 | <p>or | ||
9289 | |||
9290 | <pre>floss$ cvs update -D 1999-05-15 myproj | ||
9291 | </pre> | ||
9292 | |||
9293 | <p>is run. | ||
9294 | |||
9295 | </ul> | ||
9296 | |||
9297 | <p>(If you see some other single-letter code, it just means that CVS has | ||
9298 | added a new tag type since this chapter was written.) | ||
9299 | |||
9300 | <p>You should not remove the Tag file manually; instead, use <code>cvs update -A</code>. | ||
9301 | |||
9302 | <h2>Rarities</h2> | ||
9303 | |||
9304 | <p>There are a few other files you may occasionally find in a CVS/ subdirectory: | ||
9305 | |||
9306 | <ul> | ||
9307 | <li>CVS/Checkin.prog, CVS/Update.prog | ||
9308 | <li>CVS/Notify, CVS/Notify.tmp | ||
9309 | <li>CVS/Base/, CVS/Baserev, CVS/Baserev.tmp | ||
9310 | <li>CVS/Template | ||
9311 | </ul> | ||
9312 | |||
9313 | <p>These files are usually not the cause of problems, so I'm just listing | ||
9314 | them (see <a href="#CVS_Reference">CVS Reference</a> for their full descriptions). | ||
9315 | |||
9316 | <h2>Portability And Future Extension</h2> | ||
9317 | |||
9318 | <p>As features are added to CVS, new files (not listed here) may appear in | ||
9319 | working copy administrative areas. As new files are added, they'll | ||
9320 | probably be documented in the Cederqvist manual, in the node | ||
9321 | <cite>Working Directory Storage</cite>. You can also start looking in | ||
9322 | src/cvs.h in the source distribution, if you prefer to learn from code. | ||
9323 | |||
9324 | <p>Finally, note that all CVS/* files - present and future - use whatever | ||
9325 | line-ending convention is appropriate for the working copy's local | ||
9326 | system (for example, LF for Unix or CRLF for Windows). This means that | ||
9327 | if you transport a working copy from one kind of machine to the other, | ||
9328 | CVS won't be able to handle it (but then, you'd have other problems, | ||
9329 | because the revision-controlled files themselves would have the wrong | ||
9330 | line-end conventions for their new location). | ||
9331 | |||
9332 | <p><hr> | ||
9333 | Node:<a name="Repository_Permissions">Repository Permissions</a>, | ||
9334 | Previous:<a rel=previous href="#The_Working_Copy_Administrative_Area">The Working Copy Administrative Area</a>, | ||
9335 | Up:<a rel=up href="#The_Usual_Suspects">The Usual Suspects</a> | ||
9336 | <br> | ||
9337 | |||
9338 | <h3>Repository Permissions</h3> | ||
9339 | |||
9340 | <p>CVS does not require any particular repository permission scheme - it | ||
9341 | can handle a wide variety of permission arrangements. However, to avoid | ||
9342 | getting confusing behaviors, you should make sure your repository setup | ||
9343 | meets at least the following criteria: | ||
9344 | |||
9345 | <ul> | ||
9346 | |||
9347 | <li>If a user wants any kind of access at all - even read-only access - to | ||
9348 | a given subdirectory of the repository, she usually needs file | ||
9349 | system-level write permission to that subdirectory. This is necessary | ||
9350 | because CVS creates temporary lock files in the repository to ensure | ||
9351 | data consistency. Even read-only operations (such as checkout or | ||
9352 | update) create locks, to signal that they need the data to stay in one | ||
9353 | state until they're done. | ||
9354 | |||
9355 | <p>As noted in <a href="#Repository_Administration">Repository Administration</a>, you can get around this | ||
9356 | writeability requirement by setting the LockDir parameter in | ||
9357 | CVSROOT/config, like this: | ||
9358 | |||
9359 | <pre>LockDir=/usr/local/cvslocks | ||
9360 | </pre> | ||
9361 | |||
9362 | <p>Of course, then you would need to make sure the directory | ||
9363 | /usr/local/cvslocks is writeable by all CVS users. Either way, most CVS | ||
9364 | operations, including read-only ones, are going to require a writeable | ||
9365 | directory somewhere. By default, that directory is the project's | ||
9366 | repository; if you're very security conscious, you can change it to be | ||
9367 | somewhere else. | ||
9368 | |||
9369 | </p><li>Make sure the CVSROOT/history file is world-writeable (if it exists at | ||
9370 | all). If the history file exists, most CVS operations attempt to append | ||
9371 | a record to it; if the attempt fails, the operation exits with an error. | ||
9372 | |||
9373 | <p>Unfortunately (and inexplicably), the history file is not born | ||
9374 | world-writeable when you create a new repository with cvs init. At | ||
9375 | least with the current version of CVS, you should explicitly change its | ||
9376 | permissions after you create a new repository (or just remove it, if you | ||
9377 | want to disable history logging entirely). | ||
9378 | |||
9379 | <p>(This problem may go away - I just now submitted a patch to the CVS | ||
9380 | maintainers that makes the history file world-writeable when you | ||
9381 | initialize a new repository. So perhaps if you get a more recent | ||
9382 | version of CVS than the one available now (September 1999), it won't be | ||
9383 | a problem for you.) | ||
9384 | |||
9385 | </p><li>For security purposes, you almost certainly want to make sure that most | ||
9386 | CVS users do not have Unix-level write access to the CVSROOT directory | ||
9387 | in the repository. If someone has checkin access to CVSROOT, they can | ||
9388 | edit commitinfo, loginfo, or any of the other trigger files to invoke a | ||
9389 | program of their choice - they could even commit a new program if the | ||
9390 | one they want isn't on the system already. Therefore, you should assume | ||
9391 | that anyone who has commit access to CVSROOT is able to run arbitrary | ||
9392 | commands on the system. | ||
9393 | |||
9394 | </ul> | ||
9395 | |||
9396 | <p><hr> | ||
9397 | Node:<a name="General_Troubleshooting_Tips">General Troubleshooting Tips</a>, | ||
9398 | Next:<a rel=next href="#Some_Real_Life_Problems__With_Solutions_">Some Real Life Problems (With Solutions)</a>, | ||
9399 | Previous:<a rel=previous href="#The_Usual_Suspects">The Usual Suspects</a>, | ||
9400 | Up:<a rel=up href="#Tips_And_Troubleshooting">Tips And Troubleshooting</a> | ||
9401 | <br> | ||
9402 | |||
9403 | <h2>General Troubleshooting Tips</h2> | ||
9404 | |||
9405 | <p>The bulk of this chapter is organized into a series of questions and | ||
9406 | answers, similar to an Internet FAQ (Frequently Asked Questions) | ||
9407 | document. These are all based on actual CVS experiences. But before we | ||
9408 | look at individual cases, let's take a moment to consider CVS | ||
9409 | troubleshooting from a more general point of view. | ||
9410 | |||
9411 | <p>The first step in solving a CVS problem is usually to determine whether | ||
9412 | it's a working copy or repository problem. The best technique for doing | ||
9413 | that, not surprisingly, is to see if the problem occurs in working | ||
9414 | copies other than the one where it was first noticed. If it does, it's | ||
9415 | likely a repository issue; otherwise, it's probably just a local issue. | ||
9416 | |||
9417 | <p>Working copy problems tend to be encountered more frequently, not | ||
9418 | because working copies are somehow less reliable than repositories, but | ||
9419 | because each repository usually has many working copies. Although most | ||
9420 | working copy knots can be untied with enough patience, you may | ||
9421 | occasionally find it more time-efficient simply to delete the working | ||
9422 | copy and check it out again. | ||
9423 | |||
9424 | <p>Of course, if checking out again takes too long, or there is | ||
9425 | considerable uncommitted state in the working copy that you don't want | ||
9426 | to lose, or if you just want to know what's wrong, it's worth digging | ||
9427 | around to find the cause of the problem. When you start digging around, | ||
9428 | one of the first places to look is in the CVS/ subdirectories. Check | ||
9429 | the file contents and the file permissions. Very occasionally, the | ||
9430 | permissions can mysteriously become read-only or even unreadable. (I | ||
9431 | suspect this is caused by users accidentally mistyping Unix commands | ||
9432 | rather than any mistake on CVS's part.) | ||
9433 | |||
9434 | <p>Repository problems are almost always caused by incorrect file and | ||
9435 | directory permissions. If you suspect a problem may be due to bad | ||
9436 | repository permissions, first find out the effective repository user ID | ||
9437 | of the person who's having the trouble. For all local and most remote | ||
9438 | users, this is either their regular username or the username they | ||
9439 | specified when they checked out their working copy. If they're using | ||
9440 | the pserver method with user-aliasing (see the section <a href="#Anonymous_Access">Anonymous Access</a> in <a href="#Repository_Administration">Repository Administration</a>), the effective user ID is | ||
9441 | the one on the right in the CVSROOT/passwd file. Failure to discover | ||
9442 | this early on can cause you to waste a lot of time debugging the wrong | ||
9443 | thing. | ||
9444 | |||
9445 | <p>And now, without further ado... | ||
9446 | |||
9447 | <p><hr> | ||
9448 | Node:<a name="Some_Real_Life_Problems__With_Solutions_">Some Real Life Problems (With Solutions)</a>, | ||
9449 | Previous:<a rel=previous href="#General_Troubleshooting_Tips">General Troubleshooting Tips</a>, | ||
9450 | Up:<a rel=up href="#Tips_And_Troubleshooting">Tips And Troubleshooting</a> | ||
9451 | <br> | ||
9452 | |||
9453 | <h2>Some Real Life Problems (With Solutions)</h2> | ||
9454 | |||
9455 | <p>All of these situations are ones I've encountered in my real-life | ||
9456 | adventures as a CVS troubleshooter (plus a few items that are not really | ||
9457 | problems, just questions that I've heard asked so often that they may as | ||
9458 | well be answered here). The list is meant to be fairly comprehensive, | ||
9459 | and it may repeat material you've seen in earlier chapters. | ||
9460 | |||
9461 | <p>The situations are listed according to how frequently they seem to | ||
9462 | arise, with the most common ones first. | ||
9463 | |||
9464 | <ul> | ||
9465 | <li><a href="#CVS_says_it_is_waiting_for_a_lock__what_does_that_mean_">CVS says it is waiting for a lock; what does that mean?</a>: | ||
9466 | <li><a href="#CVS_claims_a_file_is_failing_Up-To-Date_check__what_do_I_do_">CVS claims a file is failing Up-To-Date check; what do I do?</a>: | ||
9467 | <li><a href="#The_pserver_access_method_is_not_working">The pserver access method is not working</a>: | ||
9468 | <li><a href="#The_pserver_access_method_is_STILL_not_working">The pserver access method is STILL not working</a>: | ||
9469 | <li><a href="#My_commits_seem_to_happen_in_pieces_instead_of_atomically">My commits seem to happen in pieces instead of atomically</a>: | ||
9470 | <li><a href="#CVS_keeps_changing_file_permissions__why_does_it_do_that_">CVS keeps changing file permissions; why does it do that?</a>: | ||
9471 | <li><a href="#CVS_on_Windows_complains_it_cannot_find_my_.cvspass_file__why_">CVS on Windows complains it cannot find my .cvspass file; why?</a>: | ||
9472 | <li><a href="#My_working_copy_is_on_several_different_branches__help_">My working copy is on several different branches; help?</a>: | ||
9473 | <li><a href="#When_I_do_export_-d_I_sometimes_miss_recent_commits">When I do export -d I sometimes miss recent commits</a>: | ||
9474 | <li><a href="#I_get_an_error_about_val-tags__what_should_I_do_">I get an error about val-tags; what should I do?</a>: | ||
9475 | <li><a href="#I_am_having_problems_with_sticky_tags__how_do_I_get_rid_of_them_">I am having problems with sticky tags; how do I get rid of them?</a>: | ||
9476 | <li><a href="#Checkouts_updates_exit_with_error_saying_cannot_expand_modules">Checkouts/updates exit with error saying cannot expand modules</a>: | ||
9477 | <li><a href="#I_cannot_seem_to_turn_off_watches">I cannot seem to turn off watches</a>: | ||
9478 | <li><a href="#My_binary_files_are_messed_up">My binary files are messed up</a>: | ||
9479 | <li><a href="#CVS_is_not_doing_line-end_conversion_correctly">CVS is not doing line-end conversion correctly</a>: | ||
9480 | <li><a href="#I_need_to_remove_a_subdirectory_in_my_project__how_do_I_do_it_">I need to remove a subdirectory in my project; how do I do it?</a>: | ||
9481 | <li><a href="#Can_I_copy_.cvspass_files_or_portions_of_them_">Can I copy .cvspass files or portions of them?</a>: | ||
9482 | <li><a href="#I_just_committed_some_files_with_the_wrong_log_message">I just committed some files with the wrong log message</a>: | ||
9483 | <li><a href="#I_need_to_move_files_around_without_losing_revision_history">I need to move files around without losing revision history</a>: | ||
9484 | <li><a href="#How_can_I_get_a_list_of_all_tags_in_a_project_">How can I get a list of all tags in a project?</a>: | ||
9485 | <li><a href="#How_can_I_get_a_list_of_all_projects_in_a_repository_">How can I get a list of all projects in a repository?</a>: | ||
9486 | <li><a href="#Some_commands_fail_remotely_but_not_locally__how_should_I_debug_">Some commands fail remotely but not locally; how should I debug?</a>: | ||
9487 | <li><a href="#I_do_not_see_my_problem_covered_in_this_chapter">I do not see my problem covered in this chapter</a>: | ||
9488 | <li><a href="#I_think_I_have_discovered_a_bug_in_CVS__what_do_I_do_">I think I have discovered a bug in CVS; what do I do?</a>: | ||
9489 | <li><a href="#I_have_implemented_a_new_feature_for_CVS__to_whom_do_I_send_it_">I have implemented a new feature for CVS; to whom do I send it?</a>: | ||
9490 | <li><a href="#How_can_I_keep_up_with_changes_to_CVS_">How can I keep up with changes to CVS?</a>: | ||
9491 | </ul> | ||
9492 | |||
9493 | <p><hr> | ||
9494 | Node:<a name="CVS_says_it_is_waiting_for_a_lock__what_does_that_mean_">CVS says it is waiting for a lock; what does that mean?</a>, | ||
9495 | Next:<a rel=next href="#CVS_claims_a_file_is_failing_Up-To-Date_check__what_do_I_do_">CVS claims a file is failing Up-To-Date check; what do I do?</a>, | ||
9496 | Up:<a rel=up href="#Some_Real_Life_Problems__With_Solutions_">Some Real Life Problems (With Solutions)</a> | ||
9497 | <br> | ||
9498 | |||
9499 | <h3>CVS says it is waiting for a lock; what does that mean?</h3> | ||
9500 | |||
9501 | <p>If you see a message like this | ||
9502 | |||
9503 | <pre>cvs update: [22:58:26] waiting for qsmith's lock in /usr/local/newrepos/myproj | ||
9504 | </pre> | ||
9505 | |||
9506 | <p>it means you're trying to access a subdirectory of the repository that | ||
9507 | is locked by some other CVS process at the moment. A process is being | ||
9508 | run in that directory so it may not be in a consistent state for other | ||
9509 | CVS processes to use. | ||
9510 | |||
9511 | <p>However, if the wait message persists for a long time, it probably means | ||
9512 | that a CVS process failed to clean up after itself, for whatever reason. | ||
9513 | It can happen when CVS dies suddenly and unexpectedly, say, due to a | ||
9514 | power failure on the repository machine. | ||
9515 | |||
9516 | <p>The solution is to remove the lock files by hand from the repository | ||
9517 | subdirectory in question. Go into that part of the repository and look | ||
9518 | for files named <code>#cvs.lock</code> or that begin with <code>#cvs.wfl</code> or | ||
9519 | <code>#cvs.rfl</code>. Compare the file's timestamps with the start times of | ||
9520 | any currently running CVS processes. If the files could not possibly | ||
9521 | have been created by any of those processes, it's safe to delete them. | ||
9522 | The waiting CVS processes eventually notice when the lock files are gone | ||
9523 | - this should take about 30 seconds - and allow the requested | ||
9524 | operation to proceed. | ||
9525 | |||
9526 | <p>See the node <cite>Locks</cite> in the Cederqvist manual for more details. | ||
9527 | |||
9528 | <p><hr> | ||
9529 | Node:<a name="CVS_claims_a_file_is_failing_Up-To-Date_check__what_do_I_do_">CVS claims a file is failing Up-To-Date check; what do I do?</a>, | ||
9530 | Next:<a rel=next href="#The_pserver_access_method_is_not_working">The pserver access method is not working</a>, | ||
9531 | Previous:<a rel=previous href="#CVS_says_it_is_waiting_for_a_lock__what_does_that_mean_">CVS says it is waiting for a lock; what does that mean?</a>, | ||
9532 | Up:<a rel=up href="#Some_Real_Life_Problems__With_Solutions_">Some Real Life Problems (With Solutions)</a> | ||
9533 | <br> | ||
9534 | |||
9535 | <h3>CVS claims a file is failing Up-To-Date check; what do I do?</h3> | ||
9536 | |||
9537 | <p>Don't panic - it just means that the file has changed in the repository | ||
9538 | since the last time you checked it out or updated it. | ||
9539 | |||
9540 | <p>Run <code>cvs update</code> on the file to merge in the changes from the | ||
9541 | repository. If the received changes conflict with your local changes, | ||
9542 | edit the file to resolve the conflict. Then try your commit again - it | ||
9543 | will succeed, barring the possibility that someone committed yet another | ||
9544 | revision while you were busy merging the last changes. | ||
9545 | |||
9546 | <p><hr> | ||
9547 | Node:<a name="The_pserver_access_method_is_not_working">The pserver access method is not working</a>, | ||
9548 | Next:<a rel=next href="#The_pserver_access_method_is_STILL_not_working">The pserver access method is STILL not working</a>, | ||
9549 | Previous:<a rel=previous href="#CVS_claims_a_file_is_failing_Up-To-Date_check__what_do_I_do_">CVS claims a file is failing Up-To-Date check; what do I do?</a>, | ||
9550 | Up:<a rel=up href="#Some_Real_Life_Problems__With_Solutions_">Some Real Life Problems (With Solutions)</a> | ||
9551 | <br> | ||
9552 | |||
9553 | <h3>The pserver access method is not working</h3> | ||
9554 | |||
9555 | <p>The most common, less obvious cause of this problem is that you forgot | ||
9556 | to list the repository using an <code>--allow-root</code> option in your inetd | ||
9557 | configuration file. | ||
9558 | |||
9559 | <p>Recall this example /etc/inetd.conf line from <a href="#Repository_Administration">Repository Administration</a>: | ||
9560 | |||
9561 | <pre>cvspserver stream tcp nowait root /usr/local/bin/cvs cvs \ | ||
9562 | --allow-root=/usr/local/newrepos pserver | ||
9563 | </pre> | ||
9564 | |||
9565 | <p>(In the actual file, this is all one long line, with no backslash.) | ||
9566 | |||
9567 | <p>The <code>--allow-root=/usr/local/newrepos</code> portion is a security | ||
9568 | measure, to make sure that people can't use CVS to get pserver access to | ||
9569 | repositories that are not supposed to be served remotely. Any | ||
9570 | repository intended to be accessible via pserver must be mentioned in an | ||
9571 | <code>--allow-root</code>. You can have as many different <code>--allow-root</code> | ||
9572 | options as you need for all of your system's repositories (or anyway, as | ||
9573 | many as you want until you bump up against your inetd's argument limit). | ||
9574 | |||
9575 | <p>See <a href="#Repository_Administration">Repository Administration</a> for more details on setting up the | ||
9576 | password-authenticating server. | ||
9577 | |||
9578 | <p><hr> | ||
9579 | Node:<a name="The_pserver_access_method_is_STILL_not_working">The pserver access method is STILL not working</a>, | ||
9580 | Next:<a rel=next href="#My_commits_seem_to_happen_in_pieces_instead_of_atomically">My commits seem to happen in pieces instead of atomically</a>, | ||
9581 | Previous:<a rel=previous href="#The_pserver_access_method_is_not_working">The pserver access method is not working</a>, | ||
9582 | Up:<a rel=up href="#Some_Real_Life_Problems__With_Solutions_">Some Real Life Problems (With Solutions)</a> | ||
9583 | <br> | ||
9584 | |||
9585 | <h3>The pserver access method is STILL not working</h3> | ||
9586 | |||
9587 | <p>Okay, if the problem is not a missing <code>--allow-root</code>, here are a | ||
9588 | few other possibilities: | ||
9589 | |||
9590 | <ul> | ||
9591 | |||
9592 | <li>The user has no entry in the CVSROOT/passwd file, and the CVSROOT/config | ||
9593 | file has SystemAuth=no so CVS will not fall back on the system password | ||
9594 | file (or SystemAuth=yes, but the system password file has no entry for | ||
9595 | this user either). | ||
9596 | |||
9597 | <li>The user has an entry in the CVSROOT/passwd file, but there is no user | ||
9598 | by that name on the system, and the CVSROOT/passwd entry does not map | ||
9599 | the user to any valid system username. | ||
9600 | |||
9601 | <li>The password is wrong (but CVS is usually pretty good about informing | ||
9602 | the user of this, so that's probably not the answer). | ||
9603 | |||
9604 | <li>Everything is set up correctly with the passwd files and in | ||
9605 | /etc/inetd.conf, but you forgot an entry like this in /etc/services: | ||
9606 | |||
9607 | <pre>cvspserver 2401/tcp | ||
9608 | </pre> | ||
9609 | |||
9610 | <p>so inetd is not even listening on that port to pass connections off to | ||
9611 | CVS. | ||
9612 | |||
9613 | </ul> | ||
9614 | |||
9615 | <p><hr> | ||
9616 | Node:<a name="My_commits_seem_to_happen_in_pieces_instead_of_atomically">My commits seem to happen in pieces instead of atomically</a>, | ||
9617 | Next:<a rel=next href="#CVS_keeps_changing_file_permissions__why_does_it_do_that_">CVS keeps changing file permissions; why does it do that?</a>, | ||
9618 | Previous:<a rel=previous href="#The_pserver_access_method_is_STILL_not_working">The pserver access method is STILL not working</a>, | ||
9619 | Up:<a rel=up href="#Some_Real_Life_Problems__With_Solutions_">Some Real Life Problems (With Solutions)</a> | ||
9620 | <br> | ||
9621 | |||
9622 | <h3>My commits seem to happen in pieces instead of atomically</h3> | ||
9623 | |||
9624 | <p>That's because CVS commits happen in pieces, not atomically. :-) | ||
9625 | |||
9626 | <p>More specifically, CVS operations happen directory by directory. When | ||
9627 | you do a commit (or an update, or anything else, for that matter) | ||
9628 | spanning multiple directories, CVS locks each corresponding repository | ||
9629 | directory in turn while it performs the operation for that directory. | ||
9630 | |||
9631 | <p>For small- to medium-sized projects, this is rarely a problem - CVS | ||
9632 | manages to do its thing in each directory so quickly that you never | ||
9633 | notice the nonatomicity. Unfortunately, in large projects, scenarios | ||
9634 | like the following can occur (imagine this taking place in a project | ||
9635 | with at least two deep, many-filed subdirectories, A and B): | ||
9636 | |||
9637 | <ol type=1 start=1> | ||
9638 | |||
9639 | </p><li>User qsmith starts a commit, involving files from both subdirectories. | ||
9640 | CVS commits the files in B first (perhaps because qsmith specified the | ||
9641 | directories on the command line in that order). | ||
9642 | |||
9643 | <li>User jrandom starts a cvs update. The update, for whatever reason, | ||
9644 | starts with working copy directory A (CVS makes no guarantees about the | ||
9645 | order in which it processes directories or files, if left to its own | ||
9646 | devices). Note that there is no locking contention, because qsmith is | ||
9647 | not active in A yet. | ||
9648 | |||
9649 | <li>Then, qsmith's commit finishes B, moves on to A, and finishes A. | ||
9650 | |||
9651 | <li>Finally, jrandom's update moves on to B and finishes it. | ||
9652 | |||
9653 | </ol> | ||
9654 | |||
9655 | <p>Clearly, when this is all over, jrandom's working copy reflects qsmith's | ||
9656 | changes to B but not A. Even though qsmith intended the changes to be | ||
9657 | committed as a single unit, it didn't happen that way. Now jrandom's | ||
9658 | working copy is in a state that qsmith never anticipated. | ||
9659 | |||
9660 | <p>The solution, of course, is for jrandom to do another cvs update to | ||
9661 | fetch the uncaught changes from qsmith's commit. However, that assumes | ||
9662 | that jrandom has some way of finding out in the first place that he only | ||
9663 | got part of qsmith's changes. | ||
9664 | |||
9665 | <p>There's no easy answer to this quandary. You simply have to hope that | ||
9666 | the inconsistent state of the working copy will somehow become apparent | ||
9667 | (maybe the software won't build, or jrandom and qsmith will have a | ||
9668 | conversation that's confusing until they realize what must have | ||
9669 | happened). | ||
9670 | |||
9671 | <p>CVS's failure to provide <em>atomic</em> transaction guarantees is widely | ||
9672 | considered a bug. The only reason that locks are not made at the top | ||
9673 | level of the repository is that this would result in intolerably | ||
9674 | frequent lock contentions for large projects with many developers. | ||
9675 | Therefore, CVS has chosen the lesser of two evils, reducing the | ||
9676 | contention frequency but allowing the possibility of interleaved reads | ||
9677 | and writes. Someday, someone may modify CVS (say, speeding up | ||
9678 | repository operations) so that it doesn't have to choose between two | ||
9679 | evils; until then, we're stuck with nonatomic actions. | ||
9680 | |||
9681 | <p>For more information, see the node <cite>Concurrency</cite> in the Cederqvist | ||
9682 | manual. | ||
9683 | |||
9684 | <p><hr> | ||
9685 | Node:<a name="CVS_keeps_changing_file_permissions__why_does_it_do_that_">CVS keeps changing file permissions; why does it do that?</a>, | ||
9686 | Next:<a rel=next href="#CVS_on_Windows_complains_it_cannot_find_my_.cvspass_file__why_">CVS on Windows complains it cannot find my .cvspass file; why?</a>, | ||
9687 | Previous:<a rel=previous href="#My_commits_seem_to_happen_in_pieces_instead_of_atomically">My commits seem to happen in pieces instead of atomically</a>, | ||
9688 | Up:<a rel=up href="#Some_Real_Life_Problems__With_Solutions_">Some Real Life Problems (With Solutions)</a> | ||
9689 | <br> | ||
9690 | |||
9691 | <h3>CVS keeps changing file permissions; why does it do that?</h3> | ||
9692 | |||
9693 | <p>In general, CVS doesn't do a very good job of preserving permissions on | ||
9694 | files. When you import a project and then check it out, there is no | ||
9695 | guarantee that the file permissions in the new working copy will be the | ||
9696 | same as when the project was imported. More likely, the working copy | ||
9697 | files will be created with the same standard permissions that you | ||
9698 | normally get on newly created files. | ||
9699 | |||
9700 | <p>However, there is at least one exception. If you want to store | ||
9701 | executable shell scripts in the project, you can keep them executable in | ||
9702 | all working copies by making the corresponding repository file | ||
9703 | executable: | ||
9704 | |||
9705 | <pre>floss$ ls -l /usr/local/newrepos/someproj | ||
9706 | total 6 | ||
9707 | -r--r--r-- 1 jrandom users 630 Aug 17 01:10 README.txt,v | ||
9708 | -r-xr-xr-x 1 jrandom users 1041 Aug 17 01:10 scrub.pl,v* | ||
9709 | -r--r--r-- 1 jrandom users 750 Aug 17 01:10 hello.c,v | ||
9710 | </pre> | ||
9711 | |||
9712 | <p>Notice that although the file is executable, it is still read-only, as | ||
9713 | all repository files should be (remember that CVS works by making a | ||
9714 | temporary copy of the RCS file, doing everything in the copy, and then | ||
9715 | replacing the original with the copy when ready). | ||
9716 | |||
9717 | <p>When you import or add an executable file, CVS preserves the executable | ||
9718 | bits, so if the permissions were correct from the start, you have | ||
9719 | nothing to worry about. However, if you accidentally add the file | ||
9720 | before making it executable, you must go into the repository and | ||
9721 | manually set the RCS file to be executable. | ||
9722 | |||
9723 | <p>The repository permissions always dominate. If the file is | ||
9724 | nonexecutable in the repository, but executable in the working copy, the | ||
9725 | working copy file will also be nonexecutable after you do an update. | ||
9726 | Having your files' permissions silently change can be extremely | ||
9727 | frustrating. If this happens, first check the repository and see if you | ||
9728 | can solve it by setting the appropriate permissions on the corresponding | ||
9729 | RCS files. | ||
9730 | |||
9731 | <p>A feature called <code>PreservePermissions</code> has recently been added to | ||
9732 | CVS that may alleviate some of these problems. However, using this | ||
9733 | feature can cause other unexpected results (which is why I'm not | ||
9734 | recommending it unconditionally here). Make sure you read the nodes | ||
9735 | <cite>config</cite> and <cite>Special Files</cite> in the Cederqvist before putting | ||
9736 | <code>PreservePermissions=yes</code> in CVSROOT/config. | ||
9737 | |||
9738 | <p><hr> | ||
9739 | Node:<a name="CVS_on_Windows_complains_it_cannot_find_my_.cvspass_file__why_">CVS on Windows complains it cannot find my .cvspass file; why?</a>, | ||
9740 | Next:<a rel=next href="#My_working_copy_is_on_several_different_branches__help_">My working copy is on several different branches; help?</a>, | ||
9741 | Previous:<a rel=previous href="#CVS_keeps_changing_file_permissions__why_does_it_do_that_">CVS keeps changing file permissions; why does it do that?</a>, | ||
9742 | Up:<a rel=up href="#Some_Real_Life_Problems__With_Solutions_">Some Real Life Problems (With Solutions)</a> | ||
9743 | <br> | ||
9744 | |||
9745 | <h3>CVS on Windows complains it cannot find my .cvspass file; why?</h3> | ||
9746 | |||
9747 | <p>For pserver connections, CVS on the client side tries to find the | ||
9748 | .cvspass file in your home directory. Windows machines don't have a | ||
9749 | natural "home" directory, so CVS consults the environment variable | ||
9750 | <code>%HOME%</code>. However, you have to be very careful about how you set | ||
9751 | HOME. This will work: | ||
9752 | |||
9753 | <pre>set HOME=C: | ||
9754 | </pre> | ||
9755 | |||
9756 | <p>This will not: | ||
9757 | |||
9758 | <pre>set HOME=C:\ | ||
9759 | </pre> | ||
9760 | |||
9761 | <p>That extra backslash is enough to confuse CVS, and it will be unable to | ||
9762 | open <code>C:\\.cvspass</code>. | ||
9763 | |||
9764 | <p>So, the quick and permanent solution is to put | ||
9765 | |||
9766 | <pre>set HOME=C: | ||
9767 | </pre> | ||
9768 | |||
9769 | <p>into your autoexec.bat and reboot. CVS pserver should work fine after | ||
9770 | that. | ||
9771 | |||
9772 | <p><hr> | ||
9773 | Node:<a name="My_working_copy_is_on_several_different_branches__help_">My working copy is on several different branches; help?</a>, | ||
9774 | Next:<a rel=next href="#When_I_do_export_-d_I_sometimes_miss_recent_commits">When I do export -d I sometimes miss recent commits</a>, | ||
9775 | Previous:<a rel=previous href="#CVS_on_Windows_complains_it_cannot_find_my_.cvspass_file__why_">CVS on Windows complains it cannot find my .cvspass file; why?</a>, | ||
9776 | Up:<a rel=up href="#Some_Real_Life_Problems__With_Solutions_">Some Real Life Problems (With Solutions)</a> | ||
9777 | <br> | ||
9778 | |||
9779 | <h3>My working copy is on several different branches; help?</h3> | ||
9780 | |||
9781 | <p>You mean different subdirectories of your working copy somehow got on | ||
9782 | different branches? You probably ran updates with the -r flag, but from | ||
9783 | places other than the top level of the working copy. | ||
9784 | |||
9785 | <p>No big deal. If you want to return to the trunk, just run this | ||
9786 | |||
9787 | <pre>cvs update -r HEAD | ||
9788 | </pre> | ||
9789 | |||
9790 | <p>or this | ||
9791 | |||
9792 | <pre>cvs update -A | ||
9793 | </pre> | ||
9794 | |||
9795 | <p>from the top directory. Or, if you want to put the whole working copy | ||
9796 | on one of the branches, do this: | ||
9797 | |||
9798 | <pre>cvs update -r Branch_Name | ||
9799 | </pre> | ||
9800 | |||
9801 | <p>There's nothing necessarily wrong with having one or two subdirectories | ||
9802 | of your working copy on a different branch than the rest of it, if you | ||
9803 | need to do some temporary work on that branch just in those locations. | ||
9804 | However, it's usually a good idea to switch them back when you're done | ||
9805 | - life is much less confusing when your whole working copy is on the | ||
9806 | same line of development. | ||
9807 | |||
9808 | <p><hr> | ||
9809 | Node:<a name="When_I_do_export_-d_I_sometimes_miss_recent_commits">When I do export -d I sometimes miss recent commits</a>, | ||
9810 | Next:<a rel=next href="#I_get_an_error_about_val-tags__what_should_I_do_">I get an error about val-tags; what should I do?</a>, | ||
9811 | Previous:<a rel=previous href="#My_working_copy_is_on_several_different_branches__help_">My working copy is on several different branches; help?</a>, | ||
9812 | Up:<a rel=up href="#Some_Real_Life_Problems__With_Solutions_">Some Real Life Problems (With Solutions)</a> | ||
9813 | <br> | ||
9814 | |||
9815 | <h3>When I do export -d I sometimes miss recent commits</h3> | ||
9816 | |||
9817 | <p>This is due to a clock difference between the repository and local | ||
9818 | machines. You can solve it by resetting one or both of the clocks, or | ||
9819 | specifying a different date as the argument to -D. It's perfectly | ||
9820 | acceptable to specify a date in the future (such as -D tomorrow), if | ||
9821 | that's what it takes to compensate for the time difference. | ||
9822 | |||
9823 | <p><hr> | ||
9824 | Node:<a name="I_get_an_error_about_val-tags__what_should_I_do_">I get an error about val-tags; what should I do?</a>, | ||
9825 | Next:<a rel=next href="#I_am_having_problems_with_sticky_tags__how_do_I_get_rid_of_them_">I am having problems with sticky tags; how do I get rid of them?</a>, | ||
9826 | Previous:<a rel=previous href="#When_I_do_export_-d_I_sometimes_miss_recent_commits">When I do export -d I sometimes miss recent commits</a>, | ||
9827 | Up:<a rel=up href="#Some_Real_Life_Problems__With_Solutions_">Some Real Life Problems (With Solutions)</a> | ||
9828 | <br> | ||
9829 | |||
9830 | <h3>I get an error about val-tags; what should I do?</h3> | ||
9831 | |||
9832 | <p>If you see an error like this: | ||
9833 | |||
9834 | <pre>cvs [export aborted]: cannot write /usr/local/myproj/CVSROOT/val-tags: \ | ||
9835 | Operation not permitted | ||
9836 | </pre> | ||
9837 | |||
9838 | <p>it means the user CVS is running as does not have permission to write to | ||
9839 | the CVSROOT/val-tags file. This file stores valid tag names, to give | ||
9840 | CVS a fast way to determine what tags are valid. Unfortunately, CVS | ||
9841 | sometimes modifies this file even for operations that are read-only with | ||
9842 | respect to the repository, such as checking out a project. | ||
9843 | |||
9844 | <p>This is a bug in CVS and may be fixed by the time you read this. Until | ||
9845 | then, the solution is either to make val-tags world-writeable or, | ||
9846 | failing that, to remove it or change its ownership to the user running | ||
9847 | the CVS operation. (You'd think just changing the permissions would be | ||
9848 | enough, but on several occasions I've had to change the ownership, too.) | ||
9849 | |||
9850 | <p><hr> | ||
9851 | Node:<a name="I_am_having_problems_with_sticky_tags__how_do_I_get_rid_of_them_">I am having problems with sticky tags; how do I get rid of them?</a>, | ||
9852 | Next:<a rel=next href="#Checkouts_updates_exit_with_error_saying_cannot_expand_modules">Checkouts/updates exit with error saying cannot expand modules</a>, | ||
9853 | Previous:<a rel=previous href="#I_get_an_error_about_val-tags__what_should_I_do_">I get an error about val-tags; what should I do?</a>, | ||
9854 | Up:<a rel=up href="#Some_Real_Life_Problems__With_Solutions_">Some Real Life Problems (With Solutions)</a> | ||
9855 | <br> | ||
9856 | |||
9857 | <h3>I am having problems with sticky tags; how do I get rid of them?</h3> | ||
9858 | |||
9859 | <p>Various CVS operations cause the working copy to have a <dfn>sticky | ||
9860 | tag</dfn>, meaning a single tag that corresponds to each revision for each | ||
9861 | file (in the case of a branch, the sticky tag is applied to any new | ||
9862 | files added in the working copy). You get a sticky tagged working area | ||
9863 | whenever you check out or update by tag or date, for example: | ||
9864 | |||
9865 | <pre>floss$ cvs update -r Tag_Name | ||
9866 | </pre> | ||
9867 | |||
9868 | <p>or | ||
9869 | |||
9870 | <pre>floss$ cvs checkout -D '1999-08-16' | ||
9871 | </pre> | ||
9872 | |||
9873 | <p>If a date or a nonbranch tag name is used, the working copy will be a | ||
9874 | frozen snapshot of that moment in the project's history - so naturally | ||
9875 | you will not be able to commit any changes from it. | ||
9876 | |||
9877 | <p>To remove a sticky tag, run update with the -A flag | ||
9878 | |||
9879 | <pre>floss$ cvs update -A | ||
9880 | </pre> | ||
9881 | |||
9882 | <p>which clears all the sticky tags and updates each file to its most | ||
9883 | recent trunk revision. | ||
9884 | |||
9885 | <p><hr> | ||
9886 | Node:<a name="Checkouts_updates_exit_with_error_saying_cannot_expand_modules">Checkouts/updates exit with error saying cannot expand modules</a>, | ||
9887 | Next:<a rel=next href="#I_cannot_seem_to_turn_off_watches">I cannot seem to turn off watches</a>, | ||
9888 | Previous:<a rel=previous href="#I_am_having_problems_with_sticky_tags__how_do_I_get_rid_of_them_">I am having problems with sticky tags; how do I get rid of them?</a>, | ||
9889 | Up:<a rel=up href="#Some_Real_Life_Problems__With_Solutions_">Some Real Life Problems (With Solutions)</a> | ||
9890 | <br> | ||
9891 | |||
9892 | <h3>Checkouts/updates exit with error saying cannot expand modules</h3> | ||
9893 | |||
9894 | <p>This is just a case of a bad error message in CVS; probably someone will | ||
9895 | get around to fixing it sooner or later, but meanwhile it may bite you. | ||
9896 | The error message looks something like this: | ||
9897 | |||
9898 | <pre>floss$ cvs co -d bwf-misc user-space/bwf/writings/misc | ||
9899 | cvs server: cannot find module `user-space/bwf/writings/misc' - ignored | ||
9900 | cvs [checkout aborted]: cannot expand modules | ||
9901 | </pre> | ||
9902 | |||
9903 | <p>CVS appears to be saying that there's something wrong with the | ||
9904 | CVSROOT/modules file. However, what's really going on is a permission | ||
9905 | problem in the repository. The directory I'm trying to check out isn't | ||
9906 | readable, or one of its parents isn't readable. In this case, it was a | ||
9907 | parent: | ||
9908 | |||
9909 | <pre>floss$ ls -ld /usr/local/cvs/user-space/bwf | ||
9910 | |||
9911 | drwx------ 19 bwf users 1024 Aug 17 01:24 bwf/ | ||
9912 | </pre> | ||
9913 | |||
9914 | <p>Don't let that egregiously wrong error message fool you - this is a | ||
9915 | repository permission problem. | ||
9916 | |||
9917 | <p><hr> | ||
9918 | Node:<a name="I_cannot_seem_to_turn_off_watches">I cannot seem to turn off watches</a>, | ||
9919 | Next:<a rel=next href="#My_binary_files_are_messed_up">My binary files are messed up</a>, | ||
9920 | Previous:<a rel=previous href="#Checkouts_updates_exit_with_error_saying_cannot_expand_modules">Checkouts/updates exit with error saying cannot expand modules</a>, | ||
9921 | Up:<a rel=up href="#Some_Real_Life_Problems__With_Solutions_">Some Real Life Problems (With Solutions)</a> | ||
9922 | <br> | ||
9923 | |||
9924 | <h3>I cannot seem to turn off watches</h3> | ||
9925 | |||
9926 | <p>You probably did | ||
9927 | |||
9928 | <pre>floss$ cvs watch remove | ||
9929 | </pre> | ||
9930 | |||
9931 | <p>on all the files, but forgot to also do: | ||
9932 | |||
9933 | <pre>floss$ cvs watch off | ||
9934 | </pre> | ||
9935 | |||
9936 | <p>A hint for diagnosing watch problems: Sometimes it can be immensely | ||
9937 | clarifying to just go into the repository and examine the CVS/fileattr | ||
9938 | files directly. See <a href="#Repository_Administration">Repository Administration</a> for more | ||
9939 | information about them. | ||
9940 | |||
9941 | <p><hr> | ||
9942 | Node:<a name="My_binary_files_are_messed_up">My binary files are messed up</a>, | ||
9943 | Next:<a rel=next href="#CVS_is_not_doing_line-end_conversion_correctly">CVS is not doing line-end conversion correctly</a>, | ||
9944 | Previous:<a rel=previous href="#I_cannot_seem_to_turn_off_watches">I cannot seem to turn off watches</a>, | ||
9945 | Up:<a rel=up href="#Some_Real_Life_Problems__With_Solutions_">Some Real Life Problems (With Solutions)</a> | ||
9946 | <br> | ||
9947 | |||
9948 | <h3>My binary files are messed up</h3> | ||
9949 | |||
9950 | <p>Did you remember to use -kb when you added them? If not, CVS may have | ||
9951 | performed line-end conversion or RCS keyword substitution on them. The | ||
9952 | easiest solution is usually to mark them as binary | ||
9953 | |||
9954 | <pre>floss$ cvs admin -kb foo.gif | ||
9955 | </pre> | ||
9956 | |||
9957 | <p>and then commit a fixed version of the file. CVS will not corrupt the | ||
9958 | new commit or any of the commits thereafter, because it now knows the | ||
9959 | file is binary. | ||
9960 | |||
9961 | <p><hr> | ||
9962 | Node:<a name="CVS_is_not_doing_line-end_conversion_correctly">CVS is not doing line-end conversion correctly</a>, | ||
9963 | Next:<a rel=next href="#I_need_to_remove_a_subdirectory_in_my_project__how_do_I_do_it_">I need to remove a subdirectory in my project; how do I do it?</a>, | ||
9964 | Previous:<a rel=previous href="#My_binary_files_are_messed_up">My binary files are messed up</a>, | ||
9965 | Up:<a rel=up href="#Some_Real_Life_Problems__With_Solutions_">Some Real Life Problems (With Solutions)</a> | ||
9966 | <br> | ||
9967 | |||
9968 | <h3>CVS is not doing line-end conversion correctly</h3> | ||
9969 | |||
9970 | <p>If you're running the CVS client on a non-Unix platform and are not | ||
9971 | getting the line-end conventions that you want in some working copy | ||
9972 | files, it's usually because they were accidentally added with -kb when | ||
9973 | they shouldn't have been. This can be fixed in the repository with, | ||
9974 | believe it or not, the command: | ||
9975 | |||
9976 | <pre>floss$ cvs admin -kkv FILE | ||
9977 | </pre> | ||
9978 | |||
9979 | <p>The -kkv means to do normal keyword substitution and implies normal | ||
9980 | line-end conversions as well. (Internally, CVS is a bit confused about | ||
9981 | the difference between keyword substitution and line-end conversion. | ||
9982 | This confusion is reflected in the way the -k options can control both | ||
9983 | parameters.) | ||
9984 | |||
9985 | <p>Unfortunately, that admin command only fixes the file in the repository | ||
9986 | - your working copy still thinks the file is binary. You can hand edit | ||
9987 | the CVS/Entries line for that file, removing the -kb, but that won't | ||
9988 | solve the problem for any other working copies out there. | ||
9989 | |||
9990 | <p><hr> | ||
9991 | Node:<a name="I_need_to_remove_a_subdirectory_in_my_project__how_do_I_do_it_">I need to remove a subdirectory in my project; how do I do it?</a>, | ||
9992 | Next:<a rel=next href="#Can_I_copy_.cvspass_files_or_portions_of_them_">Can I copy .cvspass files or portions of them?</a>, | ||
9993 | Previous:<a rel=previous href="#CVS_is_not_doing_line-end_conversion_correctly">CVS is not doing line-end conversion correctly</a>, | ||
9994 | Up:<a rel=up href="#Some_Real_Life_Problems__With_Solutions_">Some Real Life Problems (With Solutions)</a> | ||
9995 | <br> | ||
9996 | |||
9997 | <h3>I need to remove a subdirectory in my project; how do I do it?</h3> | ||
9998 | |||
9999 | <p>Well, you can't exactly remove the subdirectory, but you can remove all | ||
10000 | of the files in it (first remove them, then cvs remove them, and then | ||
10001 | commit). Once the directory is empty, people can have it automatically | ||
10002 | pruned out of their working copies by passing the -P flag to update. | ||
10003 | |||
10004 | <p><hr> | ||
10005 | Node:<a name="Can_I_copy_.cvspass_files_or_portions_of_them_">Can I copy .cvspass files or portions of them?</a>, | ||
10006 | Next:<a rel=next href="#I_just_committed_some_files_with_the_wrong_log_message">I just committed some files with the wrong log message</a>, | ||
10007 | Previous:<a rel=previous href="#I_need_to_remove_a_subdirectory_in_my_project__how_do_I_do_it_">I need to remove a subdirectory in my project; how do I do it?</a>, | ||
10008 | Up:<a rel=up href="#Some_Real_Life_Problems__With_Solutions_">Some Real Life Problems (With Solutions)</a> | ||
10009 | <br> | ||
10010 | |||
10011 | <h3>Can I copy .cvspass files or portions of them?</h3> | ||
10012 | |||
10013 | <p>Yes, you can. You can copy <code>.cvspass</code> files from machine to | ||
10014 | machine, and you can even copy individual lines from one .cvspass file | ||
10015 | to another. For high-latency servers, this may be faster than running | ||
10016 | cvs login from each working copy machine. | ||
10017 | |||
10018 | <p>Remember that if you transport a .cvspass file between two machines with | ||
10019 | different line-ending conventions, it probably won't work (of course, | ||
10020 | you can probably do the line-end conversion manually without too much | ||
10021 | trouble). | ||
10022 | |||
10023 | <p><hr> | ||
10024 | Node:<a name="I_just_committed_some_files_with_the_wrong_log_message">I just committed some files with the wrong log message</a>, | ||
10025 | Next:<a rel=next href="#I_need_to_move_files_around_without_losing_revision_history">I need to move files around without losing revision history</a>, | ||
10026 | Previous:<a rel=previous href="#Can_I_copy_.cvspass_files_or_portions_of_them_">Can I copy .cvspass files or portions of them?</a>, | ||
10027 | Up:<a rel=up href="#Some_Real_Life_Problems__With_Solutions_">Some Real Life Problems (With Solutions)</a> | ||
10028 | <br> | ||
10029 | |||
10030 | <h3>I just committed some files with the wrong log message</h3> | ||
10031 | |||
10032 | <p>You don't need to hand-edit anything in the repository to solve this. | ||
10033 | Just run admin with the -m flag. Remember to have no space between -m | ||
10034 | and its argument, and to quote the replacement log message as you would | ||
10035 | a normal one: | ||
10036 | |||
10037 | <pre>floss$ cvs admin -m1.17:'I take back what I said about the customer.' hello.c | ||
10038 | </pre> | ||
10039 | |||
10040 | <p><hr> | ||
10041 | Node:<a name="I_need_to_move_files_around_without_losing_revision_history">I need to move files around without losing revision history</a>, | ||
10042 | Next:<a rel=next href="#How_can_I_get_a_list_of_all_tags_in_a_project_">How can I get a list of all tags in a project?</a>, | ||
10043 | Previous:<a rel=previous href="#I_just_committed_some_files_with_the_wrong_log_message">I just committed some files with the wrong log message</a>, | ||
10044 | Up:<a rel=up href="#Some_Real_Life_Problems__With_Solutions_">Some Real Life Problems (With Solutions)</a> | ||
10045 | <br> | ||
10046 | |||
10047 | <h3>I need to move files around without losing revision history</h3> | ||
10048 | |||
10049 | <p>In the repository, copy (don't move) the RCS files to the desired new | ||
10050 | location in the project. They must remain in their old locations as | ||
10051 | well. Then, in a working copy, do: | ||
10052 | |||
10053 | <pre>floss$ rm oldfile1 oldfile2 ... | ||
10054 | floss$ cvs remove oldfile1 oldfile2 ... | ||
10055 | floss$ cvs commit -m removed from here oldfile1 oldfile2 ... | ||
10056 | </pre> | ||
10057 | |||
10058 | <p>When people do updates after that, CVS correctly removes the old files | ||
10059 | and brings the new files into the working copies just as though they had | ||
10060 | been added to the repository in the usual way (except that they'll be at | ||
10061 | unusually high revision numbers for supposedly new files). | ||
10062 | |||
10063 | <p><hr> | ||
10064 | Node:<a name="How_can_I_get_a_list_of_all_tags_in_a_project_">How can I get a list of all tags in a project?</a>, | ||
10065 | Next:<a rel=next href="#How_can_I_get_a_list_of_all_projects_in_a_repository_">How can I get a list of all projects in a repository?</a>, | ||
10066 | Previous:<a rel=previous href="#I_need_to_move_files_around_without_losing_revision_history">I need to move files around without losing revision history</a>, | ||
10067 | Up:<a rel=up href="#Some_Real_Life_Problems__With_Solutions_">Some Real Life Problems (With Solutions)</a> | ||
10068 | <br> | ||
10069 | |||
10070 | <h3>How can I get a list of all tags in a project?</h3> | ||
10071 | |||
10072 | <p>Currently, there is no convenient way to do this in CVS. The lack is | ||
10073 | sorely felt by all users, and I believe work is under way to make this | ||
10074 | feature available. By the time you read this, a <code>cvs tags</code> | ||
10075 | command or something similar may be available. | ||
10076 | |||
10077 | <p>Until then, there are workarounds. You can run cvs log -h and read the | ||
10078 | sections of the output following the header <code>symbolic names:</code>. Or, | ||
10079 | if you happen to be on the repository machine, you can just look at the | ||
10080 | beginnings of some of the RCS files directly in the repository. All of | ||
10081 | the tags (branches and nonbranches) are listed in the <code>symbols</code> | ||
10082 | field: | ||
10083 | |||
10084 | <pre>floss$ head /usr/local/newrepos/hello.c,v | ||
10085 | head2.0; | ||
10086 | access; | ||
10087 | symbols | ||
10088 | Release_1_0:1.22 | ||
10089 | Exotic_Greetings-2:1.21 | ||
10090 | merged-Exotic_Greetings-1:1.21 | ||
10091 | Exotic_Greetings-1:1.21 | ||
10092 | merged-Exotic_Greetings:1.21 | ||
10093 | Exotic_Greetings-branch:1.21.0.2 | ||
10094 | Root-of-Exotic_Greetings:1.21 | ||
10095 | start:1.1.1.1 | ||
10096 | jrandom:1.1.1; | ||
10097 | locks; strict; | ||
10098 | comment@ * @; | ||
10099 | </pre> | ||
10100 | |||
10101 | <p><hr> | ||
10102 | Node:<a name="How_can_I_get_a_list_of_all_projects_in_a_repository_">How can I get a list of all projects in a repository?</a>, | ||
10103 | Next:<a rel=next href="#Some_commands_fail_remotely_but_not_locally__how_should_I_debug_">Some commands fail remotely but not locally; how should I debug?</a>, | ||
10104 | Previous:<a rel=previous href="#How_can_I_get_a_list_of_all_tags_in_a_project_">How can I get a list of all tags in a project?</a>, | ||
10105 | Up:<a rel=up href="#Some_Real_Life_Problems__With_Solutions_">Some Real Life Problems (With Solutions)</a> | ||
10106 | <br> | ||
10107 | |||
10108 | <h3>How can I get a list of all projects in a repository?</h3> | ||
10109 | |||
10110 | <p>As with getting a list of tags, this is not implemented in the most | ||
10111 | current version of CVS, but it's highly likely that it will be | ||
10112 | implemented soon. I imagine the command will be called cvs list with a | ||
10113 | short form of cvs ls, and it probably will both parse the modules file | ||
10114 | and list the repository subdirectories. | ||
10115 | |||
10116 | <p>In the meantime, examining the CVSROOT/modules file (either directly or | ||
10117 | by running cvs checkout -c) is probably your best bet. However, if no | ||
10118 | one has explicitly made a module for a particular project, it won't show | ||
10119 | up there. | ||
10120 | |||
10121 | <p><hr> | ||
10122 | Node:<a name="Some_commands_fail_remotely_but_not_locally__how_should_I_debug_">Some commands fail remotely but not locally; how should I debug?</a>, | ||
10123 | Next:<a rel=next href="#I_do_not_see_my_problem_covered_in_this_chapter">I do not see my problem covered in this chapter</a>, | ||
10124 | Previous:<a rel=previous href="#How_can_I_get_a_list_of_all_projects_in_a_repository_">How can I get a list of all projects in a repository?</a>, | ||
10125 | Up:<a rel=up href="#Some_Real_Life_Problems__With_Solutions_">Some Real Life Problems (With Solutions)</a> | ||
10126 | <br> | ||
10127 | |||
10128 | <h3>Some commands fail remotely but not locally; how should I debug?</h3> | ||
10129 | |||
10130 | <p>Sometimes there's a problem in the communication between the client and | ||
10131 | the server. If so, it's a bug in CVS, but how would you go about | ||
10132 | tracking down such a thing? | ||
10133 | |||
10134 | <p>CVS gives you a way to watch the protocol between the client and server. | ||
10135 | Before you run the command on the local (working copy) machine, set the | ||
10136 | environment variable <code>CVS_CLIENT_LOG</code>. Here's how in Bourne shell | ||
10137 | syntax: | ||
10138 | |||
10139 | <pre>floss$ CVS_CLIENT_LOG=clog; export CVS_CLIENT_LOG | ||
10140 | </pre> | ||
10141 | |||
10142 | <p>Once that variable is set, CVS will record all communications between | ||
10143 | client and server in two files whose names are based on the variable's | ||
10144 | value: | ||
10145 | |||
10146 | <pre>floss$ ls | ||
10147 | CVS/ README.txt a-subdir/ b-subdir/ foo.gif hello.c | ||
10148 | floss$ cvs update | ||
10149 | ? clog.in | ||
10150 | ? clog.out | ||
10151 | cvs server: Updating . | ||
10152 | cvs server: Updating a-subdir | ||
10153 | cvs server: Updating a-subdir/subsubdir | ||
10154 | cvs server: Updating b-subdir | ||
10155 | floss$ ls | ||
10156 | CVS/ a-subdir/ clog.in foo.gif | ||
10157 | README.txt b-subdir/ clog.out hello.c | ||
10158 | floss$ | ||
10159 | </pre> | ||
10160 | |||
10161 | <p>The <code>clog.in</code> file contains everything that the client sent into | ||
10162 | the server, and <code>clog.out</code> contains everything the server sent back | ||
10163 | out to the client. Here are the contents of clog.out, to give you a | ||
10164 | sense of what the protocol looks like: | ||
10165 | |||
10166 | <pre>Valid-requests Root Valid-responses valid-requests Repository \ | ||
10167 | Directory Max-dotdot Static-directory Sticky Checkin-prog Update-prog \ | ||
10168 | Entry Kopt Checkin-time Modified Is-modified UseUnchanged Unchanged \ | ||
10169 | Notify Questionable Case Argument Argumentx Global_option Gzip-stream \ | ||
10170 | wrapper-sendme-rcsOptions Set expand-modules ci co update diff log add \ | ||
10171 | remove update-patches gzip-file-contents status rdiff tag rtag import \ | ||
10172 | admin export history release watch-on watch-off watch-add watch-remove \ | ||
10173 | watchers editors init annotate noop | ||
10174 | ok | ||
10175 | M ? clog.in | ||
10176 | M ? clog.out | ||
10177 | E cvs server: Updating . | ||
10178 | E cvs server: Updating a-subdir | ||
10179 | E cvs server: Updating a-subdir/subsubdir | ||
10180 | E cvs server: Updating b-subdir | ||
10181 | ok | ||
10182 | </pre> | ||
10183 | |||
10184 | <p>The clog.in file is even more complex, because it has to send revision | ||
10185 | numbers and other per-file information to the server. | ||
10186 | |||
10187 | <p>There isn't space here to document the client/server protocol, but you | ||
10188 | can read the <code>cvsclient</code> Info pages that were distributed with CVS | ||
10189 | for a complete description. You may be able to figure out a good deal | ||
10190 | of it just from reading the raw protocol itself. Although you probably | ||
10191 | won't find yourself using client logging until you've eliminated all of | ||
10192 | the other possible causes of a problem, it is an invaluable tool for | ||
10193 | finding out what's really going on between the client and server. | ||
10194 | |||
10195 | <p><hr> | ||
10196 | Node:<a name="I_do_not_see_my_problem_covered_in_this_chapter">I do not see my problem covered in this chapter</a>, | ||
10197 | Next:<a rel=next href="#I_think_I_have_discovered_a_bug_in_CVS__what_do_I_do_">I think I have discovered a bug in CVS; what do I do?</a>, | ||
10198 | Previous:<a rel=previous href="#Some_commands_fail_remotely_but_not_locally__how_should_I_debug_">Some commands fail remotely but not locally; how should I debug?</a>, | ||
10199 | Up:<a rel=up href="#Some_Real_Life_Problems__With_Solutions_">Some Real Life Problems (With Solutions)</a> | ||
10200 | <br> | ||
10201 | |||
10202 | <h3>I do not see my problem covered in this chapter</h3> | ||
10203 | |||
10204 | <p>Email an accurate and complete description of your problem to | ||
10205 | <a href="mailto:info-cvs@gnu.org">info-cvs@gnu.org</a>, the CVS discussion list. Its members are | ||
10206 | located in many different time zones, and I've usually gotten a response | ||
10207 | within an hour or two of sending a question. Please join the list by | ||
10208 | sending email to <a href="mailto:info-cvs-request@gnu.org">info-cvs-request@gnu.org</a>, so you can help | ||
10209 | answer questions, too. | ||
10210 | |||
10211 | <p><hr> | ||
10212 | Node:<a name="I_think_I_have_discovered_a_bug_in_CVS__what_do_I_do_">I think I have discovered a bug in CVS; what do I do?</a>, | ||
10213 | Next:<a rel=next href="#I_have_implemented_a_new_feature_for_CVS__to_whom_do_I_send_it_">I have implemented a new feature for CVS; to whom do I send it?</a>, | ||
10214 | Previous:<a rel=previous href="#I_do_not_see_my_problem_covered_in_this_chapter">I do not see my problem covered in this chapter</a>, | ||
10215 | Up:<a rel=up href="#Some_Real_Life_Problems__With_Solutions_">Some Real Life Problems (With Solutions)</a> | ||
10216 | <br> | ||
10217 | |||
10218 | <h3>I think I have discovered a bug in CVS; what do I do?</h3> | ||
10219 | |||
10220 | <p>CVS is far from perfect - if you've already tried reading the manual | ||
10221 | and posting a question on the mailing list, and you still think you're | ||
10222 | looking at a bug, then you probably are. | ||
10223 | |||
10224 | <p>Send as complete a description of the bug as you can to | ||
10225 | <a href="mailto:bug-cvs@gnu.org">bug-cvs@gnu.org</a> (you can also subscribe to that list; just use | ||
10226 | <a href="mailto:bug-cvs-request@gnu.org">bug-cvs-request@gnu.org</a> instead). Be sure to include the | ||
10227 | version number of CVS (both client and server versions, if applicable), | ||
10228 | and a recipe for reproducing the bug. | ||
10229 | |||
10230 | <p>If you have written a patch to fix the bug, include it and mention on | ||
10231 | the subject line of your message that you have a patch. The maintainers | ||
10232 | will be very grateful. | ||
10233 | |||
10234 | <p>(Further details about these procedures are outlined in the node | ||
10235 | <cite>BUGS</cite> in the Cederqvist manual and the file HACKING in the source | ||
10236 | distribution.) | ||
10237 | |||
10238 | <p><hr> | ||
10239 | Node:<a name="I_have_implemented_a_new_feature_for_CVS__to_whom_do_I_send_it_">I have implemented a new feature for CVS; to whom do I send it?</a>, | ||
10240 | Next:<a rel=next href="#How_can_I_keep_up_with_changes_to_CVS_">How can I keep up with changes to CVS?</a>, | ||
10241 | Previous:<a rel=previous href="#I_think_I_have_discovered_a_bug_in_CVS__what_do_I_do_">I think I have discovered a bug in CVS; what do I do?</a>, | ||
10242 | Up:<a rel=up href="#Some_Real_Life_Problems__With_Solutions_">Some Real Life Problems (With Solutions)</a> | ||
10243 | <br> | ||
10244 | |||
10245 | <h3>I have implemented a new feature for CVS; to whom do I send it?</h3> | ||
10246 | |||
10247 | <p>Same as with a bug: Send the patch to <a href="mailto:bug-cvs@gnu.org">bug-cvs@gnu.org</a>. Make | ||
10248 | sure you've read over the HACKING file first, though. | ||
10249 | |||
10250 | <p><hr> | ||
10251 | Node:<a name="How_can_I_keep_up_with_changes_to_CVS_">How can I keep up with changes to CVS?</a>, | ||
10252 | Previous:<a rel=previous href="#I_have_implemented_a_new_feature_for_CVS__to_whom_do_I_send_it_">I have implemented a new feature for CVS; to whom do I send it?</a>, | ||
10253 | Up:<a rel=up href="#Some_Real_Life_Problems__With_Solutions_">Some Real Life Problems (With Solutions)</a> | ||
10254 | <br> | ||
10255 | |||
10256 | <h3>How can I keep up with changes to CVS?</h3> | ||
10257 | |||
10258 | <p>The troubleshooting techniques and known bugs described in this chapter | ||
10259 | are accurate as of (approximately) CVS Version 1.10.7. Things move fast | ||
10260 | in the CVS world, however. While I was writing the last few chapters, | ||
10261 | the unofficial mantle of CVS maintainership passed from Cyclic Software | ||
10262 | to SourceGear, Inc (<a href="http://www.sourcegear.com">http://www.sourcegear.com</a>), which purchased | ||
10263 | Cyclic. SourceGear has publicly announced its intention to take an | ||
10264 | active role in CVS maintainer-ship and has received Cyclic's approval, | ||
10265 | which is more or less enough to make it the "lead maintainer" of CVS as | ||
10266 | of right now. (The <a href="http://www.cyclic.com">http://www.cyclic.com</a> address will continue | ||
10267 | to work, however, so all of the URLs given previously in this book | ||
10268 | should remain valid.) | ||
10269 | |||
10270 | <p>SourceGear is, at this very moment, busy organizing and cleaning up | ||
10271 | various patches that have been floating around, with the intention of | ||
10272 | incorporating many of them into CVS. Some of these patches will | ||
10273 | probably fix bugs listed previously, and others may afford new | ||
10274 | troubleshooting tools to CVS users. | ||
10275 | |||
10276 | <p>The best way to stay up to date with what's going on is to read the NEWS | ||
10277 | file in your CVS distribution, watch the mailing lists, and look for | ||
10278 | changes to the Cederqvist manual and the online version of this book | ||
10279 | (<a href="http://cvsbook.red-bean.com">http://cvsbook.red-bean.com</a>). | ||
10280 | |||
10281 | <p><hr> | ||
10282 | Node:<a name="CVS_Reference">CVS Reference</a>, | ||
10283 | Next:<a rel=next href="#Third-Party_Tools">Third-Party Tools</a>, | ||
10284 | Previous:<a rel=previous href="#Tips_And_Troubleshooting">Tips And Troubleshooting</a>, | ||
10285 | Up:<a rel=up href="#Top">Top</a> | ||
10286 | <br> | ||
10287 | |||
10288 | <h1>CVS Reference</h1> | ||
10289 | |||
10290 | <p>This chapter is a complete reference to CVS commands, repository | ||
10291 | administrative files, keyword substitution, run control files, working | ||
10292 | copy files, and environment variables - everything in CVS as of CVS | ||
10293 | version 1.10.7 (more accurately, as of August 20, 1999). | ||
10294 | |||
10295 | <ul> | ||
10296 | <li><a href="#Commands_And_Options">Commands And Options</a>: All CVS global options and commands. | ||
10297 | <li><a href="#Keyword_Substitution__RCS_Keywords_">Keyword Substitution (RCS Keywords)</a>: CVS can maintain some text for you. | ||
10298 | <li><a href="#Repository_Administrative_Files">Repository Administrative Files</a>: Server-side files affecting CVS. | ||
10299 | <li><a href="#Run_Control_Files">Run Control Files</a>: Client-side files affecting CVS. | ||
10300 | <li><a href="#Working_Copy_Files">Working Copy Files</a>: Administrivia in the working copy. | ||
10301 | <li><a href="#Environment_Variables">Environment Variables</a>: Environment variables affecting CVS. | ||
10302 | </ul> | ||
10303 | |||
10304 | <p><hr> | ||
10305 | Node:<a name="Commands_And_Options">Commands And Options</a>, | ||
10306 | Next:<a rel=next href="#Keyword_Substitution__RCS_Keywords_">Keyword Substitution (RCS Keywords)</a>, | ||
10307 | Up:<a rel=up href="#CVS_Reference">CVS Reference</a> | ||
10308 | <br> | ||
10309 | |||
10310 | <h2>Commands And Options</h2> | ||
10311 | |||
10312 | <p>This section is a reference to all CVS commands. If you are not already | ||
10313 | familiar with the syntactic conventions shared by most CVS commands, you | ||
10314 | should probably read the relevant subsections before you look up any | ||
10315 | particular command. | ||
10316 | |||
10317 | <ul> | ||
10318 | <li><a href="#Organization_And_Conventions">Organization And Conventions</a>: How to read this section. | ||
10319 | <li><a href="#General_Patterns_In_CVS_Commands">General Patterns In CVS Commands</a>: CVS commands share some properties. | ||
10320 | <li><a href="#Date_Formats">Date Formats</a>: CVS accepts a variety of date formats. | ||
10321 | <li><a href="#Global_Options">Global Options</a>: A list of all global options to CVS. | ||
10322 | <li><a href="#add">add</a>: The <code>add</code> command. | ||
10323 | <li><a href="#admin">admin</a>: The <code>admin</code> command. | ||
10324 | <li><a href="#annotate">annotate</a>: The <code>annotate</code> command. | ||
10325 | <li><a href="#checkout">checkout</a>: The <code>checkout</code> command. | ||
10326 | <li><a href="#commit">commit</a>: The <code>commit</code> command. | ||
10327 | <li><a href="#diff">diff</a>: The <code>diff</code> command. | ||
10328 | <li><a href="#edit">edit</a>: The <code>edit</code> command. | ||
10329 | <li><a href="#editors">editors</a>: The <code>editors</code> command. | ||
10330 | <li><a href="#export">export</a>: The <code>export</code> command. | ||
10331 | <li><a href="#gserver">gserver</a>: The <code>gserver</code> command. | ||
10332 | <li><a href="#history">history</a>: The <code>history</code> command. | ||
10333 | <li><a href="#import">import</a>: The <code>import</code> command. | ||
10334 | <li><a href="#init">init</a>: The <code>init</code> command. | ||
10335 | <li><a href="#kserver">kserver</a>: The <code>kserver</code> command. | ||
10336 | <li><a href="#log">log</a>: The <code>log</code> command. | ||
10337 | <li><a href="#login">login</a>: The <code>login</code> command. | ||
10338 | <li><a href="#logout">logout</a>: The <code>logout</code> command. | ||
10339 | <li><a href="#pserver">pserver</a>: The <code>pserver</code> command. | ||
10340 | <li><a href="#rdiff">rdiff</a>: The <code>rdiff</code> command. | ||
10341 | <li><a href="#release">release</a>: The <code>release</code> command. | ||
10342 | <li><a href="#remove">remove</a>: The <code>remove</code> command. | ||
10343 | <li><a href="#rtag">rtag</a>: The <code>rtag</code> command. | ||
10344 | <li><a href="#server">server</a>: The <code>server</code> command. | ||
10345 | <li><a href="#status">status</a>: The <code>status</code> command. | ||
10346 | <li><a href="#tag">tag</a>: The <code>tag</code> command. | ||
10347 | <li><a href="#unedit">unedit</a>: The <code>unedit</code> command. | ||
10348 | <li><a href="#update">update</a>: The <code>update</code> command. | ||
10349 | <li><a href="#watch">watch</a>: The <code>watch</code> command. | ||
10350 | <li><a href="#watchers">watchers</a>: The <code>watchers</code> command. | ||
10351 | </ul> | ||
10352 | |||
10353 | <p><hr> | ||
10354 | Node:<a name="Organization_And_Conventions">Organization And Conventions</a>, | ||
10355 | Next:<a rel=next href="#General_Patterns_In_CVS_Commands">General Patterns In CVS Commands</a>, | ||
10356 | Up:<a rel=up href="#Commands_And_Options">Commands And Options</a> | ||
10357 | <br> | ||
10358 | |||
10359 | <h3>Organization And Conventions</h3> | ||
10360 | |||
10361 | <p>This section is organized alphabetically to make it easy for you to look | ||
10362 | up a particular command or option. The following conventions are used: | ||
10363 | |||
10364 | <ul> | ||
10365 | |||
10366 | <li>Arguments to commands and options are in all-capitalized letters in the | ||
10367 | synopsis that begins each explanation. (Note: in the treeware version | ||
10368 | of the book, meta-arguments are italicized as well as capitalized; due | ||
10369 | to the limitations of standard terminal fonts, I have omitted the | ||
10370 | italicization here.) | ||
10371 | |||
10372 | <li>Optional items appear between square brackets: <code>[ ]</code>. (This works | ||
10373 | out okay because square brackets turn out not used in CVS syntaces.) | ||
10374 | |||
10375 | <li>If you must choose one from a set, the choices are separated by bars, | ||
10376 | like this: <code>x|y|z</code>. (And therefore forward slashes (<code>/</code>) | ||
10377 | should be interpreted literally - they do not divide choices in a set.) | ||
10378 | |||
10379 | <li>Plurals or ellipses indicate multiples, usually separated by whitespace. | ||
10380 | For example, FILES means one or more files, but [FILES] means zero or | ||
10381 | more files. The entry [&MOD...] means an ampersand followed immediately | ||
10382 | by a module name, then whitespace, then maybe another ampersand-module, | ||
10383 | and so on, zero or more times. (The ellipsis is used because a plural | ||
10384 | would have left it unclear whether the ampersand is needed only the | ||
10385 | first time or once for each module.) | ||
10386 | |||
10387 | <p>When a plural is parenthesized, as in FILE(S), it means that although | ||
10388 | technically there can be two or more files, usually there is only one. | ||
10389 | |||
10390 | </p><li>REV is often used to stand for a revision argument. This is usually | ||
10391 | either a revision number or a tag name. There are very few places in | ||
10392 | CVS where you can use one but not the other, and those places are noted | ||
10393 | in the text. | ||
10394 | |||
10395 | </ul> | ||
10396 | |||
10397 | <p><hr> | ||
10398 | Node:<a name="General_Patterns_In_CVS_Commands">General Patterns In CVS Commands</a>, | ||
10399 | Next:<a rel=next href="#Date_Formats">Date Formats</a>, | ||
10400 | Previous:<a rel=previous href="#Organization_And_Conventions">Organization And Conventions</a>, | ||
10401 | Up:<a rel=up href="#Commands_And_Options">Commands And Options</a> | ||
10402 | <br> | ||
10403 | |||
10404 | <h3>General Patterns In CVS Commands</h3> | ||
10405 | |||
10406 | <p>CVS commands follow this form: | ||
10407 | |||
10408 | <pre>cvs [GLOBAL_OPTIONS] COMMAND [OPTIONS] [FILES] | ||
10409 | </pre> | ||
10410 | |||
10411 | <p>The second set of options is sometimes called <dfn>command options</dfn>. | ||
10412 | Because there are so many of them, though, I'll just call them "options" | ||
10413 | in most places to save space. | ||
10414 | |||
10415 | <p>Many commands are meant to be run within a working copy and, therefore, | ||
10416 | may be invoked without file arguments. These commands default to all of | ||
10417 | the files in the current directory and below. So when I refer to the | ||
10418 | "file" or "files" in the text, I'm talking about the files on which CVS | ||
10419 | is acting. Depending on how you invoked CVS, these files may or may not | ||
10420 | have been explicitly mentioned on the command line. | ||
10421 | |||
10422 | <p><hr> | ||
10423 | Node:<a name="Date_Formats">Date Formats</a>, | ||
10424 | Next:<a rel=next href="#Global_Options">Global Options</a>, | ||
10425 | Previous:<a rel=previous href="#General_Patterns_In_CVS_Commands">General Patterns In CVS Commands</a>, | ||
10426 | Up:<a rel=up href="#Commands_And_Options">Commands And Options</a> | ||
10427 | <br> | ||
10428 | |||
10429 | <h3>Date Formats</h3> | ||
10430 | |||
10431 | <p>Many options take a date argument. CVS accepts a wide variety of date | ||
10432 | formats - too many to list here. When in doubt, stick with the | ||
10433 | standard ISO 8601 format: | ||
10434 | |||
10435 | <pre>1999-08-23 | ||
10436 | </pre> | ||
10437 | |||
10438 | <p>This means "23 August 1999" (in fact, "23 August 1999" is a perfectly | ||
10439 | valid date specifier too, as long as you remember to enclose it in | ||
10440 | double quotes). If you need a time of day as well, you can do this: | ||
10441 | |||
10442 | <pre>"1999-08-23 21:20:30 CDT" | ||
10443 | </pre> | ||
10444 | |||
10445 | <p>You can even use certain common English constructs, such as "now", | ||
10446 | "yesterday", and "12 days ago". In general, you can safely experiment | ||
10447 | with date formats; if CVS understands your format at all, it most likely | ||
10448 | will understand it in the way you intended. If it doesn't understand, | ||
10449 | it will exit with an error immediately. | ||
10450 | |||
10451 | <p><hr> | ||
10452 | Node:<a name="Global_Options">Global Options</a>, | ||
10453 | Next:<a rel=next href="#add">add</a>, | ||
10454 | Previous:<a rel=previous href="#Date_Formats">Date Formats</a>, | ||
10455 | Up:<a rel=up href="#Commands_And_Options">Commands And Options</a> | ||
10456 | <br> | ||
10457 | |||
10458 | <h3>Global Options</h3> | ||
10459 | |||
10460 | <p>Here are all the global options to CVS. | ||
10461 | |||
10462 | <h2><code>--allow-root=REPOSITORY</code></h2> | ||
10463 | |||
10464 | <p>The alphabetically first global option is one that is virtually never | ||
10465 | used on the command line. The -allow-root option is used with the | ||
10466 | <code>pserver</code> command to allow authenticated access to the named | ||
10467 | repository (which is a repository top level, such as | ||
10468 | <code>/usr/local/newrepos</code>, not a project subdirectory such as | ||
10469 | <code>/usr/local/newrepos/myproj</code>). | ||
10470 | |||
10471 | <p>This global option is virtually never used on the command line. | ||
10472 | Normally, the only place you'd ever use it is in /etc/inetd.conf files | ||
10473 | (see <a href="#Repository_Administration">Repository Administration</a>), which is also about the only | ||
10474 | place the <code>pserver</code> command is used. | ||
10475 | |||
10476 | <p>Every repository to be accessed via <code>cvs pserver</code> on a given | ||
10477 | host needs a corresponding -allow-root option in | ||
10478 | <code>/etc/inetd.conf</code>. This is a security device, meant to ensure that | ||
10479 | people can't use a CVS pserver to gain access to private repositories. | ||
10480 | |||
10481 | <p>(See <a href="#The_Password-Authenticating_Server">The Password-Authenticating Server</a> also the node | ||
10482 | <cite>Password Authentication Server</cite> in the Cederqvist manual.) | ||
10483 | |||
10484 | <h2><code>-a</code></h2> | ||
10485 | |||
10486 | <p>This authenticates all communications with the server. This option has | ||
10487 | no effect unless you're connecting via the GSSAPI server (gserver). | ||
10488 | GSSAPI connections are not covered in this book, because they're still | ||
10489 | somewhat rarely used (although that may change). (See the nodes | ||
10490 | <cite>Global Options</cite> and <cite>GSSAPI Authenticated</cite> in the Cederqvist | ||
10491 | manual for more information.) | ||
10492 | |||
10493 | <h2><code>-b</code> (Obsolete)</h2> | ||
10494 | |||
10495 | <p>This option formerly specified the directory where the RCS binaries | ||
10496 | could be found. CVS now implements the RCS functions internally, so | ||
10497 | this option has no effect (it is kept only for backward compatibility). | ||
10498 | |||
10499 | <h2><code>-d</code> REPOSITORY</h2> | ||
10500 | |||
10501 | <p>This specifies the repository, which might be an absolute pathname or a | ||
10502 | more complex expression involving a connection method, username and | ||
10503 | host, and path. If it is an expression specifying a connection method, | ||
10504 | the general syntax is: | ||
10505 | |||
10506 | <pre>:METHOD:USER@HOSTNAME:PATH_TO_REPOSITORY | ||
10507 | </pre> | ||
10508 | |||
10509 | <p>Here are examples using each of the connection methods: | ||
10510 | |||
10511 | <ul> | ||
10512 | |||
10513 | <li><code>:ext:jrandom@floss.red-bean.com:/usr/local/newrepos</code> - Connects | ||
10514 | using <code>rsh</code>, <code>ssh</code>, or some other external connection program. | ||
10515 | If the <code>$CVS_RSH</code> environment variable is unset, this defaults to | ||
10516 | <code>rsh</code>; otherwise, it uses the value of that variable. | ||
10517 | |||
10518 | <li><code>:server:jrandom@floss.red-bean.com:/usr/local/newrepos</code> - Like | ||
10519 | <code>:ext:</code>, but uses CVS's internal implementation of rsh. (This may | ||
10520 | not be available on all platforms.) | ||
10521 | |||
10522 | <li><code>:pserver:jrandom@floss.red-bean.com:/usr/local/newrepos</code> - | ||
10523 | Connects using the password authenticating server (see <a href="#The_Password-Authenticating_Server">The Password-Authenticating Server</a> in <a href="#Repository_Administration">Repository Administration</a>; see | ||
10524 | also the <a href="#login">login</a> command.) | ||
10525 | |||
10526 | <li><code>:kserver:jrandom@floss.red-bean.com:/usr/local/newrepos</code> - | ||
10527 | Connects using Kerberos authentication. | ||
10528 | |||
10529 | <li><code>:gserver:jrandom@floss.red-bean.com:/usr/local/newrepos</code> - | ||
10530 | Connects using GSSAPI authentication. | ||
10531 | |||
10532 | <li><code>:fork:jrandom@floss.red-bean.com:/usr/local/newrepos</code> - Connects | ||
10533 | to a local repository, but using the client/server network protocol | ||
10534 | instead of directly accessing the repository files. This is useful for | ||
10535 | testing or debugging remote CVS behaviors from your local machine. | ||
10536 | |||
10537 | <li><code>:local:jrandom@floss.red-bean.com:/usr/local/newrepos</code> - | ||
10538 | Accesses a local repository directly, as though only the absolute path | ||
10539 | to the repository had been given. | ||
10540 | |||
10541 | </ul> | ||
10542 | |||
10543 | <h2><code>-e</code> EDITOR</h2> | ||
10544 | |||
10545 | <p>Invokes EDITOR for your commit message, if the commit message was not | ||
10546 | specified on the command line with the -m option. Normally, if you | ||
10547 | don't give a message with -m, CVS invokes the editor based on the | ||
10548 | <code>$CVSEDITOR</code>, <code>$VISUAL</code>, or <code>$EDITOR</code> environment | ||
10549 | variables, which it checks in that order. Failing that, it invokes the | ||
10550 | popular Unix editor <code>vi</code>. | ||
10551 | |||
10552 | <p>If you pass both the -e global option and the -m option to commit, the | ||
10553 | -e is ignored in favor of the commit message given on the command line | ||
10554 | (that way it's safe to use -e in a <code>.cvsrc</code> file). | ||
10555 | |||
10556 | <h2><code>-f</code></h2> | ||
10557 | |||
10558 | <p>This global option suppresses reading of the <code>.cvsrc</code> file. | ||
10559 | |||
10560 | <h2><code>--help</code> [COMMAND] or <code>-H</code> [COMMAND]</h2> | ||
10561 | |||
10562 | <p>These two options are synonymous. If no COMMAND is specified, a basic | ||
10563 | usage message is printed to the standard output. If COMMAND is | ||
10564 | specified, a usage message for that command is printed. | ||
10565 | |||
10566 | <h2><code>--help-options</code></h2> | ||
10567 | |||
10568 | <p>Prints out a list of all global options to CVS, with brief explanations. | ||
10569 | |||
10570 | <h2><code>--help-synonyms</code></h2> | ||
10571 | |||
10572 | <p>Prints out a list of CVS commands and their short forms ("up" for | ||
10573 | "update", and so on). | ||
10574 | |||
10575 | <h2><code>-l</code></h2> | ||
10576 | |||
10577 | <p>Suppresses logging of this command in the <code>CVSROOT/history</code> file in | ||
10578 | the repository. The command is still executed normally, but no record | ||
10579 | of it is made in the history file. | ||
10580 | |||
10581 | <h2><code>-n</code></h2> | ||
10582 | |||
10583 | <p>Doesn't change any files in the working copy or in the repository. In | ||
10584 | other words, the command is executed as a "dry run" - CVS goes through | ||
10585 | most of the steps of the command but stops short of actually running it. | ||
10586 | |||
10587 | <p>This is useful when you want to see what the command would have done had | ||
10588 | you actually run it. One common scenario is when you want to see what | ||
10589 | files in your working directory have been modified, but not do a full | ||
10590 | update (which would bring down changes from the repository). By running | ||
10591 | <code>cvs -n update</code>, you can see a summary of what's been done | ||
10592 | locally, without changing your working copy. | ||
10593 | |||
10594 | <h2><code>-q</code></h2> | ||
10595 | |||
10596 | <p>This tells CVS to be moderately quiet by suppressing the printing of | ||
10597 | unimportant informational messages. What is considered "important" | ||
10598 | depends on the command. For example, in updates, the messages that CVS | ||
10599 | normally prints on entering each subdirectory of the working copy are | ||
10600 | suppressed, but the one-line status messages for modified or updated | ||
10601 | files are still printed. | ||
10602 | |||
10603 | <h2><code>-Q</code></h2> | ||
10604 | |||
10605 | <p>This tells CVS to be very quiet, by suppressing all output except what | ||
10606 | is absolutely necessary to complete the command. Commands whose sole | ||
10607 | purpose is to produce some output (such as <code>diff</code> or | ||
10608 | <code>annotate</code>), of course, still give that output. However, commands | ||
10609 | that could have an effect independent of any messages that they may | ||
10610 | print (such as <code>update</code> or <code>commit</code>) print nothing. | ||
10611 | |||
10612 | <h2><code>-r</code></h2> | ||
10613 | |||
10614 | <p>Causes new working files to be created read-only (the same effect as | ||
10615 | setting the <code>$CVSREAD</code> environment variable). | ||
10616 | |||
10617 | <p>If you pass this option, checkouts and updates make the files in your | ||
10618 | working copy read-only (assuming your operating system permits it). | ||
10619 | Frankly, I'm not sure why one would ever want to use this option. | ||
10620 | |||
10621 | <h2><code>-s</code> VARIABLE<code>=</code>VALUE</h2> | ||
10622 | |||
10623 | <p>This sets an internal CVS variable named VARIABLE to | ||
10624 | VALUE. | ||
10625 | |||
10626 | <p>On the repository side, the <code>CVSROOT/*info</code> trigger files can | ||
10627 | expand such variables to values that were assigned in the -s option. | ||
10628 | For example, if <code>CVSROOT/loginfo</code> contains a line like this | ||
10629 | |||
10630 | <pre>myproj /usr/local/bin/foo.pl ${=FISH} | ||
10631 | </pre> | ||
10632 | |||
10633 | <p>and someone runs a commit from a myproj working copy like this | ||
10634 | |||
10635 | <pre>floss$ cvs -s FISH=carp commit -m "fixed the bait bug" | ||
10636 | </pre> | ||
10637 | |||
10638 | <p>the <code>foo.pl</code> script is invoked with <code>carp</code> as an argument. | ||
10639 | Note the funky syntax, though: The dollar sign, equal sign, and curly | ||
10640 | braces are all necessary - if any of them are missing, the expansion | ||
10641 | will not take place (at least not as intended). Variable names may | ||
10642 | contain alphanumerics and underscores only. Although it is not required | ||
10643 | that they consist entirely of capital letters, most people do seem to | ||
10644 | follow that convention. | ||
10645 | |||
10646 | <p>You can use the -s flag as many times as you like in a single command. | ||
10647 | However, if the trigger script refers to variables that aren't set in a | ||
10648 | particular invocation of CVS, the command still succeeds, but none of | ||
10649 | the variables are expanded, and the user sees a warning. For example, | ||
10650 | if loginfo has this | ||
10651 | |||
10652 | <pre>myproj /usr/local/bin/foo.pl ${=FISH} ${=BIRD} | ||
10653 | </pre> | ||
10654 | |||
10655 | <p>but the same command as before is run | ||
10656 | |||
10657 | <pre>floss$ cvs -s FISH=carp commit -m "fixed the bait bug" | ||
10658 | </pre> | ||
10659 | |||
10660 | <p>the person running the command sees a warning something like this | ||
10661 | (placed last in the output) | ||
10662 | |||
10663 | <pre>loginfo:31: no such user variable ${=BIRD} | ||
10664 | </pre> | ||
10665 | |||
10666 | <p>and the <code>foo.pl</code> script is invoked with no arguments. But if this | ||
10667 | command were run | ||
10668 | |||
10669 | <pre>floss$ cvs -s FISH=carp -s BIRD=vulture commit -m "fixed the bait bug" | ||
10670 | </pre> | ||
10671 | |||
10672 | <p>there would be no warning, and both <code>${=FISH}</code> and | ||
10673 | <code>${=BIRD}</code> in loginfo would be correctly expanded. In either | ||
10674 | case, the commit itself would still succeed. | ||
10675 | |||
10676 | <p>Although these examples all use <code>commit</code>, variable expansion can be | ||
10677 | done with any CVS command that can be noticed in a <code>CVSROOT/</code> | ||
10678 | trigger file - which is why the -s option is global. | ||
10679 | |||
10680 | <p>(See the section <a href="#Repository_Administrative_Files">Repository Administrative Files</a> later in this | ||
10681 | chapter for more details about variable expansion in trigger files.) | ||
10682 | |||
10683 | <h2><code>-T</code> DIR</h2> | ||
10684 | |||
10685 | <p>Stores any temporary files in DIR instead of wherever CVS normally puts | ||
10686 | them (specifically, this overrides the value of the <code>$TMPDIR</code> | ||
10687 | environment variable, if any exists). DIR should be an absolute path. | ||
10688 | |||
10689 | <p>This option is useful when you don't have write permission (and, | ||
10690 | therefore, CVS doesn't either) to the usual temporary locations. | ||
10691 | |||
10692 | <h2><code>-t</code></h2> | ||
10693 | |||
10694 | <p>Traces the execution of a CVS command. This causes CVS to print | ||
10695 | messages showing the steps that it's going through to complete a | ||
10696 | command. You may find it particularly useful in conjunction with the -n | ||
10697 | global option, to preview the effects of an unfamiliar command before | ||
10698 | running it for real. It can also be handy when you're trying to | ||
10699 | discover why a command failed. | ||
10700 | |||
10701 | <h2><code>-v</code> or <code>--version</code></h2> | ||
10702 | |||
10703 | <p>Causes CVS to print out its version and copyright information and then | ||
10704 | exit with no error. | ||
10705 | |||
10706 | <h2><code>-w</code></h2> | ||
10707 | |||
10708 | <p>Causes new working files to be created read-write (overrides any setting | ||
10709 | of the <code>$CVSREAD</code> environment variable). Because files are created | ||
10710 | read-write by default anyway, this option is rarely used. | ||
10711 | |||
10712 | <p>If both -r and -w are passed, -w dominates. | ||
10713 | |||
10714 | <h2><code>-x</code></h2> | ||
10715 | |||
10716 | <p>Encrypts all communications with the server. This option has no effect | ||
10717 | unless you're connecting via the GSSAPI server (gserver). GSSAPI | ||
10718 | connections are not covered in this book, because they're still somewhat | ||
10719 | rarely used (although that may change). (See the nodes <cite>Global | ||
10720 | Options</cite> and <cite>GSSAPI Authenticated</cite> in the Cederqvist manual for | ||
10721 | more information.) | ||
10722 | |||
10723 | <h2><code>-z</code> GZIPLEVEL</h2> | ||
10724 | |||
10725 | <p>Sets the compression level on communications with the server. The | ||
10726 | argument GZIPLEVEL must be a number from 1 to 9. Level 1 is | ||
10727 | minimal compression (very fast, but doesn't compress much); Level 9 is | ||
10728 | highest compression (uses a lot of CPU time, but sure does squeeze the | ||
10729 | data). Level 9 is only useful on very slow network connections. Most | ||
10730 | people find levels between 3 and 5 to be most beneficial. | ||
10731 | |||
10732 | <p>A space between -z and its argument is optional. | ||
10733 | |||
10734 | <p><hr> | ||
10735 | Node:<a name="add">add</a>, | ||
10736 | Next:<a rel=next href="#admin">admin</a>, | ||
10737 | Previous:<a rel=previous href="#Global_Options">Global Options</a>, | ||
10738 | Up:<a rel=up href="#Commands_And_Options">Commands And Options</a> | ||
10739 | <br> | ||
10740 | |||
10741 | <h3>add</h3> | ||
10742 | |||
10743 | <p>Synopsis: add [OPTIONS] FILES | ||
10744 | |||
10745 | <ul> | ||
10746 | <li>Alternate names - ad, new | ||
10747 | <li>Requires - Working copy, repository | ||
10748 | <li>Changes - Working copy | ||
10749 | </ul> | ||
10750 | |||
10751 | <p>Adds a new file or files to an existing project. Although the | ||
10752 | repository is contacted for confirmation, the file does not actually | ||
10753 | appear in it until a subsequent commit is performed. (See also | ||
10754 | <a href="#remove">remove</a> and <a href="#import">import</a>.) | ||
10755 | |||
10756 | <p>Options: | ||
10757 | |||
10758 | <ul> | ||
10759 | |||
10760 | <li>-kKEYWORD_SUBSTITUTION_MODE - Specifies that the file is to be stored | ||
10761 | with the given RCS keyword substitution mode. There is no space between | ||
10762 | the -k and its argument. (See the section <a href="#Keyword_Substitution__RCS_Keywords_">Keyword Substitution (RCS Keywords)</a> later in this chapter for a list of valid modes and | ||
10763 | examples.) | ||
10764 | |||
10765 | <li>-m MESSAGE - Records MESSAGE as the creation message, or description, | ||
10766 | for the file. This is different from a per-revision log message - each | ||
10767 | file has only one description. Descriptions are optional. | ||
10768 | |||
10769 | <p>As of version 1.10.7, there is a bug in CVS whereby the description is | ||
10770 | lost if you add a file via client/server CVS. The rest of the add | ||
10771 | process seems to work fine, however, if that's any comfort. | ||
10772 | |||
10773 | </ul> | ||
10774 | |||
10775 | <p><hr> | ||
10776 | Node:<a name="admin">admin</a>, | ||
10777 | Next:<a rel=next href="#annotate">annotate</a>, | ||
10778 | Previous:<a rel=previous href="#add">add</a>, | ||
10779 | Up:<a rel=up href="#Commands_And_Options">Commands And Options</a> | ||
10780 | <br> | ||
10781 | |||
10782 | <h3>admin</h3> | ||
10783 | |||
10784 | <p>Synopsis: admin [OPTIONS] [FILES] | ||
10785 | |||
10786 | <ul> | ||
10787 | <li>Alternate names - adm, rcs | ||
10788 | <li>Requires - Working copy, repository | ||
10789 | <li>Changes - Repository | ||
10790 | </ul> | ||
10791 | |||
10792 | <p>This command is an interface to various administrative tasks - | ||
10793 | specifically, tasks applicable to individual RCS files in the | ||
10794 | repository, such as changing a file's keyword substitution mode or | ||
10795 | changing a log message after it's been committed. | ||
10796 | |||
10797 | <p>Although admin behaves recursively if no files are given as arguments, | ||
10798 | you normally will want to name files explicitly. It's very rare for a | ||
10799 | single admin command to be meaningful when applied to all files in a | ||
10800 | project, or even in a directory. Accordingly, when the following | ||
10801 | explanations refer to the "file", they mean the file or (rarely) files | ||
10802 | passed as arguments to the admin command. | ||
10803 | |||
10804 | <p>If there is a system group named <code>cvsadmin</code> on the repository | ||
10805 | machine, only members of that group can run admin (with the exception of | ||
10806 | the <code>cvs admin -k</code> command, which is always permitted). Thus | ||
10807 | you can disallow admin for all users by setting the group to have no | ||
10808 | users. | ||
10809 | |||
10810 | <p>Options: | ||
10811 | |||
10812 | <ul> | ||
10813 | |||
10814 | <li>-AOLDFILE - (Obsolete) Appends the RCS access list of OLDFILE to the | ||
10815 | access list of the file that is the argument to admin. CVS ignores RCS | ||
10816 | access lists, so this option is useless. | ||
10817 | |||
10818 | <li>-a USER1 [,USER2...] - (Obsolete) Appends the users in the | ||
10819 | comma-separated list to the access list of the file. Like -A, this | ||
10820 | option is useless in CVS. | ||
10821 | |||
10822 | <li>-bREV - Sets the revision of the file's default branch (usually the | ||
10823 | trunk) to REV. You won't normally need this option, because you can | ||
10824 | usually get the revisions you need via sticky tags, but you may use it | ||
10825 | to revert to a vendor's version if you're using vendor branches. There | ||
10826 | should be no space between the -b and its argument. | ||
10827 | |||
10828 | <li>-cCOMMENT_PREFIX - (Obsolete) Sets the comment leader of the file to | ||
10829 | COMMENT_PREFIX. The comment leader is not used by CVS or even by recent | ||
10830 | versions of RCS; therefore, this option is useless and is included only | ||
10831 | for backward-compatibility. | ||
10832 | |||
10833 | <li>-eUSER1[,USER2...] - (Obsolete) Removes the usernames appearing in the | ||
10834 | comma-separated list from the access list of the RCS file. Like -a and | ||
10835 | -A, this option is now useless in CVS. | ||
10836 | |||
10837 | <li>-i or -I - These two are so obsolete I'm not even going to tell you | ||
10838 | what they used to do. (See the Cederqvist manual if you're curious.) | ||
10839 | |||
10840 | <li>-kMODE - Sets the file's default keyword substitution mode to MODE. | ||
10841 | This option behaves like the -k option to add, only it gives you a way | ||
10842 | to change a file's mode after it's been added. (See the section | ||
10843 | <a href="#Keyword_Substitution__RCS_Keywords_">Keyword Substitution (RCS Keywords)</a> later in this chapter for | ||
10844 | valid modes.) There should be no space between -k and its argument. | ||
10845 | |||
10846 | <li>-L - Sets locking to <code>strict</code>. (See -l below.) | ||
10847 | |||
10848 | <li>-l[REV] - Locks the file's revision to REV. If REV is omitted, it | ||
10849 | locks the latest revision on the default branch (usually the trunk). If | ||
10850 | REV is a branch, it locks the latest revision on that branch. | ||
10851 | |||
10852 | <p>The intent of this option is to give you a way to do <dfn>reserved | ||
10853 | checkouts</dfn>, where only one user can be editing the file at a time. I'm | ||
10854 | not sure how useful this really is, but if you want to try it, you | ||
10855 | should probably do so in conjunction with the rcslock.pl script in the | ||
10856 | CVS source distribution's contrib/ directory. See comments in that file | ||
10857 | for further information. Among other things, those comments indicate | ||
10858 | that the locking must be set to <code>strict</code>. (See -L.) There is no | ||
10859 | space between -l and its argument. | ||
10860 | |||
10861 | </p><li>-mREV:MESSAGE - Changes the log message for revision REV to MESSAGE. | ||
10862 | Very handy - along with -k, this is probably the most frequently used | ||
10863 | admin option. There are no spaces between option and arguments or | ||
10864 | around the colon between the two arguments. Of course, MESSAGE may | ||
10865 | contain spaces within itself (in which case, remember to surround it | ||
10866 | with quotes so the shell knows it's all one thing). | ||
10867 | |||
10868 | <li>-NNAME[:[REV]] - Just like -n, except it forces the override of any | ||
10869 | existing assignment of the symbolic name NAME, instead of exiting with | ||
10870 | error. | ||
10871 | |||
10872 | <li>-nNAME[:[REV]] - This is a generic interface to assigning, renaming, | ||
10873 | and deleting tags. There is no reason, as far as I can see, to prefer | ||
10874 | it to the tag command and the various options available there (-d, -r, | ||
10875 | -b, -f, and so on). I recommend using the tag command instead. The | ||
10876 | NAME and optional REV can be combined in the following ways: | ||
10877 | |||
10878 | <ul> | ||
10879 | |||
10880 | <li>If only the NAME argument is given, the symbolic name (tag) named NAME | ||
10881 | is deleted. | ||
10882 | |||
10883 | <li>If NAME: is given but no REV, NAME is assigned to the latest revision on | ||
10884 | the default branch (usually the trunk). | ||
10885 | |||
10886 | <li>If NAME:REV is given, NAME is assigned to that revision. REV can be a | ||
10887 | symbolic name itself, in which case it is translated to a revision | ||
10888 | number first (can be a branch number). | ||
10889 | |||
10890 | <li>If REV is a branch number and is followed by a period (<code>.</code>), NAME | ||
10891 | is attached to the highest revision on that branch. If REV is just $, | ||
10892 | NAME is attached to revision numbers found in keyword strings in the | ||
10893 | working files. | ||
10894 | |||
10895 | <p>In all cases where a NAME is assigned, CVS exits with an error if there | ||
10896 | is already a tag named NAME in the file (but see -N). There are no | ||
10897 | spaces between -n and its arguments. | ||
10898 | |||
10899 | </ul> | ||
10900 | |||
10901 | </p><li>-oRANGE - Deletes the revisions specified by RANGE (also known as | ||
10902 | "outdating", hence the -o). Range can be specified in one of the | ||
10903 | following ways: | ||
10904 | |||
10905 | <ul> | ||
10906 | <li>REV1::REV2 - Collapses all intermediate revisions between REV1 and | ||
10907 | REV2, so that the revision history goes directly from REV1 to REV2. | ||
10908 | After this, any revisions between the two no longer exist, and there | ||
10909 | will be a noncontiguous jump in the revision number sequence. | ||
10910 | |||
10911 | <li>::REV - Collapses all revisions between the beginning of REV's branch | ||
10912 | (which may be the beginning of the trunk) and REV, noninclusively of | ||
10913 | course. REV is then the first revision on that line. | ||
10914 | |||
10915 | <li>REV:: - Collapses all revisions between REV and the end of its branch | ||
10916 | (which may be the trunk). REV is then the last revision on that line. | ||
10917 | |||
10918 | <li>REV - Deletes the revision REV (-o1.8 would be equivalent to | ||
10919 | -o1.7::1.9). | ||
10920 | |||
10921 | <li>REV1:REV2 - Deletes the revisions from REV1 to REV2, inclusive. They | ||
10922 | must be on the same branch. After this, you cannot retrieve REV1, REV2, | ||
10923 | or any of the revisions in between. | ||
10924 | |||
10925 | <li>:REV - Deletes revisions from the beginning of the branch (or trunk) to | ||
10926 | REV, inclusive. (See the preceding warning.) | ||
10927 | |||
10928 | <li>REV: - Deletes revisions from REV to the end of its branch (or trunk), | ||
10929 | inclusive. (See the preceding warning.) | ||
10930 | |||
10931 | <p>None of the revisions being deleted may have branches or locks. If any | ||
10932 | of the revisions have symbolic names attached, you have to delete them | ||
10933 | first with tag -d or admin -n. (Actually, right now CVS only protects | ||
10934 | against deleting symbolically named revisions if you're using one of the | ||
10935 | :: syntaxes, but the single-colon syntaxes may soon change to this | ||
10936 | behavior as well.) | ||
10937 | |||
10938 | <p>Instead of using this option to undo a bad commit, you should commit a | ||
10939 | new revision that undoes the bad change. There are no spaces between -o | ||
10940 | and its arguments. | ||
10941 | |||
10942 | </ul> | ||
10943 | |||
10944 | </p><li>-q - Tells CVS to run quietly - don't print diagnostic messages (just | ||
10945 | like the global -q option). | ||
10946 | |||
10947 | <li>-sSTATE[:REV] - Sets the state attribute of revision REV to STATE. If | ||
10948 | REV is omitted, the latest revision on the default branch (usually the | ||
10949 | trunk) is used. If REV is a branch tag or number, the latest revision | ||
10950 | on that branch is used. | ||
10951 | |||
10952 | <p>Any string of letters or numbers is acceptable for STATE; some commonly | ||
10953 | used states are Exp for experimental, Stab for stable, and Rel for | ||
10954 | released. (In fact, CVS sets the state to Exp when a file is created.) | ||
10955 | Note that CVS uses the state dead for its own purposes, so don't specify | ||
10956 | that one. | ||
10957 | |||
10958 | <p>States are displayed in cvs log output, and in the $Log and $State RCS | ||
10959 | keywords in files. There is no space between -s and its arguments. | ||
10960 | |||
10961 | </p><li>-t[DESCFILE] - Replaces the description (creation message) for the file | ||
10962 | with the contents of DESCFILE, or reads from standard input if no | ||
10963 | DESCFILE is specified. | ||
10964 | |||
10965 | <p>This useful option, unfortunately, does not currently work in | ||
10966 | client/server CVS. In addition, if you try it in client/server and omit | ||
10967 | DESCFILE, any existing description for the file is wiped out and | ||
10968 | replaced with the empty string. If you need to rewrite a file's | ||
10969 | description, either do so using only local CVS on the same machine as | ||
10970 | the repository or -t-STRING (see below). There is no space between -t | ||
10971 | and its argument. DESCFILE may not begin with a hyphen (<code>-</code>). | ||
10972 | |||
10973 | </p><li>-t-STRING - Like -t, except that STRING is taken directly as the new | ||
10974 | description. STRING may contain spaces, in which case you should | ||
10975 | surround it with quotes. Unlike the other syntax for -t, this works in | ||
10976 | client/server as well as locally. | ||
10977 | |||
10978 | <li>-U - Sets locking to nonstrict. (See -l and -L options, discussed | ||
10979 | earlier.) | ||
10980 | |||
10981 | <li>-u[REV] - Unlocks revision REV. (See -l.) If REV is omitted, CVS | ||
10982 | unlocks the latest lock held by the caller. If REV is a branch, CVS | ||
10983 | unlocks the latest revision on that branch. If someone other than the | ||
10984 | owner of a lock breaks the lock, a mail message is sent to the original | ||
10985 | locker. The content for this message is solicited on standard input | ||
10986 | from the person breaking the lock. There is no space between -u and its | ||
10987 | argument. | ||
10988 | |||
10989 | <li>-VRCS_VERSION_NUMBER - (Obsolete) This used to be a way to tell CVS to | ||
10990 | produce RCS files acceptable to previous versions of RCS. Now the RCS | ||
10991 | format used by CVS is drifting away from the RCS format used by RCS, so | ||
10992 | this option is useless. Specifying it results in an error. | ||
10993 | |||
10994 | <li>-xSUFFIX - (Obsolete) Theoretically, this gives you a way to specify | ||
10995 | the suffix for RCS file names. However, CVS and related tools all | ||
10996 | depend on that suffix being the default (,v), so this option does | ||
10997 | nothing. | ||
10998 | |||
10999 | </ul> | ||
11000 | |||
11001 | <p><hr> | ||
11002 | Node:<a name="annotate">annotate</a>, | ||
11003 | Next:<a rel=next href="#checkout">checkout</a>, | ||
11004 | Previous:<a rel=previous href="#admin">admin</a>, | ||
11005 | Up:<a rel=up href="#Commands_And_Options">Commands And Options</a> | ||
11006 | <br> | ||
11007 | |||
11008 | <h3>annotate</h3> | ||
11009 | |||
11010 | <p>Synopsis: annotate [OPTIONS] [FILES] | ||
11011 | |||
11012 | <ul> | ||
11013 | <li>Alternate name - ann | ||
11014 | <li>Requires - Working copy, repository | ||
11015 | <li>Changes - Nothing | ||
11016 | </ul> | ||
11017 | |||
11018 | <p>Shows information on who last modified each line of each file and when. | ||
11019 | Each line of output corresponds to one line of the file. From left to | ||
11020 | right, the line displays the revision number of the last modification of | ||
11021 | that line, a parenthetical expression containing the user and date of | ||
11022 | the modification, a colon, and the contents of the line in the file. | ||
11023 | |||
11024 | <p>For example, if a file looks like this | ||
11025 | |||
11026 | <pre>this is a test file | ||
11027 | it only has too lines | ||
11028 | I mean "two" | ||
11029 | </pre> | ||
11030 | |||
11031 | <p>the annotations for that file could look like this | ||
11032 | |||
11033 | <pre>1.1 (jrandom 22-Aug-99): this is a test file | ||
11034 | 1.1 (jrandom 22-Aug-99): it only has too lines | ||
11035 | 1.2 (jrandom 22-Aug-99): I mean "two" | ||
11036 | </pre> | ||
11037 | |||
11038 | <p>from which you would know that the first two lines were in the initial | ||
11039 | revision, and the last line was added or modified (also by jrandom) in | ||
11040 | Revision 1.2. | ||
11041 | |||
11042 | <p>Options: | ||
11043 | |||
11044 | <ul> | ||
11045 | |||
11046 | <li>-D DATE - Shows the annotations as of the latest revision no later than | ||
11047 | DATE. | ||
11048 | |||
11049 | <li>-f - Forces use of the head revision if the specified tag or date is | ||
11050 | not found. You can use this in combination with -D or -r to ensure that | ||
11051 | there is some output from the annotate command, even if only to show | ||
11052 | Revision 1.1 of the file. | ||
11053 | |||
11054 | <li>-l - Local. Runs in the current working directory only. Does not | ||
11055 | descend into subdirectories. | ||
11056 | |||
11057 | <li>-R - Recursive. Descends into subdirectories (the default). The point | ||
11058 | of the -R option is to override any -l option set in a .cvsrc file. | ||
11059 | |||
11060 | <li>-r REV - Shows annotations as of revision REV (can be a revision number | ||
11061 | or a tag). | ||
11062 | |||
11063 | </ul> | ||
11064 | |||
11065 | <p><hr> | ||
11066 | Node:<a name="checkout">checkout</a>, | ||
11067 | Next:<a rel=next href="#commit">commit</a>, | ||
11068 | Previous:<a rel=previous href="#annotate">annotate</a>, | ||
11069 | Up:<a rel=up href="#Commands_And_Options">Commands And Options</a> | ||
11070 | <br> | ||
11071 | |||
11072 | <h3>checkout</h3> | ||
11073 | |||
11074 | <p>Synopsis: checkout [OPTIONS] PROJECT(S) | ||
11075 | |||
11076 | <ul> | ||
11077 | <li>Alternate names - co, get | ||
11078 | <li>Requires - Repository | ||
11079 | <li>Changes - Current directory | ||
11080 | </ul> | ||
11081 | |||
11082 | <p>Checks out a module from the repository into a working copy. The | ||
11083 | working copy is created if it doesn't exist already and updated if it | ||
11084 | does. (See also <a href="#update">update</a>.) | ||
11085 | |||
11086 | <p>Options: | ||
11087 | |||
11088 | <ul> | ||
11089 | |||
11090 | <li>-A - Resets any sticky tags, sticky dates, or sticky -k (RCS keyword | ||
11091 | substitution mode) options. This is like the -A option to update and is | ||
11092 | probably more often used there than with checkout. | ||
11093 | |||
11094 | <li>-c - Doesn't check anything out; just prints the CVSROOT/modules file, | ||
11095 | sorted, on standard output. This is a good way to get an overview of | ||
11096 | what projects are in a repository. However, a project without an entry | ||
11097 | in modules does not appear (this situation is quite normal because the | ||
11098 | name of the project's top-level directory in the repository functions as | ||
11099 | the project's "default" module name). | ||
11100 | |||
11101 | <li>-D DATE - Checks out the latest revisions no later than DATE. This | ||
11102 | option is sticky, so you won't be able to commit from the working copy | ||
11103 | without resetting the sticky date. (See -A.) This option also implies | ||
11104 | -P, described later. | ||
11105 | |||
11106 | <li>-d DIR - Creates the working copy in a directory named DIR, instead of | ||
11107 | creating a directory with the same name as the checked-out module. If | ||
11108 | you check out only a portion of a project and the portion is located | ||
11109 | somewhere beneath the project's top level, the locally empty | ||
11110 | intermediate directories are omitted. You can use -N to suppress this | ||
11111 | directory-collapsing behavior. | ||
11112 | |||
11113 | <li>-f - Forces checkout of the head revision if the specified tag or date | ||
11114 | is not found. Most often used in combination with -D or -r to ensure | ||
11115 | that something always gets checked out. | ||
11116 | |||
11117 | <li>-j REV[:DATE] or -j REV1[:DATE] -j REV2[:DATE] - Joins (merges) two | ||
11118 | lines of development. This is just like the -j option to update, where | ||
11119 | it is more commonly used. (See <a href="#update">update</a> for details.) | ||
11120 | |||
11121 | <li>-k MODE - Substitutes RCS keywords according to MODE (which can | ||
11122 | override the default modes for the files). (See the section <a href="#Keyword_Substitution__RCS_Keywords_">Keyword Substitution (RCS Keywords)</a> later in this chapter for valid modes.) | ||
11123 | The mode chosen will be sticky - future updates of the working copy | ||
11124 | will keep that mode. | ||
11125 | |||
11126 | <li>-l - Local. Checks out the top-level directory of the project only. | ||
11127 | Does not process subdirectories. | ||
11128 | |||
11129 | <li>-N - Suppresses collapsing of empty directories with -d option. (See | ||
11130 | -d.) | ||
11131 | |||
11132 | <li>-n - Doesn't run any checkout program that was specified with -o in | ||
11133 | CVSROOT/modules. (See the section <a href="#Repository_Administrative_Files">Repository Administrative Files</a> later in this chapter for more on this.) | ||
11134 | |||
11135 | <li>-P - Prunes empty directories from the working copy (like the -P option | ||
11136 | to update). | ||
11137 | |||
11138 | <li>-p - Checks files out to standard output, not into files (like the -p | ||
11139 | option to update). | ||
11140 | |||
11141 | <li>-R - Checks out subdirectories as well (the default). (See also the -f | ||
11142 | option.) | ||
11143 | |||
11144 | <li>-r TAG - Checks out the project as of revision TAG (it would make | ||
11145 | almost no sense to specify a numeric revision for TAG, although CVS lets | ||
11146 | you). This option is sticky and implies -P. | ||
11147 | |||
11148 | <li>-s - Like -c, but shows the status of each module and sorts by status. | ||
11149 | (See <a href="#modules">modules</a> in the section <a href="#Repository_Administrative_Files">Repository Administrative Files</a> | ||
11150 | for more information.) | ||
11151 | |||
11152 | </ul> | ||
11153 | |||
11154 | <p><hr> | ||
11155 | Node:<a name="commit">commit</a>, | ||
11156 | Next:<a rel=next href="#diff">diff</a>, | ||
11157 | Previous:<a rel=previous href="#checkout">checkout</a>, | ||
11158 | Up:<a rel=up href="#Commands_And_Options">Commands And Options</a> | ||
11159 | <br> | ||
11160 | |||
11161 | <h3>commit</h3> | ||
11162 | |||
11163 | <p>Synopsis: commit [OPTIONS] [FILES] | ||
11164 | |||
11165 | <ul> | ||
11166 | <li>Alternate names - ci, com | ||
11167 | <li>Requires - Working copy, repository | ||
11168 | <li>Changes - Repository (and working copy administrative area) | ||
11169 | </ul> | ||
11170 | |||
11171 | <p>Commits changes from a working copy to the repository. | ||
11172 | |||
11173 | <p>Options: | ||
11174 | |||
11175 | <ul> | ||
11176 | |||
11177 | <li>-F MSGFILE - Uses the contents of MSGFILE for the log message instead | ||
11178 | of invoking an editor. This option cannot be combined with -m. | ||
11179 | |||
11180 | <li>-f - Forces commit of a new revision even if no changes have been made | ||
11181 | to the files. <code>commit</code> does not recurse with this option (it | ||
11182 | implies -l). You can force it to recurse with -R. | ||
11183 | |||
11184 | <p>This meaning of -f is at odds with its usual meaning ("force to head | ||
11185 | revision") in CVS commands. | ||
11186 | |||
11187 | </p><li>-l - Local. Commits changes from the current directory only. Doesn't | ||
11188 | descend into subdirectories. | ||
11189 | |||
11190 | <li>-m MESSAGE - Uses MESSAGE as the log message instead of invoking an | ||
11191 | editor. Cannot be used with -F. | ||
11192 | |||
11193 | <li>-n - Does not run any module program. (See the section | ||
11194 | <a href="#Repository_Administrative_Files">Repository Administrative Files</a> in this chapter for information | ||
11195 | about module programs.) | ||
11196 | |||
11197 | <li>-R - Commits changes from subdirectories as well as from the current | ||
11198 | directory (the default). This option is used only to counteract the | ||
11199 | effect of a -l in .cvsrc. | ||
11200 | |||
11201 | <li>-r REV - Commits to revision REV, which must be either a branch or a | ||
11202 | revision on the trunk that is higher than any existing revision. | ||
11203 | Commits to a branch always go on the tip of the branch (extending it); | ||
11204 | you cannot commit to a specific revision on a branch. Use of this | ||
11205 | option sets the new revision as a sticky tag on the file. This can be | ||
11206 | cleared with update -A. | ||
11207 | |||
11208 | <p>The -r REV option implies -f as well. A new revision is committed even | ||
11209 | if there are no changes to commit. | ||
11210 | |||
11211 | </ul> | ||
11212 | |||
11213 | <p><hr> | ||
11214 | Node:<a name="diff">diff</a>, | ||
11215 | Next:<a rel=next href="#edit">edit</a>, | ||
11216 | Previous:<a rel=previous href="#commit">commit</a>, | ||
11217 | Up:<a rel=up href="#Commands_And_Options">Commands And Options</a> | ||
11218 | <br> | ||
11219 | |||
11220 | <h3>diff</h3> | ||
11221 | |||
11222 | <p>Synopsis: diff [OPTIONS] [FILES] | ||
11223 | |||
11224 | <ul> | ||
11225 | <li>Alternate names - di, dif | ||
11226 | <li>Requires - Working copy, repository | ||
11227 | <li>Changes - Nothing | ||
11228 | </ul> | ||
11229 | |||
11230 | <p>Shows the difference between two revisions (in Unix diff format). When | ||
11231 | invoked with no options, CVS diffs the repository base revisions against | ||
11232 | the (possibly uncommitted) contents of the working copy. The <dfn>base</dfn> | ||
11233 | revisions are the latest revisions of this working copy retrieved from | ||
11234 | the repository; note that there could be even later revisions in the | ||
11235 | repository, if someone else committed changes but this working copy | ||
11236 | hasn't been updated yet. (See also <a href="#rdiff">rdiff</a>.) | ||
11237 | |||
11238 | <p>Options: | ||
11239 | |||
11240 | <ul> | ||
11241 | |||
11242 | <li>-D DATE - Diffs against the latest revisions no later than DATE. | ||
11243 | Behaves like -r REV, except uses dates rather than revisions. (See -r | ||
11244 | for details.) | ||
11245 | |||
11246 | <li>-k MODE - Expands RCS keywords in the diffs according to MODE. (See | ||
11247 | the section <a href="#Keyword_Substitution__RCS_Keywords_">Keyword Substitution (RCS Keywords)</a> in this chapter | ||
11248 | for possible modes.) | ||
11249 | |||
11250 | <li>-l - Local. If no files were specified as arguments, this option diffs | ||
11251 | files in the current directory, but does not descend into | ||
11252 | subdirectories. | ||
11253 | |||
11254 | <li>-R - Recursive. This option is the opposite of -l. This is the | ||
11255 | default behavior, so the only reason to specify -R is to counteract a -l | ||
11256 | in a .cvsrc file. | ||
11257 | |||
11258 | <li>-r REV or -r REV1 -r REV2 - Diffs against (or between) the specified | ||
11259 | revisions. With one -r option, this diffs revision REV against your | ||
11260 | working copy of that file (so when multiple files are being diffed, REV | ||
11261 | is almost always a tag). With two -r options, it diffs REV1 against | ||
11262 | REV2 for each file (and the working copy is, therefore, irrelevant). | ||
11263 | The two revisions can be in any order - REV1 does not have to be an | ||
11264 | earlier revision than REV2. The output reflects the direction of | ||
11265 | change. With no -r options, it shows the difference between the working | ||
11266 | file and the revision on which it is based. | ||
11267 | |||
11268 | </ul> | ||
11269 | |||
11270 | <p>Diff Compatibility Options | ||
11271 | |||
11272 | <p>In addition to the preceding options, cvs diff also shares a number of | ||
11273 | options with the GNU version of the standard command-line diff program. | ||
11274 | Following is a complete list of these options, along with an explanation | ||
11275 | of a few of the most commonly used ones. (See the GNU diff documentation | ||
11276 | for the others.) | ||
11277 | |||
11278 | <pre>-0 -1 -2 -3 -4 -5 -6 -7 -8 -9 | ||
11279 | --binary | ||
11280 | --brief | ||
11281 | --changed-group-format=ARG | ||
11282 | -c | ||
11283 | -C NLINES | ||
11284 | --context[=LINES] | ||
11285 | -e --ed | ||
11286 | -t --expand-tabs | ||
11287 | -f --forward-ed | ||
11288 | --horizon-lines=ARG | ||
11289 | --ifdef=ARG | ||
11290 | -w --ignore-all-space | ||
11291 | -B --ignore-blank-lines | ||
11292 | -i --ignore-case | ||
11293 | -I REGEXP | ||
11294 | --ignore-matching-lines=REGEXP | ||
11295 | -h | ||
11296 | -b --ignore-space-change | ||
11297 | -T --initial-tab | ||
11298 | -L LABEL | ||
11299 | --label=LABEL | ||
11300 | --left-column | ||
11301 | -d --minimal | ||
11302 | -N --new-file | ||
11303 | --new-line-format=ARG | ||
11304 | --old-line-format=ARG | ||
11305 | --paginate | ||
11306 | -n --rcs | ||
11307 | -s --report-identical-files | ||
11308 | -p | ||
11309 | --show-c-function | ||
11310 | -y --side-by-side | ||
11311 | -F REGEXP | ||
11312 | --show-function-line=REGEXP | ||
11313 | -H --speed-large-files | ||
11314 | --suppress-common-lines | ||
11315 | -a --text | ||
11316 | --unchanged-group-format=ARG | ||
11317 | -u | ||
11318 | -U NLINES | ||
11319 | --unified[=LINES] | ||
11320 | -V ARG | ||
11321 | -W COLUMNS | ||
11322 | --width=COLUMNS | ||
11323 | </pre> | ||
11324 | |||
11325 | <p>Following are the GNU diff options most frequently used with cvs diff. | ||
11326 | |||
11327 | <ul> | ||
11328 | |||
11329 | <li>-B - Ignores differences that are merely the insertion or deletion of | ||
11330 | blank lines (lines containing nothing but whitespace characters). | ||
11331 | |||
11332 | <li>-b - Ignores differences in the amount of whitespace. This option | ||
11333 | treats all whitespace sequences as being equal and ignores whitespace at | ||
11334 | line end. More technically, this option collapses each whitespace | ||
11335 | sequence in the input to a single space and removes any trailing | ||
11336 | whitespace from each line, before taking the diff. (See also -w.) | ||
11337 | |||
11338 | <li>-c - Shows output in context diff format, defaulting to three lines of | ||
11339 | context per difference (for the sake of the patch program, which | ||
11340 | requires at least two lines of context). | ||
11341 | |||
11342 | <li>-C NUM - context=NUM - Like -c, but with NUM lines of context. | ||
11343 | |||
11344 | <li>-i - Compares case insensitively. Treats upper- and lowercase versions | ||
11345 | of a letter as the same. | ||
11346 | |||
11347 | <li>-u - Shows output in unified diff format. | ||
11348 | |||
11349 | <li>-w - Ignores all whitespace differences, even when one side of the | ||
11350 | input has whitespace where the other has none. Essentially a stronger | ||
11351 | version of -b. | ||
11352 | |||
11353 | </ul> | ||
11354 | |||
11355 | <p><hr> | ||
11356 | Node:<a name="edit">edit</a>, | ||
11357 | Next:<a rel=next href="#editors">editors</a>, | ||
11358 | Previous:<a rel=previous href="#diff">diff</a>, | ||
11359 | Up:<a rel=up href="#Commands_And_Options">Commands And Options</a> | ||
11360 | <br> | ||
11361 | |||
11362 | <h3>edit</h3> | ||
11363 | |||
11364 | <p>Synopsis: edit [OPTIONS] [FILES] | ||
11365 | |||
11366 | <ul> | ||
11367 | <li>Alternate names - None | ||
11368 | <li>Requires - Working copy, repository | ||
11369 | <li>Changes - Permissions in working copy, watchlist in repository | ||
11370 | </ul> | ||
11371 | |||
11372 | <p>Signals that you are about to begin editing a watched file or files. | ||
11373 | Also adds you as a temporary watcher to the file's watch list (you'll be | ||
11374 | removed when you do cvs unedit). (See also <a href="#watch">watch</a>, | ||
11375 | <a href="#watchers">watchers</a>, <a href="#unedit">unedit</a>, and <a href="#editors">editors</a>.) | ||
11376 | |||
11377 | <p>Options: | ||
11378 | |||
11379 | <ul> | ||
11380 | |||
11381 | <li>-a ACTIONS - Specifies for which actions you want to be a temporary | ||
11382 | watcher. ACTIONS should be either edit, unedit, commit, all, or none. | ||
11383 | (If you don't use -a, the temporary watch will be for all actions.) | ||
11384 | |||
11385 | <li>-l - Local. Signals editing for files in the current working directory | ||
11386 | only. | ||
11387 | |||
11388 | <li>-R - Recursive (this is the default). Opposite of b; you would only | ||
11389 | need to pass -R to counteract a -l in a .cvsrc file. | ||
11390 | |||
11391 | </ul> | ||
11392 | |||
11393 | <p><hr> | ||
11394 | Node:<a name="editors">editors</a>, | ||
11395 | Next:<a rel=next href="#export">export</a>, | ||
11396 | Previous:<a rel=previous href="#edit">edit</a>, | ||
11397 | Up:<a rel=up href="#Commands_And_Options">Commands And Options</a> | ||
11398 | <br> | ||
11399 | |||
11400 | <h3>editors</h3> | ||
11401 | |||
11402 | <p>Synopsis: editors [OPTIONS] [FILES] | ||
11403 | |||
11404 | <ul> | ||
11405 | <li>Alternate names - None | ||
11406 | <li>Requires - Working copy, repository | ||
11407 | <li>Changes - Nothing | ||
11408 | </ul> | ||
11409 | |||
11410 | <p>Shows who is currently editing a watched file. (See also | ||
11411 | <a href="#watch">watch</a>, <a href="#watchers">watchers</a>, <a href="#edit">edit</a>, and <a href="#unedit">unedit</a>.) | ||
11412 | |||
11413 | <p>Options: | ||
11414 | |||
11415 | <ul> | ||
11416 | |||
11417 | <li>-l - Local. Views editors for files in current directory only. | ||
11418 | |||
11419 | <li>-R - Recursive. Views editors for files in this directory and its | ||
11420 | subdirectories (the default). You may need to pass -R to counteract a | ||
11421 | -l in a .cvsrc file, though. | ||
11422 | |||
11423 | </ul> | ||
11424 | |||
11425 | <p><hr> | ||
11426 | Node:<a name="export">export</a>, | ||
11427 | Next:<a rel=next href="#gserver">gserver</a>, | ||
11428 | Previous:<a rel=previous href="#editors">editors</a>, | ||
11429 | Up:<a rel=up href="#Commands_And_Options">Commands And Options</a> | ||
11430 | <br> | ||
11431 | |||
11432 | <h3>export</h3> | ||
11433 | |||
11434 | <p>Synopsis: export [OPTIONS] PROJECT(S) | ||
11435 | |||
11436 | <ul> | ||
11437 | <li>Alternate names - exp, ex | ||
11438 | <li>Requires - Repository | ||
11439 | <li>Changes - Current directory | ||
11440 | </ul> | ||
11441 | |||
11442 | <p>Exports files from the repository to create a project tree that is not a | ||
11443 | working copy (has no CVS/ administrative subdirectories). Useful mainly | ||
11444 | for packaging distributions. | ||
11445 | |||
11446 | <p>Options: | ||
11447 | |||
11448 | <ul> | ||
11449 | |||
11450 | <li>-D DATE - Exports the latest revisions no later than DATE. | ||
11451 | |||
11452 | <li>-d DIR - Exports into DIR (otherwise, defaults to the module name). | ||
11453 | |||
11454 | <li>-f - Forces use of head revisions, if a given tag or date would result | ||
11455 | in nothing being found (for use with -D or -r). | ||
11456 | |||
11457 | <li>-k MODE - Expands RCS keywords according to MODE. (See the section | ||
11458 | <a href="#Keyword_Substitution__RCS_Keywords_">Keyword Substitution (RCS Keywords)</a> later in this chapter.) | ||
11459 | |||
11460 | <li>-l - Local. Exports only the top level of the project, no | ||
11461 | subdirectories. | ||
11462 | |||
11463 | <li>-N - Doesn't "collapse" empty intermediate directories. This option is | ||
11464 | like the -N option to checkout (see <a href="#checkout">checkout</a>). | ||
11465 | |||
11466 | <li>-n - Does not run a module program as may be specified in | ||
11467 | <code>CVSROOT/modules</code>. (See <a href="#Repository_Administrative_Files">Repository Administrative Files</a> | ||
11468 | later in this chapter for more about this.) | ||
11469 | |||
11470 | <li>-P - Prunes empty directories (like the -P option to checkout or | ||
11471 | update). | ||
11472 | |||
11473 | <li>-R - Recursive. Exports all subdirectories of the project (the | ||
11474 | default). The only reason to specify -R is to counteract a -l in a | ||
11475 | <code>.cvsrc</code> file. | ||
11476 | |||
11477 | <li>-r REV - Exports revision REV. REV is almost certainly a tag name, not | ||
11478 | a numeric revision. | ||
11479 | |||
11480 | </ul> | ||
11481 | |||
11482 | <p><hr> | ||
11483 | Node:<a name="gserver">gserver</a>, | ||
11484 | Next:<a rel=next href="#history">history</a>, | ||
11485 | Previous:<a rel=previous href="#export">export</a>, | ||
11486 | Up:<a rel=up href="#Commands_And_Options">Commands And Options</a> | ||
11487 | <br> | ||
11488 | |||
11489 | <h3>gserver</h3> | ||
11490 | |||
11491 | <p>Synopsis: gserver | ||
11492 | |||
11493 | <p>This is the GSSAPI (Generic Security Services API) server. This command | ||
11494 | is not normally run directly by users. Instead, it is started up on the | ||
11495 | server side when a user connects from a client with the <code>:gserver:</code> | ||
11496 | access method: | ||
11497 | |||
11498 | <pre>cvs -d :gserver:floss.red-bean.com:/usr/local/newrepos checkout myproj | ||
11499 | </pre> | ||
11500 | |||
11501 | <p>GSSAPI provides, among other things, Kerberos Version 5; for Kerberos | ||
11502 | Version 4, use <code>:kserver:</code>. | ||
11503 | |||
11504 | <p>Setting up and using a GSSAPI library on your machines is beyond the | ||
11505 | scope of this book. (See the node <cite>GSSAPI Authenticated</cite> in the | ||
11506 | Cederqvist manual for some useful hints, however.) | ||
11507 | |||
11508 | <p>Options: None. | ||
11509 | |||
11510 | <p><hr> | ||
11511 | Node:<a name="history">history</a>, | ||
11512 | Next:<a rel=next href="#import">import</a>, | ||
11513 | Previous:<a rel=previous href="#gserver">gserver</a>, | ||
11514 | Up:<a rel=up href="#Commands_And_Options">Commands And Options</a> | ||
11515 | <br> | ||
11516 | |||
11517 | <h3>history</h3> | ||
11518 | |||
11519 | <p>Synopsis: history [OPTIONS] [FILENAME_SUBSTRING(S)] | ||
11520 | |||
11521 | <ul> | ||
11522 | <li>Alternate names - hi, his | ||
11523 | <li>Requires - Repository, CVSROOT/history | ||
11524 | <li>Changes - Nothing | ||
11525 | </ul> | ||
11526 | |||
11527 | <p>Shows a history of activity in the repository. Specifically, this | ||
11528 | option shows records of checkouts, commits, rtags, updates, and | ||
11529 | releases. By default, the option shows checkouts (but see the -x | ||
11530 | option). This command won't work if there's no CVSROOT/history file in | ||
11531 | the repository. | ||
11532 | |||
11533 | <p>The history command differs from other CVS commands in several ways. | ||
11534 | First, it must usually be given options to do anything useful (and some | ||
11535 | of those options mean different things for history than they do | ||
11536 | elsewhere in CVS). Second, instead of taking full file names as | ||
11537 | arguments, it takes one or more substrings to match against file names | ||
11538 | (all records matching at least one of those substrings are retrieved). | ||
11539 | Third, history's output looks a lot like line noise until you learn to | ||
11540 | read it, so I'll explain the output format in a special section, after | ||
11541 | the options. (See also <a href="#log">log</a>.) | ||
11542 | |||
11543 | <p>Options: | ||
11544 | |||
11545 | <ul> | ||
11546 | |||
11547 | <li>-a - Shows history for all users (otherwise, defaults to self). | ||
11548 | |||
11549 | <li>-b STR - Shows data back to record containing string STR in the module | ||
11550 | name, file name, or repository path. | ||
11551 | |||
11552 | <li>-c - Reports commits. | ||
11553 | |||
11554 | <li>-D DATE - Shows data since DATE (the usual CVS date formats are | ||
11555 | available). | ||
11556 | |||
11557 | <li>-e - Everything - reports on all record types. | ||
11558 | |||
11559 | <li>-f FILE - Reports the most recent event concerning FILE. You can | ||
11560 | specify this option multiple times. This is different from the usual | ||
11561 | meaning of -f in CVS commands: "Force to head revision as a last | ||
11562 | resort." | ||
11563 | |||
11564 | <li>-l - Shows the record representing the last (as in "most recent") event | ||
11565 | of each project. This is different from the usual meaning of -l in CVS | ||
11566 | commands: "Run locally, do not recurse." | ||
11567 | |||
11568 | <li>-m MODULE - This provides a full report about MODULE (a project name). | ||
11569 | You can specify this option multiple times. | ||
11570 | |||
11571 | <li>-n MODULE - Reports the most recent event about MODULE. For example, | ||
11572 | checking out the module is about the module itself, but modifying or | ||
11573 | updating a file inside the module is about that file, not about the | ||
11574 | module. You can specify this option multiple times. This is different | ||
11575 | from the usual meaning of -n in CVS commands: "Don't run a | ||
11576 | CVSROOT/modules program." | ||
11577 | |||
11578 | <li>-o - Shows checkout records (the default). | ||
11579 | |||
11580 | <li>-p REPOS - Shows data for a particular directory in the repository. | ||
11581 | You can specify this option multiple times. The meaning of this option | ||
11582 | differs from the usual meaning of -p in CVS commands: "Pipe the data to | ||
11583 | standard output instead of a file." | ||
11584 | |||
11585 | <p>This option appears to be at least partially broken as of summer 1999. | ||
11586 | |||
11587 | </p><li>-r REV - Shows records referring to revisions since the revision or tag | ||
11588 | named REV appears in individual RCS files. Each RCS file is searched | ||
11589 | for the revision or tag. | ||
11590 | |||
11591 | <li>-T - Reports on all tag events. | ||
11592 | |||
11593 | <li>-t TAG - Shows records since tag TAG was last added to the history | ||
11594 | file. This differs from the -r flag in that it reads only the | ||
11595 | CVSROOT/history file, not the RCS files, and is therefore much faster. | ||
11596 | |||
11597 | <li>-u USER - Shows events associated with USER. You can specify this | ||
11598 | option multiple times. | ||
11599 | |||
11600 | <li>-w - Shows records that are associated with the same working directory | ||
11601 | from which you are invoking history. | ||
11602 | |||
11603 | <li>-X HISTORYFILE - Uses HISTORYFILE instead of CVSROOT/history. This | ||
11604 | option is mainly for debugging and is not officially supported; | ||
11605 | nevertheless, you may find it useful (perhaps for generating | ||
11606 | human-readable reports from old history files you've kept around). | ||
11607 | |||
11608 | <li>-x TYPES - Reports on events specified in TYPES. Each type is | ||
11609 | represented by a single letter, from the set <code>TOEFWUCGMAR</code>; any | ||
11610 | number of letters can be combined. Here is what they mean: | ||
11611 | |||
11612 | <ul> | ||
11613 | <li>T - Tag | ||
11614 | <li>O - Checkout | ||
11615 | <li>E - Export | ||
11616 | <li>F - Release | ||
11617 | <li>W - Update (newly obsolete file removed from working copy) | ||
11618 | <li>U - Update (file was checked out over user file) | ||
11619 | <li>C - Update (merge, with conflicts) | ||
11620 | <li>G - Update (merge, no conflicts) | ||
11621 | <li>M - Commit (file was modified) | ||
11622 | <li>A - Commit (file was added) | ||
11623 | <li>R - Commit (file was removed) | ||
11624 | </ul> | ||
11625 | |||
11626 | <p>The default, if no -x option is given, is to show checkouts (like | ||
11627 | <code>-x O</code>). | ||
11628 | |||
11629 | </p><li>-z ZONE - Displays times in output as for time zone ZONE. ZONE is an | ||
11630 | abbreviated time zone name, such as UTC, GMT, BST, CDT, CCT, and so on. | ||
11631 | A complete list of time zones is available in the TimezoneTable in the | ||
11632 | file lib/getdate.c in the CVS source distribution. | ||
11633 | |||
11634 | </ul> | ||
11635 | |||
11636 | <p>History Output | ||
11637 | |||
11638 | <p>The output of the history command is a series of lines; each line | ||
11639 | represents one "history event" and starts with a single code letter | ||
11640 | indicating what type of event it is. For example: | ||
11641 | |||
11642 | <pre>floss$ cvs history -D yesterday -x TMO | ||
11643 | M 08/21 20:19 +0000 jrandom 2.2 baar myproj == <remote> | ||
11644 | M 08/22 04:18 +0000 jrandom 1.2 README myproj == <remote> | ||
11645 | O 08/22 05:15 +0000 jrandom myproj =myproj= ~/src/* | ||
11646 | M 08/22 05:33 +0000 jrandom 2.18 README.txt myproj == ~/src/myproj | ||
11647 | O 08/22 14:25 CDT jrandom myproj =myproj= ~/src/* | ||
11648 | O 08/22 14:26 CDT jrandom [99.08.23.19.26.03] myproj =myproj= ~/src/* | ||
11649 | O 08/22 14:28 CDT jrandom [Exotic_Greetings-branch] myproj =myproj= ~/src/* | ||
11650 | </pre> | ||
11651 | |||
11652 | <p>The code letters are the same as for the -x option just described. | ||
11653 | Following the code letter is the date of the event (expressed in UTC/GMT | ||
11654 | time, unless the -z option is used), followed by the user responsible | ||
11655 | for the event. | ||
11656 | |||
11657 | <p>After the user might be a revision number, tag, or date, but only if | ||
11658 | such is appropriate for the event (date or tag will be in square | ||
11659 | brackets and formatted as shown in the preceding example). If you | ||
11660 | commit a file, it shows the new revision number; if you check out with | ||
11661 | -D or -r, the sticky date or tag is shown in square brackets. For a | ||
11662 | plain checkout, nothing extra is shown. | ||
11663 | |||
11664 | <p>Next comes the name of the file in question, or module name if the event | ||
11665 | is about a module. If the former, the next two things are the | ||
11666 | module/project name and the location of the working copy in the user's | ||
11667 | home directory. If the latter, the next two things are the name of the | ||
11668 | module's checked-out working copy (between two equal signs), followed by | ||
11669 | its location in the user's home directory. (The name of the checked-out | ||
11670 | working copy may differ from the module name if the -d flag is used with | ||
11671 | checkout.) | ||
11672 | |||
11673 | <p><hr> | ||
11674 | Node:<a name="import">import</a>, | ||
11675 | Next:<a rel=next href="#init">init</a>, | ||
11676 | Previous:<a rel=previous href="#history">history</a>, | ||
11677 | Up:<a rel=up href="#Commands_And_Options">Commands And Options</a> | ||
11678 | <br> | ||
11679 | |||
11680 | <h3>import</h3> | ||
11681 | |||
11682 | <p>Synopsis: import [OPTIONS] REPOSITORY VENDOR_TAG RELEASE_TAG(S) | ||
11683 | |||
11684 | <ul> | ||
11685 | <li>Alternate names - im, imp | ||
11686 | <li>Requires - Repository, current directory (the source directory) | ||
11687 | <li>Changes - Repository | ||
11688 | </ul> | ||
11689 | |||
11690 | <p>Imports new sources into the repository, either creating a new project | ||
11691 | or creating a new vendor revision on a vendor branch of an existing | ||
11692 | project. (See <a href="#Advanced_CVS">Advanced CVS</a> for a basic explanation of vendor | ||
11693 | branches in import, which will help you to understand the following.) | ||
11694 | |||
11695 | <p>It's normal to use import to add many files or directories at once or to | ||
11696 | create a new project. To add single files, you should use add. | ||
11697 | |||
11698 | <p>Options: | ||
11699 | |||
11700 | <ul> | ||
11701 | |||
11702 | <li>-b BRANCH - Imports to vendor branch BRANCH. (BRANCH is an actual | ||
11703 | branch number, not a tag.) This is rarely used but can be helpful if | ||
11704 | you get sources for the same project from different vendors. A normal | ||
11705 | import command assumes that the sources are to be imported on the | ||
11706 | default vendor branch, which is "1.1.1". Because it is the default, you | ||
11707 | normally don't bother to specify it with -b: | ||
11708 | |||
11709 | <pre>floss$ cvs import -m "importing from vendor 1" theirproj THEM1 THEM1-0 | ||
11710 | </pre> | ||
11711 | |||
11712 | <p>To import to a vendor branch other than the default, you must specify a | ||
11713 | different branch number explicitly: | ||
11714 | |||
11715 | <pre>floss$ cvs import -b 1.1.3 -m "from vendor 2" theirproj THEM2 THEM2-0 | ||
11716 | </pre> | ||
11717 | |||
11718 | <p>The 1.1.3 branch can absorb future imports and be merged like any other | ||
11719 | vendor branch. However, you must make sure any future imports that | ||
11720 | specify <code>-b 1.1.3</code> also use the same vendor tag (<code>THEM2</code>). | ||
11721 | CVS does not check to make sure that the vendor branch matches the | ||
11722 | vendor tag. However, if they mismatch, odd and unpredictable things | ||
11723 | will happen. | ||
11724 | |||
11725 | <p>Vendor branches are odd-numbered, the opposite of regular branches. | ||
11726 | |||
11727 | </p><li>-d - Takes the file's modification time as the time of import instead | ||
11728 | of using the current time. This does not work with client/server CVS. | ||
11729 | |||
11730 | <li>-I NAME - Gives file names that should be ignored in the import. You | ||
11731 | can use this option multiple times in one import. Wildcard patterns are | ||
11732 | supported: <code>*.foo</code> means ignore everything ending in <code>.foo</code>. | ||
11733 | (See <a href="#cvsignore">cvsignore</a> in <a href="#Repository_Administrative_Files">Repository Administrative Files</a> for | ||
11734 | details about wildcards.) | ||
11735 | |||
11736 | <p>The following file and directory names are ignored by default: | ||
11737 | |||
11738 | <pre>. | ||
11739 | .. | ||
11740 | .#* | ||
11741 | #* | ||
11742 | ,* | ||
11743 | _$* | ||
11744 | *~ | ||
11745 | *$ | ||
11746 | *.a | ||
11747 | *.bak | ||
11748 | *.BAK | ||
11749 | *.elc | ||
11750 | *.exe | ||
11751 | *.ln | ||
11752 | *.o | ||
11753 | *.obj | ||
11754 | *.olb | ||
11755 | *.old | ||
11756 | *.orig | ||
11757 | *.rej | ||
11758 | *.so | ||
11759 | *.Z | ||
11760 | .del-* | ||
11761 | .make.state | ||
11762 | .nse_depinfo | ||
11763 | core | ||
11764 | CVS | ||
11765 | CVS.adm | ||
11766 | cvslog.* | ||
11767 | RCS | ||
11768 | RCSLOG | ||
11769 | SCCS | ||
11770 | tags | ||
11771 | TAGS | ||
11772 | </pre> | ||
11773 | |||
11774 | <p>You can suppress the ignoring of those file name patterns, as well as | ||
11775 | any specified in <code>.cvsignore</code>, <code>CVSROOT/cvsignore</code>, and the | ||
11776 | <code>$CVSIGNORE</code> environment variable, by using <code>-I !</code>. That | ||
11777 | is, | ||
11778 | |||
11779 | <pre>floss$ cvs import -I ! -m "importing the universe" proj VENDOR VENDOR_0 | ||
11780 | </pre> | ||
11781 | |||
11782 | <p>imports all files in the current directory tree, even those that would | ||
11783 | otherwise be ignored. | ||
11784 | |||
11785 | <p>Using a <code>-I !</code> clears whatever ignore list has been created to | ||
11786 | that point, so any -I options that came before it would be nullified, | ||
11787 | but any that come after will still count. Thus, | ||
11788 | |||
11789 | <pre>floss$ cvs import -I ! -I README.txt -m "some msg" theirproj THEM THEM_0 | ||
11790 | </pre> | ||
11791 | |||
11792 | <p>is not the same as | ||
11793 | |||
11794 | <pre>floss$ cvs import -I README.txt -I ! -m "some msg" theirproj THEM THEM_0 | ||
11795 | </pre> | ||
11796 | |||
11797 | <p>The former ignores (fails to import) README.txt, whereas the latter | ||
11798 | imports it. | ||
11799 | |||
11800 | </p><li>-k MODE - Sets the default RCS keyword substitution mode for the | ||
11801 | imported files. (See <a href="#Keyword_Substitution__RCS_Keywords_">Keyword Substitution (RCS Keywords)</a> later in | ||
11802 | this chapter for a list of valid modes.) | ||
11803 | |||
11804 | <li>-m MESSAGE - Records MESSAGE as the import log message. | ||
11805 | |||
11806 | <li>-W SPEC - Specifies filters based on file names that should be in | ||
11807 | effect for the import. You can use this option multiple times. (See | ||
11808 | <a href="#cvswrappers">cvswrappers</a> in <a href="#Repository_Administrative_Files">Repository Administrative Files</a> for details | ||
11809 | about wrapper specs.) | ||
11810 | |||
11811 | </ul> | ||
11812 | |||
11813 | <p><hr> | ||
11814 | Node:<a name="init">init</a>, | ||
11815 | Next:<a rel=next href="#kserver">kserver</a>, | ||
11816 | Previous:<a rel=previous href="#import">import</a>, | ||
11817 | Up:<a rel=up href="#Commands_And_Options">Commands And Options</a> | ||
11818 | <br> | ||
11819 | |||
11820 | <h3>init</h3> | ||
11821 | |||
11822 | <p>Synopsis: init NEW_REPOSITORY | ||
11823 | |||
11824 | <ul> | ||
11825 | <li>Alternate names - None | ||
11826 | <li>Requires - Location for new repository | ||
11827 | <li>Creates - Repository | ||
11828 | </ul> | ||
11829 | |||
11830 | <p>Creates a new repository (that is, a root repository in which many | ||
11831 | different projects are stored). You will almost always want to use the | ||
11832 | global -d option with this, as in | ||
11833 | |||
11834 | <pre>floss$ cvs -d /usr/local/yet_another_repository init | ||
11835 | </pre> | ||
11836 | |||
11837 | <p>because even if you have a CVSROOT environment variable set, it's | ||
11838 | probably pointing to an existing repository, which would be useless and | ||
11839 | possibly dangerous in the context of this command. (See <a href="#Repository_Administration">Repository Administration</a> for additional steps that you should take after | ||
11840 | initializing a new repository.) | ||
11841 | |||
11842 | <p>Options: None. | ||
11843 | |||
11844 | <p><hr> | ||
11845 | Node:<a name="kserver">kserver</a>, | ||
11846 | Next:<a rel=next href="#log">log</a>, | ||
11847 | Previous:<a rel=previous href="#init">init</a>, | ||
11848 | Up:<a rel=up href="#Commands_And_Options">Commands And Options</a> | ||
11849 | <br> | ||
11850 | |||
11851 | <h3>kserver</h3> | ||
11852 | |||
11853 | <p>Synopsis: kserver | ||
11854 | |||
11855 | <p>This is the Kerberos server. (If you have Kerberos libraries Version 4 | ||
11856 | or below - Version 5 just uses GSSAPI, see <a href="#gserver">gserver</a>.) This | ||
11857 | command is not normally run directly by users but is instead started up | ||
11858 | on the server side when a user connects from a client with the | ||
11859 | <code>:kserver:</code> access method: | ||
11860 | |||
11861 | <pre>cvs -d :kserver:floss.red-bean.com:/usr/local/newrepos checkout myproj | ||
11862 | </pre> | ||
11863 | |||
11864 | <p>Setting up and using Kerberos on your machine is beyond the scope of | ||
11865 | this book. (However, see the node <cite>Kerberos Authenticated</cite> in the | ||
11866 | Cederqvist manual for some useful hints.) | ||
11867 | |||
11868 | <p>Options: None. | ||
11869 | |||
11870 | <p><hr> | ||
11871 | Node:<a name="log">log</a>, | ||
11872 | Next:<a rel=next href="#login">login</a>, | ||
11873 | Previous:<a rel=previous href="#kserver">kserver</a>, | ||
11874 | Up:<a rel=up href="#Commands_And_Options">Commands And Options</a> | ||
11875 | <br> | ||
11876 | |||
11877 | <h3>log</h3> | ||
11878 | |||
11879 | <p>Synopsis: log [OPTIONS] [FILES] | ||
11880 | |||
11881 | <ul> | ||
11882 | <li>Alternate names - lo, rlog | ||
11883 | <li>Requires - Working copy, repository | ||
11884 | <li>Changes - Nothing | ||
11885 | </ul> | ||
11886 | |||
11887 | <p>Shows log messages for a project, or for files within a project. The | ||
11888 | output of log is not quite in the same style as the output of other CVS | ||
11889 | commands, because log is based on an older RCS program (rlog). Its | ||
11890 | output format gives a header, containing various pieces of | ||
11891 | non-revision-specific information about the file, followed by the log | ||
11892 | messages (arranged by revision). Each revision shows not merely the | ||
11893 | revision number and log message, but also the author and date of the | ||
11894 | change and the number of lines added or deleted. All times are printed | ||
11895 | in UTC (GMT), not local time. | ||
11896 | |||
11897 | <p>Because log output is per file, a single commit involving multiple files | ||
11898 | may not immediately appear as a conceptually atomic change. However, if | ||
11899 | you read all of the log messages and dates carefully, you may be able to | ||
11900 | reconstruct what happened. (For information about a tool that can | ||
11901 | reformat multifile log output into a more readable form, see | ||
11902 | <a href="#cvs2cl_--_Generate_GNU-Style_ChangeLogs">cvs2cl - Generate GNU-Style ChangeLogs</a> in <a href="#Third-Party_Tools">Third-Party Tools</a> for details.) (See also <a href="#history">history</a>.) | ||
11903 | |||
11904 | <p>Options: | ||
11905 | |||
11906 | <p>As you read over the following filtering options, it may not be | ||
11907 | completely clear how they behave when combined. A precise description | ||
11908 | of log's behavior is that it takes the intersection of the revisions | ||
11909 | selected by -d, -s, and -w, intersected with the union of those selected | ||
11910 | by -b and -r. | ||
11911 | |||
11912 | <ul> | ||
11913 | |||
11914 | <li>-b - Prints log information about the default branch only (usually the | ||
11915 | highest branch on the trunk). This is usually done to avoid printing | ||
11916 | the log messages for side branches of development. | ||
11917 | |||
11918 | <li>-dDATES - Prints log information for only those revisions that match | ||
11919 | the date or date range given in DATES, a semicolon-separated list. | ||
11920 | Dates can be given in any of the usual date formats (see <a href="#Date_Formats">Date Formats</a> earlier in this section) and can be combined into ranges as | ||
11921 | follows: | ||
11922 | |||
11923 | <ul> | ||
11924 | |||
11925 | <li>DATE1<DATE2 - Selects revisions created between DATE1 and DATE2. If | ||
11926 | DATE1 is after DATE2, use <code>></code> instead; otherwise, no log messages | ||
11927 | are retrieved. | ||
11928 | |||
11929 | <li><DATE DATE> - All revisions from DATE or earlier. | ||
11930 | |||
11931 | <li>>DATE DATE< - All revisions from DATE or later. | ||
11932 | |||
11933 | <li>DATE - Just selects the most recent single revision from DATE or | ||
11934 | earlier. | ||
11935 | |||
11936 | </ul> | ||
11937 | |||
11938 | <p>You may use <code><=</code> and <code>>=</code> instead of <code><</code> and <code>></code> to | ||
11939 | indicate an inclusive range (otherwise, ranges are exclusive). Multiple | ||
11940 | ranges should be separated with semicolons, for example | ||
11941 | |||
11942 | <pre>floss$ cvs log -d"1999-06-01<1999-07-01;1999-08-01<1999-09-01" | ||
11943 | </pre> | ||
11944 | |||
11945 | <p>selects log messages for revisions committed in June or August of 1999 | ||
11946 | (skipping July). There can be no space between -d and its arguments. | ||
11947 | |||
11948 | </p><li>-h - Prints only the header information for each file, which includes | ||
11949 | the file name, working directory, head revision, default branch, access | ||
11950 | list, locks, symbolic names (tags), and the file's default keyword | ||
11951 | substitution mode. No log messages are printed. | ||
11952 | |||
11953 | <li>-l - Local. Runs only on files in the current working directory. | ||
11954 | |||
11955 | <li>-N - Omits the list of symbolic names (tags) from the header. This can | ||
11956 | be helpful when your project has a lot of tags but you're only | ||
11957 | interested in seeing the log messages. | ||
11958 | |||
11959 | <li>-R - Prints the name of the RCS file in the repository. | ||
11960 | |||
11961 | <p>This is different from the usual meaning of -R: "recursive". There's no | ||
11962 | way to override a -l for this command, so don't put log -l in your | ||
11963 | .cvsrc. | ||
11964 | |||
11965 | </p><li>-rREVS - Shows log information for the revisions specified in REVS, a | ||
11966 | comma-separated list. REVS can contain both revision numbers and tags. | ||
11967 | Ranges can be specified like this: | ||
11968 | |||
11969 | <ul> | ||
11970 | |||
11971 | <li>REV1:REV2 - Revisions from REV1 to REV2 (they must be on the same | ||
11972 | branch). | ||
11973 | |||
11974 | <li>:REV - Revisions from the start of REV's branch up to and including | ||
11975 | REV. | ||
11976 | |||
11977 | <li>REV: - Revisions from REV to the end of REV's branch. | ||
11978 | |||
11979 | <li>BRANCH - All revisions on that branch, from root to tip. | ||
11980 | |||
11981 | <li>BRANCH1:BRANCH2 - A range of branches - all revisions on all the | ||
11982 | branches in that range. | ||
11983 | |||
11984 | <li>BRANCH. - The latest (tip) revision on BRANCH. | ||
11985 | |||
11986 | </ul> | ||
11987 | |||
11988 | <p>Finally, a lone -r, with no argument, means select the latest revision | ||
11989 | on the default branch (normally the trunk). There can be no space | ||
11990 | between -r and its argument. | ||
11991 | |||
11992 | <p>If the argument to -r is a list, it is comma-separated, not | ||
11993 | semicolon-separated like -d. | ||
11994 | |||
11995 | </p><li>-sSTATES - Selects revisions whose state attribute matches one of the | ||
11996 | states given in STATES, a comma-separated list. There can be no space | ||
11997 | between -s and its argument. | ||
11998 | |||
11999 | <p>If the argument to -s is a list, it is comma-separated, not semicolon-separated like -d. | ||
12000 | |||
12001 | </p><li>-t - Like -h, but also includes the file's description (its creation | ||
12002 | message). | ||
12003 | |||
12004 | <li>-wUSERS - Selects revisions committed by users whose usernames appear | ||
12005 | in the comma-separated list USERS. A lone -w with no USERS means to | ||
12006 | take the username of the person running cvs log. | ||
12007 | |||
12008 | <p>Remember that when user aliasing is in effect (see the section <a href="#The_Password-Authenticating_Server">The Password-Authenticating Server</a> in <a href="#Repository_Administration">Repository Administration</a>), CVS | ||
12009 | records the CVS username, not the system username, with each commit. | ||
12010 | There can be no space between -w and its argument. | ||
12011 | |||
12012 | <p>If the argument to -w is a list, it is comma-separated, not | ||
12013 | semicolon-separated like -d. | ||
12014 | |||
12015 | </ul> | ||
12016 | |||
12017 | <p><hr> | ||
12018 | Node:<a name="login">login</a>, | ||
12019 | Next:<a rel=next href="#logout">logout</a>, | ||
12020 | Previous:<a rel=previous href="#log">log</a>, | ||
12021 | Up:<a rel=up href="#Commands_And_Options">Commands And Options</a> | ||
12022 | <br> | ||
12023 | |||
12024 | <h3>login</h3> | ||
12025 | |||
12026 | <p>Synopsis: login | ||
12027 | |||
12028 | <ul> | ||
12029 | <li>Alternate names - logon, lgn | ||
12030 | <li>Requires - Repository | ||
12031 | <li>Changes - ~/.cvspass file | ||
12032 | </ul> | ||
12033 | |||
12034 | <p>Contacts a CVS server and confirms authentication information for a | ||
12035 | particular repository. This command does not affect either the working | ||
12036 | copy or the repository; it just confirms a password (for use with the | ||
12037 | :pserver: access method) with a repository and stores the password for | ||
12038 | later use in the .cvspass file in your home directory. Future commands | ||
12039 | accessing the same repository with the same username will not require | ||
12040 | you to rerun login, because the client-side CVS will just consult the | ||
12041 | .cvspass file for the password. | ||
12042 | |||
12043 | <p>If you use this command, you should specify a repository using the | ||
12044 | pserver access method, like this | ||
12045 | |||
12046 | <pre>floss$ cvs -d :pserver:jrandom@floss.red-bean.com:/usr/local/newrepos | ||
12047 | </pre> | ||
12048 | |||
12049 | <p>or by setting the CVSROOT environment variable. | ||
12050 | |||
12051 | <p>If the password changes on the server side, you have to rerun login. | ||
12052 | |||
12053 | <p>Options: None. | ||
12054 | |||
12055 | <p><hr> | ||
12056 | Node:<a name="logout">logout</a>, | ||
12057 | Next:<a rel=next href="#pserver">pserver</a>, | ||
12058 | Previous:<a rel=previous href="#login">login</a>, | ||
12059 | Up:<a rel=up href="#Commands_And_Options">Commands And Options</a> | ||
12060 | <br> | ||
12061 | |||
12062 | <h3>logout</h3> | ||
12063 | |||
12064 | <p>Synopsis: logout | ||
12065 | |||
12066 | <ul> | ||
12067 | <li>Alternate names - None | ||
12068 | <li>Requires - ~/.cvspass file | ||
12069 | <li>Changes - ~/.cvspass file | ||
12070 | </ul> | ||
12071 | |||
12072 | <p>The opposite of login - removes the password for this repository from | ||
12073 | .cvspass. | ||
12074 | |||
12075 | <p>Options: None. | ||
12076 | |||
12077 | <p><hr> | ||
12078 | Node:<a name="pserver">pserver</a>, | ||
12079 | Next:<a rel=next href="#rdiff">rdiff</a>, | ||
12080 | Previous:<a rel=previous href="#logout">logout</a>, | ||
12081 | Up:<a rel=up href="#Commands_And_Options">Commands And Options</a> | ||
12082 | <br> | ||
12083 | |||
12084 | <h3>pserver</h3> | ||
12085 | |||
12086 | <p>Synopsis: pserver | ||
12087 | |||
12088 | <ul> | ||
12089 | <li>Alternate names - None | ||
12090 | <li>Requires - Repository | ||
12091 | <li>Changes - Nothing | ||
12092 | </ul> | ||
12093 | |||
12094 | <p>This is the password-authenticating server. This command is not | ||
12095 | normally run directly by users but is started up from | ||
12096 | <code>/etc/inetd.conf</code> on the server side when a user connects from a | ||
12097 | client with the <code>:pserver:</code> access method. (See also the | ||
12098 | <a href="#login">login</a> and <a href="#logout">logout</a> commands, and the file <code>.cvspass</code> in | ||
12099 | the <a href="#Run_Control_Files">Run Control Files</a> section in this chapter. See | ||
12100 | <a href="#Repository_Administration">Repository Administration</a> for details on setting up a | ||
12101 | password-authenticating CVS server.) | ||
12102 | |||
12103 | <p>Options: None. | ||
12104 | |||
12105 | <p><hr> | ||
12106 | Node:<a name="rdiff">rdiff</a>, | ||
12107 | Next:<a rel=next href="#release">release</a>, | ||
12108 | Previous:<a rel=previous href="#pserver">pserver</a>, | ||
12109 | Up:<a rel=up href="#Commands_And_Options">Commands And Options</a> | ||
12110 | <br> | ||
12111 | |||
12112 | <h3>rdiff</h3> | ||
12113 | |||
12114 | <p>Synopsis: rdiff [OPTIONS] PROJECTS | ||
12115 | |||
12116 | <ul> | ||
12117 | <li>Alternate names - patch, pa | ||
12118 | <li>Requires - Repository | ||
12119 | <li>Changes - Nothing | ||
12120 | </ul> | ||
12121 | |||
12122 | <p>Like the diff command, except it operates directly in the repository | ||
12123 | and, therefore, requires no working copy. This command is meant for | ||
12124 | obtaining the differences between one release and another of your | ||
12125 | project, in a format suitable as input to the patch program (perhaps so | ||
12126 | you can distribute patch files to users who want to upgrade). | ||
12127 | |||
12128 | <p>The operation of the patch program is beyond the scope of this book. | ||
12129 | However, note that if the patch file contains diffs for files in | ||
12130 | subdirectories, you may need to use the -p option to patch to get it to | ||
12131 | apply the differences correctly. (See the patch documentation for more | ||
12132 | about this.) (See also <a href="#diff">diff</a>.) | ||
12133 | |||
12134 | <p>Options: | ||
12135 | |||
12136 | <ul> | ||
12137 | |||
12138 | <li>-c - Prints output in context diff format (the default). | ||
12139 | |||
12140 | <li>-D DATE or -D DATE1 -D DATE2 - With one date, this shows the | ||
12141 | differences between the files as of DATE and the head revisions. With | ||
12142 | two dates, it shows the differences between the dates. | ||
12143 | |||
12144 | <li>-f - Forces the use of head revision if no matching revision is found | ||
12145 | for the -D or -r flag (otherwise, rdiff would just ignore the file). | ||
12146 | |||
12147 | <li>-l - Local. Won't descend into subdirectories. | ||
12148 | |||
12149 | <li>-R - Recursive. Descends into subdirectories (the default). You only | ||
12150 | specify this option to counteract a -l in your .cvsrc. | ||
12151 | |||
12152 | <li>-r REV -r REV1 -r REV2 - With one revision, this shows the differences | ||
12153 | between revision REV of the files and the head revisions. With two, it | ||
12154 | shows the differences between the revisions. | ||
12155 | |||
12156 | <li>-s - Displays a summary of differences. This shows which files have | ||
12157 | been added, modified, or removed, without showing changes in their | ||
12158 | content. The output looks like this: | ||
12159 | |||
12160 | <pre>floss$ cvs -Q rdiff -s -D 1999-08-20 myproj | ||
12161 | File myproj/Random.txt is new; current revision 1.4 | ||
12162 | File myproj/README.txt changed from revision 2.1 to 2.20 | ||
12163 | File myproj/baar is new; current revision 2.3 | ||
12164 | </pre> | ||
12165 | |||
12166 | <li>-t - Shows the diff between the top two revisions of each file. This | ||
12167 | is a handy shortcut for determining the most recent changes to a | ||
12168 | project. This option is incompatible with -D and -r. | ||
12169 | |||
12170 | <li>-u - Prints output in unidiff format. Older versions of patch can't | ||
12171 | handle unidiff format; therefore, don't use -u if you're trying to | ||
12172 | generate a distributable patch file - use -c instead. | ||
12173 | |||
12174 | <li>-V (Obsolete) - CVS reports an error if you try to use this option now. | ||
12175 | I've included it here only in case you see some old script trying to use | ||
12176 | it. | ||
12177 | |||
12178 | </ul> | ||
12179 | |||
12180 | <p><hr> | ||
12181 | Node:<a name="release">release</a>, | ||
12182 | Next:<a rel=next href="#remove">remove</a>, | ||
12183 | Previous:<a rel=previous href="#rdiff">rdiff</a>, | ||
12184 | Up:<a rel=up href="#Commands_And_Options">Commands And Options</a> | ||
12185 | <br> | ||
12186 | |||
12187 | <h3>release</h3> | ||
12188 | |||
12189 | <p>Synopsis: release [OPTIONS] DIRECTORY | ||
12190 | |||
12191 | <ul> | ||
12192 | <li>Alternate names - re, rel | ||
12193 | <li>Requires - Working copy | ||
12194 | <li>Changes - Working copy, CVSROOT/history | ||
12195 | </ul> | ||
12196 | |||
12197 | <p>Cancels a checkout (indicates that a working copy is no longer in use). | ||
12198 | Unlike most CVS commands that operate on a working copy, this one is not | ||
12199 | invoked from within the working copy but from directly above it (in its | ||
12200 | parent directory). You either have to set your CVSROOT environment | ||
12201 | variable or use the -d global option, as CVS will not be able to find | ||
12202 | out the repository from the working copy. | ||
12203 | |||
12204 | <p>Using release is never necessary. Because CVS doesn't normally do | ||
12205 | locking, you can just remove your working copy. | ||
12206 | |||
12207 | <p>However, if you have uncommitted changes in your working copy or you | ||
12208 | want your cessation of work to be noted in the CVSROOT/history file (see | ||
12209 | the history command), you should use release. CVS first checks for any | ||
12210 | uncommitted changes; if there are any, it warns you and prompts for | ||
12211 | continuation. Once the working copy is actually released, that fact is | ||
12212 | recorded in the repository's CVSROOT/history file. | ||
12213 | |||
12214 | <p>Options: | ||
12215 | |||
12216 | <ul> | ||
12217 | |||
12218 | <li>-d - Deletes the working copy if the release succeeds. Without -d, the | ||
12219 | working copy remains on disk after the release. | ||
12220 | |||
12221 | </ul> | ||
12222 | |||
12223 | <p>If you created any new directories inside your working copy but did not | ||
12224 | add them to the repository, they are deleted along with the rest of the | ||
12225 | working copy, if you specified the -d flag. | ||
12226 | |||
12227 | <p><hr> | ||
12228 | Node:<a name="remove">remove</a>, | ||
12229 | Next:<a rel=next href="#rtag">rtag</a>, | ||
12230 | Previous:<a rel=previous href="#release">release</a>, | ||
12231 | Up:<a rel=up href="#Commands_And_Options">Commands And Options</a> | ||
12232 | <br> | ||
12233 | |||
12234 | <h3>remove</h3> | ||
12235 | |||
12236 | <p>Synopsis: remove [OPTIONS] [FILES] | ||
12237 | |||
12238 | <ul> | ||
12239 | <li>Alternate names - rm, delete | ||
12240 | <li>Requires - Working copy | ||
12241 | <li>Changes - Working copy | ||
12242 | </ul> | ||
12243 | |||
12244 | <p>Removes a file from a project. Normally, the file itself is removed | ||
12245 | from disk when you invoke this command (but see -f). Although this | ||
12246 | command operates recursively by default, it is common to explicitly name | ||
12247 | the files being removed. Note the odd implication of the previous | ||
12248 | sentence: Usually, you run cvs remove on files that don't exist anymore | ||
12249 | in your working copy. | ||
12250 | |||
12251 | <p>Although the repository is contacted for confirmation, the file is not | ||
12252 | actually removed until a subsequent commit is performed. Even then, the | ||
12253 | RCS file is not really removed from the repository; if it is removed | ||
12254 | from the trunk, it is just moved into an Attic/ subdirectory, where it | ||
12255 | is still available to exist on branches. If it is removed from a | ||
12256 | branch, its location is not changed, but a new revision with state dead | ||
12257 | is added on the branch. (See also <a href="#add">add</a>.) | ||
12258 | |||
12259 | <p>Options: | ||
12260 | |||
12261 | <ul> | ||
12262 | |||
12263 | <li>-f - Force. Deletes the file from disk before removing it from CVS. | ||
12264 | This meaning differs from the usual meaning of -f in CVS commands: | ||
12265 | "Force to head revision". | ||
12266 | |||
12267 | <li>-l - Local. Runs only in current working directory. | ||
12268 | |||
12269 | <li>-R - Recursive. Descends into subdirectories (the default). This | ||
12270 | option exists only to counteract a -l in .cvsrc. | ||
12271 | |||
12272 | </ul> | ||
12273 | |||
12274 | <p><hr> | ||
12275 | Node:<a name="rtag">rtag</a>, | ||
12276 | Next:<a rel=next href="#server">server</a>, | ||
12277 | Previous:<a rel=previous href="#remove">remove</a>, | ||
12278 | Up:<a rel=up href="#Commands_And_Options">Commands And Options</a> | ||
12279 | <br> | ||
12280 | |||
12281 | <h3>rtag</h3> | ||
12282 | |||
12283 | <p>Synopsis: rtag [OPTIONS] TAG PROJECT(S) | ||
12284 | |||
12285 | <ul> | ||
12286 | <li>Alternate names - rt, rfreeze | ||
12287 | <li>Requires - Repository | ||
12288 | <li>Changes - Repository | ||
12289 | </ul> | ||
12290 | |||
12291 | <p>Tags a module directly in the repository (requires no working copy). | ||
12292 | You probably need to have your CVSROOT environment variable set or use | ||
12293 | the -d global option for this to work. (See also <a href="#tag">tag</a>.) | ||
12294 | |||
12295 | <p>Options: | ||
12296 | |||
12297 | <ul> | ||
12298 | |||
12299 | <li>-a - Clears the tag from any removed files, because removed files stay | ||
12300 | in the repository for historical purposes but are not considered part of | ||
12301 | the live project anymore. Although it's illegal to tag files with a tag | ||
12302 | name that's already in use, there should be no interference if the name | ||
12303 | is only used in removed files (which, from the current point of view of | ||
12304 | the project, don't exist anymore). | ||
12305 | |||
12306 | <li>-b - Creates a new branch, with branch name TAG. | ||
12307 | |||
12308 | <li>-D DATE - Tags the latest revisions no later than DATE. | ||
12309 | |||
12310 | <li>-d - Deletes the tag. No record is made of this change - the tag | ||
12311 | simply disappears. CVS does not keep a change history for tags. | ||
12312 | |||
12313 | <li>-F - Forces reassignment of the tag name, if it happens to exist | ||
12314 | already for some other revision in the file. | ||
12315 | |||
12316 | <li>-f - Forces to head revision if a given tag or date is not found. (See | ||
12317 | -r and -D.) | ||
12318 | |||
12319 | <li>-l - Local. Runs in the current directory only. | ||
12320 | |||
12321 | <li>-n - Won't execute a tag program from CVSROOT/modules. (See the section | ||
12322 | <a href="#Repository_Administrative_Files">Repository Administrative Files</a> later in this chapter for | ||
12323 | details about such programs.) | ||
12324 | |||
12325 | <li>-R - Recursive. Descends into subdirectories (the default). The -R | ||
12326 | option exists only to counteract a -l in .cvsrc. | ||
12327 | |||
12328 | <li>-r REV - Tags revision REV (which may itself be a tag name). | ||
12329 | |||
12330 | </ul> | ||
12331 | |||
12332 | <p><hr> | ||
12333 | Node:<a name="server">server</a>, | ||
12334 | Next:<a rel=next href="#status">status</a>, | ||
12335 | Previous:<a rel=previous href="#rtag">rtag</a>, | ||
12336 | Up:<a rel=up href="#Commands_And_Options">Commands And Options</a> | ||
12337 | <br> | ||
12338 | |||
12339 | <h3>server</h3> | ||
12340 | |||
12341 | <p>Synopsis: server | ||
12342 | |||
12343 | <p>Starts up a CVS server. This command is never invoked by users (unless | ||
12344 | they're trying to debug the client/server protocol), so forget I even | ||
12345 | mentioned it. | ||
12346 | |||
12347 | <p>Options: None. | ||
12348 | |||
12349 | <p><hr> | ||
12350 | Node:<a name="status">status</a>, | ||
12351 | Next:<a rel=next href="#tag">tag</a>, | ||
12352 | Previous:<a rel=previous href="#server">server</a>, | ||
12353 | Up:<a rel=up href="#Commands_And_Options">Commands And Options</a> | ||
12354 | <br> | ||
12355 | |||
12356 | <h3>status</h3> | ||
12357 | |||
12358 | <p>Synopsis: status [OPTIONS] [FILES] | ||
12359 | |||
12360 | <ul> | ||
12361 | <li>Alternate names - st, stat | ||
12362 | <li>Requires - Working copy | ||
12363 | <li>Changes - Nothing | ||
12364 | </ul> | ||
12365 | |||
12366 | <p>Shows the status of files in the working copy. | ||
12367 | |||
12368 | <p>Options: | ||
12369 | |||
12370 | <ul> | ||
12371 | |||
12372 | <li>-l - Local. Runs in the current directory only. | ||
12373 | |||
12374 | <li>-R - Recursive. Descends into subdirectories (the default). The -R | ||
12375 | option exists only to counteract a -l in .cvsrc. | ||
12376 | |||
12377 | <li>-v - Shows tag information for the file. | ||
12378 | |||
12379 | </ul> | ||
12380 | |||
12381 | <p><hr> | ||
12382 | Node:<a name="tag">tag</a>, | ||
12383 | Next:<a rel=next href="#unedit">unedit</a>, | ||
12384 | Previous:<a rel=previous href="#status">status</a>, | ||
12385 | Up:<a rel=up href="#Commands_And_Options">Commands And Options</a> | ||
12386 | <br> | ||
12387 | |||
12388 | <h3>tag</h3> | ||
12389 | |||
12390 | <p>Synopsis: tag [OPTIONS] TAG [FILES] | ||
12391 | |||
12392 | <ul> | ||
12393 | <li>Alternate names - ta, freeze | ||
12394 | <li>Requires - Working copy, repository | ||
12395 | <li>Changes - Repository | ||
12396 | </ul> | ||
12397 | |||
12398 | <p>Attaches a name to a particular revision or collection of revisions for | ||
12399 | a project. Often called "taking a snapshot" of the project. This | ||
12400 | command is also used to create branches in CVS. (See the -b option - | ||
12401 | see also <a href="#rtag">rtag</a>.) | ||
12402 | |||
12403 | <p>Options: | ||
12404 | |||
12405 | <ul> | ||
12406 | |||
12407 | <li>-b - Creates a branch named TAG. | ||
12408 | |||
12409 | <li>-c - Checks that the working copy has no uncommitted changes. If it | ||
12410 | does, the command exits with a warning, and no tag is made. | ||
12411 | |||
12412 | <li>-D DATE - Tags the latest revisions no later than DATE. | ||
12413 | |||
12414 | <li>-d - Deletes the tag. No record is made of this change; the tag simply | ||
12415 | disappears. CVS does not keep a change history for tags. | ||
12416 | |||
12417 | <li>-F - Forces reassignment of the tag name, if it happens to exist | ||
12418 | already for some other revision in the file. | ||
12419 | |||
12420 | <li>-f - Forces to head revision if a given tag or date is not found. (See | ||
12421 | -r and -D.) | ||
12422 | |||
12423 | <li>-l - Local. Runs in the current directory only. | ||
12424 | |||
12425 | <li>-R - Recursive. Descends into subdirectories (the default). The -R | ||
12426 | option exists only to counteract a -l in .cvsrc. | ||
12427 | |||
12428 | <li>-r REV - Tags revision REV (which may itself be a tag name). | ||
12429 | |||
12430 | </ul> | ||
12431 | |||
12432 | <p><hr> | ||
12433 | Node:<a name="unedit">unedit</a>, | ||
12434 | Next:<a rel=next href="#update">update</a>, | ||
12435 | Previous:<a rel=previous href="#tag">tag</a>, | ||
12436 | Up:<a rel=up href="#Commands_And_Options">Commands And Options</a> | ||
12437 | <br> | ||
12438 | |||
12439 | <h3>unedit</h3> | ||
12440 | |||
12441 | <p>Synopsis: unedit [OPTIONS] [FILES] | ||
12442 | |||
12443 | <ul> | ||
12444 | <li>Alternate names - None | ||
12445 | <li>Requires - Working copy, repository | ||
12446 | <li>Changes - edit/watch lists in the repository | ||
12447 | </ul> | ||
12448 | |||
12449 | <p>Signals to watchers that you are done editing a file. (See also | ||
12450 | <a href="#watch">watch</a>, <a href="#watchers">watchers</a>, <a href="#edit">edit</a>, and <a href="#editors">editors</a>.) | ||
12451 | |||
12452 | <p>Options: | ||
12453 | |||
12454 | <ul> | ||
12455 | |||
12456 | <li>-l - Local. Signals editing for files in the current working directory | ||
12457 | only. | ||
12458 | |||
12459 | <li>-R - Recursive (opposite of -l). Recursive is the default; the only | ||
12460 | reason to pass -R is to counteract a -l in your .cvsrc file. | ||
12461 | |||
12462 | </ul> | ||
12463 | |||
12464 | <p><hr> | ||
12465 | Node:<a name="update">update</a>, | ||
12466 | Next:<a rel=next href="#watch">watch</a>, | ||
12467 | Previous:<a rel=previous href="#unedit">unedit</a>, | ||
12468 | Up:<a rel=up href="#Commands_And_Options">Commands And Options</a> | ||
12469 | <br> | ||
12470 | |||
12471 | <h3>update</h3> | ||
12472 | |||
12473 | <p>Synopsis: update [OPTIONS] [FILES] | ||
12474 | |||
12475 | <ul> | ||
12476 | <li>Alternate names - up, upd | ||
12477 | <li>Requires - Working copy, repository | ||
12478 | <li>Changes - Working copy | ||
12479 | </ul> | ||
12480 | |||
12481 | <p>Merges changes from the repository into your working copy. As a side | ||
12482 | effect, it indicates which files in your working copy are modified (but | ||
12483 | if the -Q global option is passed, these indications won't be printed). | ||
12484 | (See also <a href="#checkout">checkout</a>.) | ||
12485 | |||
12486 | <p>Options: | ||
12487 | |||
12488 | <ul> | ||
12489 | |||
12490 | <li>-A - Clears any sticky tags, sticky dates, or sticky RCS keyword | ||
12491 | expansion modes. This may result in the contents of files changing, if | ||
12492 | the trunk-head revisions are different from the former sticky revisions. | ||
12493 | (Think of -A as being like a fresh checkout of the project trunk.) | ||
12494 | |||
12495 | <li>-C - Clean out any locally changed files and replace them with the | ||
12496 | latest versions from the repository. This is not necessarily the same | ||
12497 | as reverting the files, since the repository may have changed since the | ||
12498 | last update or checkout. Any local modifications are saved in | ||
12499 | <code>.#file.rev</code>. | ||
12500 | |||
12501 | <p>Note: this option was implemented in January 2000; if your CVS was | ||
12502 | acquired before then, you'd have to upgrade. | ||
12503 | |||
12504 | </p><li>-D DATE - Updates to the most recent revisions no later than DATE. | ||
12505 | This option is sticky and implies -P. If the working copy has a sticky | ||
12506 | date, commits are not possible. | ||
12507 | |||
12508 | <li>-d - Retrieves absent directories - that is, directories that exist in | ||
12509 | the repository but not yet in the working copy. Such directories may | ||
12510 | have been created in the repository after the working copy was checked | ||
12511 | out. Without this option, update only operates on the directories | ||
12512 | present in the working copy; new files are brought down from the | ||
12513 | repository, but new directories are not. (See also -P.) | ||
12514 | |||
12515 | <li>-f - Forces to head revision if no matching revision is found with the | ||
12516 | -D or -r flags. | ||
12517 | |||
12518 | <li>-I NAME - Like the -I option of import. | ||
12519 | |||
12520 | <li>-j REV[:DATE] or -j REV1[:DATE] -j REV2[:DATE] - Joins, or merges, two | ||
12521 | lines of development. Ignoring the optional DATE arguments for the | ||
12522 | moment (we'll get to them later), here's how -j works: If only one -j is | ||
12523 | given, it takes all changes from the common ancestor to REV and merges | ||
12524 | them into the working copy. The <dfn>common ancestor</dfn> is the latest | ||
12525 | revision that is ancestral to both the revisions in the working | ||
12526 | directory and to REV. If two -j options are given, it merges the | ||
12527 | changes from REV1 to REV2 into the working copy. | ||
12528 | |||
12529 | <p>The special tags HEAD and BASE may be used as arguments to -j; they mean | ||
12530 | the most recent revision in the repository, and the revision on which | ||
12531 | the current working copy file is based, respectively. | ||
12532 | |||
12533 | <p>As for the optional DATE arguments, if REV is a branch, it is normally | ||
12534 | taken to mean the latest revision on that branch, but you can restrict | ||
12535 | it to the latest revision no later than DATE. The date should be | ||
12536 | separated from the revision by a colon, with no spaces, for instance: | ||
12537 | |||
12538 | <pre>floss$ cvs update -j ABranch:1999-07-01 -j ABranch:1999-08-01 | ||
12539 | </pre> | ||
12540 | |||
12541 | <p>In this example, different dates on the same branch are used, so the | ||
12542 | effect is to take the changes on that branch from July to August and | ||
12543 | merge them into the working copy. However, note that there is no | ||
12544 | requirement that the branch be the same in both -j options. | ||
12545 | |||
12546 | </p><li>-k MODE - Does RCS keyword substitution according to MODE. (See the | ||
12547 | section <a href="#Keyword_Substitution__RCS_Keywords_">Keyword Substitution (RCS Keywords)</a> later in this | ||
12548 | chapter.) The mode remains sticky on the working copy, so it will | ||
12549 | affect future updates (but see -A). | ||
12550 | |||
12551 | <li>-l - Local. Updates the current directory only. | ||
12552 | |||
12553 | <li>-P - Prunes empty directories. Any CVS-controlled directory that | ||
12554 | contains no files at the end of the update are removed from the working | ||
12555 | copy. (See also -d.) | ||
12556 | |||
12557 | <li>-p - Sends file contents to standard output instead of to the files. | ||
12558 | Used mainly for reverting to a previous revision without producing | ||
12559 | sticky tags in the working copy. For example: | ||
12560 | |||
12561 | <pre>floss$ cvs update -p -r 1.3 README.txt > README.txt | ||
12562 | </pre> | ||
12563 | |||
12564 | <p>Now README.txt in the working copy has the contents of its past Revision | ||
12565 | 1.3, just as if you had hand-edited it into that state. | ||
12566 | |||
12567 | </p><li>-R - Recursive. Descends into subdirectories to update (the default). | ||
12568 | The only reason you'd specify it is to counteract a -l in .cvsrc. | ||
12569 | |||
12570 | <li>-r REV - Updates (or downdates, or crossdates) to revision REV. When | ||
12571 | updating a whole working copy, REV is most often a tag (regular or | ||
12572 | branch). However, when updating an individual file, it is just as | ||
12573 | likely to be a revision number as a tag. | ||
12574 | |||
12575 | <p>This option is sticky. If the files are switched to a nonbranch tag or | ||
12576 | sticky revision, they cannot be committed until the stickiness is | ||
12577 | removed. (See -A.) If REV was a branch tag, however, commits are | ||
12578 | possible. They'll simply commit new revisions on that branch. | ||
12579 | |||
12580 | </p><li>-WSPEC - Specifies wrapper-style filters to use during the update. You | ||
12581 | can use this option multiple times. (See <a href="#cvswrappers">cvswrappers</a> in | ||
12582 | <a href="#Repository_Administrative_Files">Repository Administrative Files</a> in this chapter for details about | ||
12583 | wrapper specs.) There is no space between -W and its argument. | ||
12584 | |||
12585 | </ul> | ||
12586 | |||
12587 | <p><hr> | ||
12588 | Node:<a name="watch">watch</a>, | ||
12589 | Next:<a rel=next href="#watchers">watchers</a>, | ||
12590 | Previous:<a rel=previous href="#update">update</a>, | ||
12591 | Up:<a rel=up href="#Commands_And_Options">Commands And Options</a> | ||
12592 | <br> | ||
12593 | |||
12594 | <h3>watch</h3> | ||
12595 | |||
12596 | <p>Synopsis: watch on|off|add|remove [OPTIONS] [FILES] | ||
12597 | |||
12598 | <ul> | ||
12599 | <li>Alternate names - None | ||
12600 | <li>Requires - Working copy, repository | ||
12601 | <li>Changes - Watch list in repository | ||
12602 | </ul> | ||
12603 | |||
12604 | <p>Sets a watch on one or more files. Unlike most CVS commands, watch | ||
12605 | requires a further subcommand to do something useful. (See also | ||
12606 | <a href="#watchers">watchers</a>, <a href="#edit">edit</a>, <a href="#editors">editors</a>, and <a href="#unedit">unedit</a>, and | ||
12607 | <a href="#users">users</a>.) | ||
12608 | |||
12609 | <p>Subcommands: | ||
12610 | |||
12611 | <ul> | ||
12612 | |||
12613 | <li>on - Declares that the files are being watched. This means that they | ||
12614 | are created read-only on checkout, and users should do cvs edit to make | ||
12615 | them read-write (and notify any watchers that the file is now being | ||
12616 | edited). Turning on a watch does not add you to the watch list for any | ||
12617 | files. (See <code>watch add</code> and <code>watch remove</code> for that.) | ||
12618 | |||
12619 | <li>off - Opposite of watch on. Declares that the files are no longer | ||
12620 | being watched. | ||
12621 | |||
12622 | <li>add - Adds you to the list of watchers for this file. You are notified | ||
12623 | when someone commits or runs cvs edit or cvs unedit (but see the -a | ||
12624 | option). | ||
12625 | |||
12626 | <li>remove - Opposite of watch add. Removes you from the list of watchers | ||
12627 | for this file. | ||
12628 | |||
12629 | </ul> | ||
12630 | |||
12631 | <p>Options (for use with any watch subcommand). All three options have the | ||
12632 | same meanings as for edit: | ||
12633 | |||
12634 | <ul> | ||
12635 | |||
12636 | <li>-a ACTIONS | ||
12637 | |||
12638 | <li>-l | ||
12639 | |||
12640 | <li>-R | ||
12641 | |||
12642 | </ul> | ||
12643 | |||
12644 | <p><hr> | ||
12645 | Node:<a name="watchers">watchers</a>, | ||
12646 | Previous:<a rel=previous href="#watch">watch</a>, | ||
12647 | Up:<a rel=up href="#Commands_And_Options">Commands And Options</a> | ||
12648 | <br> | ||
12649 | |||
12650 | <h3>watchers</h3> | ||
12651 | |||
12652 | <p>Synopsis: watchers [OPTIONS] [FILES] | ||
12653 | |||
12654 | <ul> | ||
12655 | <li>Alternate names - None | ||
12656 | <li>Requires - Working copy, repository | ||
12657 | <li>Changes - Nothing | ||
12658 | </ul> | ||
12659 | |||
12660 | <p>Shows who's watching what files. | ||
12661 | |||
12662 | <p>Options - these options mean the same thing here as for <a href="#edit">edit</a>: | ||
12663 | |||
12664 | <ul> | ||
12665 | |||
12666 | <li>-l | ||
12667 | |||
12668 | <li>-R | ||
12669 | |||
12670 | </ul> | ||
12671 | |||
12672 | <p><hr> | ||
12673 | Node:<a name="Keyword_Substitution__RCS_Keywords_">Keyword Substitution (RCS Keywords)</a>, | ||
12674 | Next:<a rel=next href="#Repository_Administrative_Files">Repository Administrative Files</a>, | ||
12675 | Previous:<a rel=previous href="#Commands_And_Options">Commands And Options</a>, | ||
12676 | Up:<a rel=up href="#CVS_Reference">CVS Reference</a> | ||
12677 | <br> | ||
12678 | |||
12679 | <h2>Keyword Substitution (RCS Keywords)</h2> | ||
12680 | |||
12681 | <p>CVS can perform certain textual substitutions in files, allowing you to | ||
12682 | keep some kinds of information automatically up to date in your files. | ||
12683 | All of the substitutions are triggered by a certain keyword pattern, | ||
12684 | surrounded by dollar signs. For example, | ||
12685 | |||
12686 | <pre>$Revision$ | ||
12687 | </pre> | ||
12688 | |||
12689 | <p>in a file expands to something like | ||
12690 | |||
12691 | <pre>$Revision$ | ||
12692 | </pre> | ||
12693 | |||
12694 | <p>and CVS continues to keep the revision string up to date as new | ||
12695 | revisions are committed. | ||
12696 | |||
12697 | <ul> | ||
12698 | <li><a href="#Controlling_Keyword_Expansion">Controlling Keyword Expansion</a>: How to use keywords in your files. | ||
12699 | <li><a href="#List_Of_Keywords">List Of Keywords</a>: All the keywords. | ||
12700 | </ul> | ||
12701 | |||
12702 | <p><hr> | ||
12703 | Node:<a name="Controlling_Keyword_Expansion">Controlling Keyword Expansion</a>, | ||
12704 | Next:<a rel=next href="#List_Of_Keywords">List Of Keywords</a>, | ||
12705 | Up:<a rel=up href="#Keyword_Substitution__RCS_Keywords_">Keyword Substitution (RCS Keywords)</a> | ||
12706 | <br> | ||
12707 | |||
12708 | <h3>Controlling Keyword Expansion</h3> | ||
12709 | |||
12710 | <p>By default, CVS performs keyword expansion unless you tell it to stop. | ||
12711 | You can permanently suppress keyword expansion for a file with the -k | ||
12712 | option when you add the file to the project, or you can turn it off | ||
12713 | later by invoking admin with -k. The -k option offers several different | ||
12714 | modes of keyword control; usually you want mode o or b, for example: | ||
12715 | |||
12716 | <pre>floss$ cvs add -ko chapter-9.sgml | ||
12717 | </pre> | ||
12718 | |||
12719 | <p>This command added <code>chapter-9.sgml</code> to the project with keyword | ||
12720 | expansion turned off. It sets the file's default keyword expansion mode | ||
12721 | to <code>o</code>, which means no substitution. (Actually, the "o" stands for | ||
12722 | "old", meaning to substitute the string with its old value, which is the | ||
12723 | same as substituting it for itself, resulting in no change. I'm sure | ||
12724 | this logic made sense to somebody at the time.) | ||
12725 | |||
12726 | <p>Each file's default keyword mode is stored in the repository. However, | ||
12727 | each working copy can also have its own local keyword substitution mode | ||
12728 | - accomplished with the -k options to checkout or update. You can also | ||
12729 | have a mode in effect for the duration of just one command, with the -k | ||
12730 | option to diff. | ||
12731 | |||
12732 | <p>Here are all the possible modes, presented with the -k option prepended | ||
12733 | (as one would type at a command line). Any of these options can be used | ||
12734 | as either the default or local keyword substitution mode for a file: | ||
12735 | |||
12736 | <ul> | ||
12737 | |||
12738 | <li>-kkv - Expands to keyword and value. This is the default keyword | ||
12739 | expansion mode, so you don't need to set it for new files. You might | ||
12740 | use it to change a file from another keyword mode, however. | ||
12741 | |||
12742 | <li>-kkvl - Like -kkv, but includes the locker's name if the revision is | ||
12743 | currently locked. (See the -l option to admin for more on this.) | ||
12744 | |||
12745 | <li>-kk - Won't expand values in keyword strings, just uses the keyword | ||
12746 | name. For example, with this option, | ||
12747 | |||
12748 | <pre>$Revision$ | ||
12749 | </pre> | ||
12750 | |||
12751 | <p>and | ||
12752 | |||
12753 | <pre>$Revision$ | ||
12754 | </pre> | ||
12755 | |||
12756 | <p>would both "expand" (okay, contract) to: | ||
12757 | |||
12758 | <pre>$Revision$ | ||
12759 | </pre> | ||
12760 | |||
12761 | </p><li>-ko - Reuses the keyword string found in the file (hence "o" for | ||
12762 | "old"), as it was in the working file just before the commit. | ||
12763 | |||
12764 | <li>-kb - Like -ko, but also suppresses interplatform line-end conversions. | ||
12765 | The "b" stands for "binary"; it is the mode you should use for binary | ||
12766 | files. | ||
12767 | |||
12768 | <li>-kv - Substitutes the keyword with its value, for example | ||
12769 | |||
12770 | <pre>$Revision$ | ||
12771 | </pre> | ||
12772 | |||
12773 | <p>might become: | ||
12774 | |||
12775 | <pre>1.5 | ||
12776 | </pre> | ||
12777 | |||
12778 | <p>Of course, after that's happened once, future substitutions will not | ||
12779 | take place, so this option should be used with care. | ||
12780 | |||
12781 | </ul> | ||
12782 | |||
12783 | <p><hr> | ||
12784 | Node:<a name="List_Of_Keywords">List Of Keywords</a>, | ||
12785 | Previous:<a rel=previous href="#Controlling_Keyword_Expansion">Controlling Keyword Expansion</a>, | ||
12786 | Up:<a rel=up href="#Keyword_Substitution__RCS_Keywords_">Keyword Substitution (RCS Keywords)</a> | ||
12787 | <br> | ||
12788 | |||
12789 | <h3>List Of Keywords</h3> | ||
12790 | |||
12791 | <p>These are all the dollar-sign-delimited keywords that CVS recognizes. | ||
12792 | Following is a list of the keyword, a brief description, and an example | ||
12793 | of its expanded form: | ||
12794 | |||
12795 | <ul> | ||
12796 | |||
12797 | <li>$Author$ - Author of the change: | ||
12798 | |||
12799 | <pre>$Author$ | ||
12800 | </pre> | ||
12801 | |||
12802 | <li>$Date$ - The date and time of the change, in UTC (GMT): | ||
12803 | |||
12804 | <pre>$Date$ | ||
12805 | </pre> | ||
12806 | |||
12807 | <li>$Header$ - Various pieces of information thought to be useful: full | ||
12808 | path to the RCS file in the repository, revision, date (in UTC), author, | ||
12809 | state, and locker. (Lockers are rare; although in the following example, | ||
12810 | qsmith has a lock.): | ||
12811 | |||
12812 | <pre>$Header: /usr/local/newrepos/myproj/hello.c,v 1.1 1999/06/01 \ | ||
12813 | 03:21:13 jrandom Exp qsmith $ | ||
12814 | </pre> | ||
12815 | |||
12816 | <li>$Id$ - Like $Header$, but without the full path to the RCS file: | ||
12817 | |||
12818 | <pre>$Id$ | ||
12819 | </pre> | ||
12820 | |||
12821 | <li>$Log$ | ||
12822 | <li>Revision 1.1 2002/06/23 14:32:50 llornkcor | ||
12823 | <li>some dev docs | ||
12824 | <li> - The log message of this revision, along with the revision | ||
12825 | number, date, and author. Unlike other keywords, the previous | ||
12826 | expansions are not replaced. Instead, they are pushed down, so that the | ||
12827 | newest expansion appears at the top of an ever-growing stack of $Log$ | ||
12828 | newest expansion appears at the top of an ever-growing stack of Revision 1.1 2002/06/23 14:32:50 llornkcor | ||
12829 | newest expansion appears at the top of an ever-growing stack of some dev docs | ||
12830 | newest expansion appears at the top of an ever-growing stack of | ||
12831 | messages: | ||
12832 | |||
12833 | <pre>$Log$ | ||
12834 | <pre>Revision 1.1 2002/06/23 14:32:50 llornkcor | ||
12835 | <pre>some dev docs | ||
12836 | <pre> Revision 1.12 1999/07/19 06:12:43 jrandom | ||
12837 | say hello in Aramaic | ||
12838 | </pre> | ||
12839 | |||
12840 | <p>Any text preceding the $Log$ | ||
12841 | <p>Any text preceding the Revision 1.1 2002/06/23 14:32:50 llornkcor | ||
12842 | <p>Any text preceding the some dev docs | ||
12843 | <p>Any text preceding the keyword on the same line will be prepended to the downward expansions too; this is so that if you use it in a comment in a program source file, all of the expansion is commented, too. | ||
12844 | |||
12845 | </p><li>$Locker$ - Name of the person who has a lock on this revision (usually | ||
12846 | no one): | ||
12847 | |||
12848 | <pre>$Locker$ | ||
12849 | </pre> | ||
12850 | |||
12851 | <li>$Name$ - Name of the sticky tag: | ||
12852 | |||
12853 | <pre>$Name$ | ||
12854 | </pre> | ||
12855 | |||
12856 | <li>$RCSfile$ - Name of the RCS file in the repository: | ||
12857 | |||
12858 | <pre>$RCSfile$ | ||
12859 | </pre> | ||
12860 | |||
12861 | <li>$Revision$ - Revision number: | ||
12862 | |||
12863 | <pre>$Revision$ | ||
12864 | </pre> | ||
12865 | |||
12866 | <li>$Source$ - Full path to the RCS file in the repository: | ||
12867 | |||
12868 | <pre>$Source$ | ||
12869 | </pre> | ||
12870 | |||
12871 | <li>$State$ - State of this revision: | ||
12872 | |||
12873 | <pre>$State$ | ||
12874 | </pre> | ||
12875 | |||
12876 | </ul> | ||
12877 | |||
12878 | <p><hr> | ||
12879 | Node:<a name="Repository_Administrative_Files">Repository Administrative Files</a>, | ||
12880 | Next:<a rel=next href="#Run_Control_Files">Run Control Files</a>, | ||
12881 | Previous:<a rel=previous href="#Keyword_Substitution__RCS_Keywords_">Keyword Substitution (RCS Keywords)</a>, | ||
12882 | Up:<a rel=up href="#CVS_Reference">CVS Reference</a> | ||
12883 | <br> | ||
12884 | |||
12885 | <h2>Repository Administrative Files</h2> | ||
12886 | |||
12887 | <p>The repository's administrative files are stored in the CVSROOT | ||
12888 | subdirectory of the repository. These files control various aspects of | ||
12889 | CVS's behavior (in that repository only, of course). | ||
12890 | |||
12891 | <p>You may also want to refer to the discussion of administrative files in | ||
12892 | <a href="#Repository_Administration">Repository Administration</a>, which includes examples. | ||
12893 | |||
12894 | <ul> | ||
12895 | <li><a href="#Storage_And_Editing">Storage And Editing</a>: How to make changes to the administrative files. | ||
12896 | <li><a href="#Shared_Syntax">Shared Syntax</a>: Most administrative files share a common syntax. | ||
12897 | <li><a href="#Shared_Variables">Shared Variables</a>: Some administrative files can expand variables. | ||
12898 | <li><a href="#User_Variables">User Variables</a>: How to expand run-time variables set by users. | ||
12899 | <li><a href="#checkoutlist">checkoutlist</a>: The <code>checkoutlist</code> file. | ||
12900 | <li><a href="#commitinfo">commitinfo</a>: The <code>commitinfo</code> file. | ||
12901 | <li><a href="#config">config</a>: The <code>config</code> file. | ||
12902 | <li><a href="#cvsignore">cvsignore</a>: The <code>cvsignore</code> file. | ||
12903 | <li><a href="#cvswrappers">cvswrappers</a>: The <code>cvswrappers</code> file. | ||
12904 | <li><a href="#editinfo">editinfo</a>: The <code>editinfo</code> file. | ||
12905 | <li><a href="#history_file">history file</a>: The <code>history</code> file. | ||
12906 | <li><a href="#loginfo">loginfo</a>: The <code>loginfo</code> file. | ||
12907 | <li><a href="#modules">modules</a>: The <code>modules</code> file. | ||
12908 | <li><a href="#notify">notify</a>: The <code>notify</code> file. | ||
12909 | <li><a href="#passwd">passwd</a>: The <code>passwd</code> file. | ||
12910 | <li><a href="#rcsinfo">rcsinfo</a>: The <code>rcsinfo</code> file. | ||
12911 | <li><a href="#taginfo">taginfo</a>: The <code>taginfo</code> file. | ||
12912 | <li><a href="#users">users</a>: The <code>users</code> file. | ||
12913 | <li><a href="#val-tags">val-tags</a>: The <code>val-tags</code> file. | ||
12914 | <li><a href="#verifymsg">verifymsg</a>: The <code>verifymsg</code> file. | ||
12915 | </ul> | ||
12916 | |||
12917 | <p><hr> | ||
12918 | Node:<a name="Storage_And_Editing">Storage And Editing</a>, | ||
12919 | Next:<a rel=next href="#Shared_Syntax">Shared Syntax</a>, | ||
12920 | Up:<a rel=up href="#Repository_Administrative_Files">Repository Administrative Files</a> | ||
12921 | <br> | ||
12922 | |||
12923 | <h3>Storage And Editing</h3> | ||
12924 | |||
12925 | <p>Generally, the administrative files are kept under revision control just | ||
12926 | like any other file in the repository (the exceptions are noted). | ||
12927 | However, unlike other files, checked-out copies of the administrative | ||
12928 | files are stored in the repository, right next to their corresponding | ||
12929 | RCS files in the <code>CVSROOT</code> subdirectory. It is these checked-out | ||
12930 | copies which actually govern CVS's behavior. | ||
12931 | |||
12932 | <p>The normal way to modify the administrative files is to check out a | ||
12933 | working copy of the CVSROOT module, make your changes, and commit. CVS | ||
12934 | updates the checked-out copies in the repository automatically. (See | ||
12935 | <a href="#checkoutlist">checkoutlist</a>.) In an emergency, however, it is also possible to | ||
12936 | edit the checked-out copies in the repository directly. | ||
12937 | |||
12938 | <p><hr> | ||
12939 | Node:<a name="Shared_Syntax">Shared Syntax</a>, | ||
12940 | Next:<a rel=next href="#Shared_Variables">Shared Variables</a>, | ||
12941 | Previous:<a rel=previous href="#Storage_And_Editing">Storage And Editing</a>, | ||
12942 | Up:<a rel=up href="#Repository_Administrative_Files">Repository Administrative Files</a> | ||
12943 | <br> | ||
12944 | |||
12945 | <h3>Shared Syntax</h3> | ||
12946 | |||
12947 | <p>In all of the administrative files, a <code>#</code> at the beginning of a line | ||
12948 | signifies a comment; that line is ignored by CVS. A backslash preceding | ||
12949 | a newline quotes the newline out of existence. | ||
12950 | |||
12951 | <p>Some of the files (commitinfo, loginfo, taginfo, and rcsinfo) share more | ||
12952 | syntactic conventions as well. In these files, on the left of each line | ||
12953 | is a regular expression (which is matched against a file or directory | ||
12954 | name), and the rest of the line is a program, possibly with arguments, | ||
12955 | which is invoked if something is done to a file matching the regular | ||
12956 | expression. The program is run with its working directory set to the | ||
12957 | top of the repository. | ||
12958 | |||
12959 | <p>In these files, there are two special regular expressions that may be | ||
12960 | used: ALL and DEFAULT. ALL matches any file or directory, whether or | ||
12961 | not there is some other match for it, and DEFAULT matches only if | ||
12962 | nothing else matched. | ||
12963 | |||
12964 | <p><hr> | ||
12965 | Node:<a name="Shared_Variables">Shared Variables</a>, | ||
12966 | Next:<a rel=next href="#User_Variables">User Variables</a>, | ||
12967 | Previous:<a rel=previous href="#Shared_Syntax">Shared Syntax</a>, | ||
12968 | Up:<a rel=up href="#Repository_Administrative_Files">Repository Administrative Files</a> | ||
12969 | <br> | ||
12970 | |||
12971 | <h3>Shared Variables</h3> | ||
12972 | |||
12973 | <p>The info files also allow certain variables to be expanded at runtime. | ||
12974 | To expand a variable, precede it with a dollar sign (and put it in curly | ||
12975 | braces just to be safe). Here are the variables CVS knows about: | ||
12976 | |||
12977 | <ul> | ||
12978 | |||
12979 | <li>${CVSROOT} - The top of the repository. | ||
12980 | |||
12981 | <li>${RCSBIN} - (Obsolete) Don't use this variable. It is only | ||
12982 | applicable in CVS Version 1.9.18 and older. Specifying it now may | ||
12983 | result in an error. | ||
12984 | |||
12985 | <li>${CVSEDITOR} ${VISUAL} ${EDITOR} - These all expand to the editor | ||
12986 | that CVS is using for a log message. | ||
12987 | |||
12988 | <li>${USER} - The user running CVS (on the server side). | ||
12989 | |||
12990 | </ul> | ||
12991 | |||
12992 | <p><hr> | ||
12993 | Node:<a name="User_Variables">User Variables</a>, | ||
12994 | Next:<a rel=next href="#checkoutlist">checkoutlist</a>, | ||
12995 | Previous:<a rel=previous href="#Shared_Variables">Shared Variables</a>, | ||
12996 | Up:<a rel=up href="#Repository_Administrative_Files">Repository Administrative Files</a> | ||
12997 | <br> | ||
12998 | |||
12999 | <h3>User Variables</h3> | ||
13000 | |||
13001 | <p>Users can also set their own variables when they run any CVS | ||
13002 | command. (See the -s global option.) These variables can be accessed | ||
13003 | in the <code>*info</code> files by preceding them with an equal sign, as in | ||
13004 | ${=VAR}. | ||
13005 | |||
13006 | <p><hr> | ||
13007 | Node:<a name="checkoutlist">checkoutlist</a>, | ||
13008 | Next:<a rel=next href="#commitinfo">commitinfo</a>, | ||
13009 | Previous:<a rel=previous href="#User_Variables">User Variables</a>, | ||
13010 | Up:<a rel=up href="#Repository_Administrative_Files">Repository Administrative Files</a> | ||
13011 | <br> | ||
13012 | |||
13013 | <h3>checkoutlist</h3> | ||
13014 | |||
13015 | <p>This contains a list of files for which checked-out copies should be | ||
13016 | kept in the repository. Each line gives the file name and an error | ||
13017 | message for CVS to print if, for some reason, the file cannot be checked | ||
13018 | out in the repository: | ||
13019 | |||
13020 | <pre>FILENAME ERROR_MESSAGE | ||
13021 | </pre> | ||
13022 | |||
13023 | <p>Because CVS already knows to keep checked-out copies of the existing | ||
13024 | administrative files, they do not need to be listed in checkoutlist. | ||
13025 | Specifically, the following files never need entries in checkoutlist: | ||
13026 | loginfo, rcsinfo, editinfo, verifymsg, commitinfo, taginfo, ignore, | ||
13027 | checkoutlist, cvswrappers, notify, modules, readers, writers, and | ||
13028 | config. | ||
13029 | |||
13030 | <p><hr> | ||
13031 | Node:<a name="commitinfo">commitinfo</a>, | ||
13032 | Next:<a rel=next href="#config">config</a>, | ||
13033 | Previous:<a rel=previous href="#checkoutlist">checkoutlist</a>, | ||
13034 | Up:<a rel=up href="#Repository_Administrative_Files">Repository Administrative Files</a> | ||
13035 | <br> | ||
13036 | |||
13037 | <h3>commitinfo</h3> | ||
13038 | |||
13039 | <p>Specifies programs to run at commit time, based on what's being | ||
13040 | committed. Each line consists of a regular expression followed by a | ||
13041 | command template: | ||
13042 | |||
13043 | <pre>REGULAR_EXPRESSION PROGRAM [ARGUMENTS] | ||
13044 | </pre> | ||
13045 | |||
13046 | <p>The PROGRAM is passed additional arguments following any arguments you | ||
13047 | may have written into the template. These additional arguments are the | ||
13048 | full path to the repository, followed by the name of each file about to | ||
13049 | be committed. These files can be examined by PROGRAM; their contents | ||
13050 | are the same as those of the working copy files about to be committed. | ||
13051 | If PROGRAM exits with nonzero status, the commit fails; otherwise, it | ||
13052 | succeeds. (See also <a href="#Shared_Syntax">Shared Syntax</a> earlier in this chapter.) | ||
13053 | |||
13054 | <p><hr> | ||
13055 | Node:<a name="config">config</a>, | ||
13056 | Next:<a rel=next href="#cvsignore">cvsignore</a>, | ||
13057 | Previous:<a rel=previous href="#commitinfo">commitinfo</a>, | ||
13058 | Up:<a rel=up href="#Repository_Administrative_Files">Repository Administrative Files</a> | ||
13059 | <br> | ||
13060 | |||
13061 | <h3>config</h3> | ||
13062 | |||
13063 | <p>Controls various global (non-project-specific) repository parameters. | ||
13064 | The syntax of each line is | ||
13065 | |||
13066 | <pre>ParameterName=yes|no | ||
13067 | </pre> | ||
13068 | |||
13069 | <p>except for the LockDir parameter, which takes an absolute pathname as | ||
13070 | argument. | ||
13071 | |||
13072 | <p>The following parameters are supported: | ||
13073 | |||
13074 | <ul> | ||
13075 | |||
13076 | <li>RCSBIN (default: <code>=no</code>) - (Obsolete) This option is silently | ||
13077 | accepted for backwards compatibility, but no longer has any effect. | ||
13078 | |||
13079 | <li>SystemAuth (default: <code>=no</code>) - If <code>yes</code>, CVS pserver | ||
13080 | authentication tries the system user database - usually | ||
13081 | <code>/etc/passwd</code> - if a username is not found in | ||
13082 | <code>CVSROOT/passwd</code>. If <code>no</code>, the user must exist in | ||
13083 | <code>CVSROOT/passwd</code> to gain access via the <code>:pserver:</code> method. | ||
13084 | |||
13085 | <li>PreservePermissions (default: <code>=no</code>) - If <code>yes</code>, CVS tries to | ||
13086 | preserve permissions and other special file system information (such as | ||
13087 | device numbers and symbolic link targets) for files. You probably don't | ||
13088 | want to do this, as it does not necessarily behave as expected. (See the | ||
13089 | node <cite>Special Files</cite> in the Cederqvist manual for details.) | ||
13090 | |||
13091 | <li>TopLevelAdmin (default: <code>=no</code>) - If <code>yes</code>, checkouts create a | ||
13092 | <code>CVS/</code> subdirectory next to each working copy tree (in the parent | ||
13093 | directory of the working copy). This can be useful if you will be | ||
13094 | checking out many working copies from the same repository; on the other | ||
13095 | hand, setting it here affects everyone who uses this repository. | ||
13096 | |||
13097 | <li>LockDir (unset by default) - The argument after the equal sign is a | ||
13098 | path to a directory in which CVS can create lockfiles. If not set, | ||
13099 | lockfiles are created in the repository, in locations corresponding to | ||
13100 | each project's RCS files. This means that users of those projects must | ||
13101 | have file-system-level write access to those repository directories. | ||
13102 | |||
13103 | </ul> | ||
13104 | |||
13105 | <p><hr> | ||
13106 | Node:<a name="cvsignore">cvsignore</a>, | ||
13107 | Next:<a rel=next href="#cvswrappers">cvswrappers</a>, | ||
13108 | Previous:<a rel=previous href="#config">config</a>, | ||
13109 | Up:<a rel=up href="#Repository_Administrative_Files">Repository Administrative Files</a> | ||
13110 | <br> | ||
13111 | |||
13112 | <h3>cvsignore</h3> | ||
13113 | |||
13114 | <p>Ignores certain files when doing updates, imports, or releases. By | ||
13115 | default, CVS already ignores some kinds of files. (For a full list, see | ||
13116 | the -I option to import, earlier in this chapter.) You can add to this | ||
13117 | list by putting additional file names or wildcard patterns in the | ||
13118 | cvsignore file. Each line gives a file name or pattern, for example: | ||
13119 | |||
13120 | <pre>README.msdos | ||
13121 | *.html | ||
13122 | blah?.out | ||
13123 | </pre> | ||
13124 | |||
13125 | <p>This causes CVS to ignore any file named <code>README.msdos</code>, any file | ||
13126 | ending in <code>.html</code>, and any file beginning with <code>blah</code> and | ||
13127 | ending with <code>.out</code>. (Technically, you can name multiple files or | ||
13128 | patterns on each line, separated by whitespace, but it is more readable | ||
13129 | to keep them to one per line. The whitespace separation rule does, | ||
13130 | unfortunately, mean that there's no way to specify a space in a file | ||
13131 | name, except to use wildcards.) | ||
13132 | |||
13133 | <p>A <code>!</code> anywhere in the list cancels all previous entries. (See | ||
13134 | <a href="#_CVSIGNORE">$CVSIGNORE</a> in the section <a href="#Environment_Variables">Environment Variables</a> in | ||
13135 | this chapter for a fuller discussion of ignore processing.) | ||
13136 | |||
13137 | <p><hr> | ||
13138 | Node:<a name="cvswrappers">cvswrappers</a>, | ||
13139 | Next:<a rel=next href="#editinfo">editinfo</a>, | ||
13140 | Previous:<a rel=previous href="#cvsignore">cvsignore</a>, | ||
13141 | Up:<a rel=up href="#Repository_Administrative_Files">Repository Administrative Files</a> | ||
13142 | <br> | ||
13143 | |||
13144 | <h3>cvswrappers</h3> | ||
13145 | |||
13146 | <p>Specifies certain filtering behaviors based on file name. Each line has | ||
13147 | a file-globbing pattern (that is, a file name or file wildcards), | ||
13148 | followed by an option indicating the filter type and an argument for the | ||
13149 | option. | ||
13150 | |||
13151 | <p>Options: | ||
13152 | |||
13153 | <ul> | ||
13154 | |||
13155 | <li>-m - Specifies an update method. Possible arguments are MERGE, which | ||
13156 | means to merge changes into working files automatically, and COPY, which | ||
13157 | means don't try to automerge but present the user with both versions of | ||
13158 | the file and let them work it out. MERGE is the default, except for | ||
13159 | binary files (those whose keyword substitution mode is -kb). (See the | ||
13160 | <a href="#Keyword_Substitution__RCS_Keywords_">Keyword Substitution (RCS Keywords)</a> section in this chapter.) | ||
13161 | Files marked as binary automatically use the COPY method, so there is no | ||
13162 | need to make a -m COPY wrapper for them. | ||
13163 | |||
13164 | <li>-k - Specifies a keyword substitution mode. All of the usual modes are | ||
13165 | possible. (See the <a href="#Keyword_Substitution__RCS_Keywords_">Keyword Substitution (RCS Keywords)</a> section in | ||
13166 | this chapter for a complete list.) | ||
13167 | |||
13168 | </ul> | ||
13169 | |||
13170 | <p>Here is an example cvswrappers file: | ||
13171 | |||
13172 | <pre>*.blob -m COPY | ||
13173 | *.blink -k o | ||
13174 | </pre> | ||
13175 | |||
13176 | <p>This cvswrappers file says to not attempt merges on files ending in | ||
13177 | <code>.blob</code> and suppress keyword substitution for files ending in | ||
13178 | <code>.blink</code>. (See also the file <code>.cvswrappers</code> in the | ||
13179 | <a href="#Working_Copy_Files">Working Copy Files</a> section in this chapter.) | ||
13180 | |||
13181 | <p><hr> | ||
13182 | Node:<a name="editinfo">editinfo</a>, | ||
13183 | Next:<a rel=next href="#history_file">history file</a>, | ||
13184 | Previous:<a rel=previous href="#cvswrappers">cvswrappers</a>, | ||
13185 | Up:<a rel=up href="#Repository_Administrative_Files">Repository Administrative Files</a> | ||
13186 | <br> | ||
13187 | |||
13188 | <h3>editinfo</h3> | ||
13189 | |||
13190 | <p>This file is obsolete. Very. | ||
13191 | |||
13192 | <p><hr> | ||
13193 | Node:<a name="history_file">history file</a>, | ||
13194 | Next:<a rel=next href="#loginfo">loginfo</a>, | ||
13195 | Previous:<a rel=previous href="#editinfo">editinfo</a>, | ||
13196 | Up:<a rel=up href="#Repository_Administrative_Files">Repository Administrative Files</a> | ||
13197 | <br> | ||
13198 | |||
13199 | <h3>history file</h3> | ||
13200 | |||
13201 | <p>Stores an ever-accumulating history of activity in the repository, for | ||
13202 | use by the cvs history command. To disable this feature, simply remove | ||
13203 | the history file. If you don't remove the file, you should probably | ||
13204 | make it world-writeable to avoid permission problems later. | ||
13205 | |||
13206 | <p>The contents of this file do not modify CVS's behavior in any way | ||
13207 | (except for the output of cvs history, of course). | ||
13208 | |||
13209 | <p><hr> | ||
13210 | Node:<a name="loginfo">loginfo</a>, | ||
13211 | Next:<a rel=next href="#modules">modules</a>, | ||
13212 | Previous:<a rel=previous href="#history_file">history file</a>, | ||
13213 | Up:<a rel=up href="#Repository_Administrative_Files">Repository Administrative Files</a> | ||
13214 | <br> | ||
13215 | |||
13216 | <h3>loginfo</h3> | ||
13217 | |||
13218 | <p>Specifies programs to run on the log message for each commit, based on | ||
13219 | what's being committed. Each line consists of a regular expression | ||
13220 | followed by a command template: | ||
13221 | |||
13222 | <pre>REGULAR_EXPRESSION PROGRAM [ARGUMENTS] | ||
13223 | </pre> | ||
13224 | |||
13225 | <p>The PROGRAM is passed the log message on its standard input. | ||
13226 | |||
13227 | <p>Several special codes are available for use in the arguments: <code>%s</code> | ||
13228 | expands to the names of the files being committed, <code>%V</code> expands to | ||
13229 | the old revisions from before the commit, and <code>%v</code> expands to the | ||
13230 | new revisions after the commit. When there are multiple files involved, | ||
13231 | each element of the expansion is separated from the others by | ||
13232 | whitespace. For example, in a commit involving two files, <code>%s</code> | ||
13233 | might expand into <code>hello.c README.txt</code>, and <code>%v</code> into | ||
13234 | <code>1.17 1.12</code>. | ||
13235 | |||
13236 | <p>You may combine codes inside curly braces, in which case, each unit of | ||
13237 | expansion is internally separated by commas and externally separated | ||
13238 | from the other units by whitespace. Continuing the previous example, | ||
13239 | <code>%{sv}</code> expands into <code>hello.c,1.17 README.txt,1.12</code>. | ||
13240 | |||
13241 | <p>If any <code>%</code> expansion is done at all, the expansion is prefixed by | ||
13242 | the path to the project subdirectory (relative to the top of the | ||
13243 | repository). So that last expansion would actually be: | ||
13244 | |||
13245 | <pre>myproj hello.c,1.17 README.txt,1.12 | ||
13246 | </pre> | ||
13247 | |||
13248 | <p>If PROGRAM exits with nonzero status, the commit fails; otherwise, it | ||
13249 | succeeds. (See also the <a href="#Shared_Syntax">Shared Syntax</a> section in this | ||
13250 | chapter.) | ||
13251 | |||
13252 | <p><hr> | ||
13253 | Node:<a name="modules">modules</a>, | ||
13254 | Next:<a rel=next href="#notify">notify</a>, | ||
13255 | Previous:<a rel=previous href="#loginfo">loginfo</a>, | ||
13256 | Up:<a rel=up href="#Repository_Administrative_Files">Repository Administrative Files</a> | ||
13257 | <br> | ||
13258 | |||
13259 | <h3>modules</h3> | ||
13260 | |||
13261 | <p>This maps names to repository directories. The general syntax of each | ||
13262 | line is: | ||
13263 | |||
13264 | <pre>MODULE [OPTIONS] [&OTHERMODULE...] [DIR] [FILES] | ||
13265 | </pre> | ||
13266 | |||
13267 | <p>DIR need not be a top-level project directory - it could be a | ||
13268 | subdirectory. If any FILES are specified, the module consists of only | ||
13269 | those files from the directory. | ||
13270 | |||
13271 | <p>An ampersand followed by a module name means to include the expansion of | ||
13272 | that module's line in place. | ||
13273 | |||
13274 | <p>Options: | ||
13275 | |||
13276 | <ul> | ||
13277 | |||
13278 | <li>-a - This is an <dfn>alias</dfn> module, meaning it expands literally to | ||
13279 | everything after the OPTIONS. In this case, the usual DIR/FILES | ||
13280 | behavior is turned off, and everything after the OPTIONS is treated as | ||
13281 | other modules or repository directories. | ||
13282 | |||
13283 | <p>If you use the -a option, you may exclude certain directories from other | ||
13284 | modules by putting them after an exclamation point (!). For example | ||
13285 | |||
13286 | <pre>top_proj -a !myproj/a-subdir !myproj/b-subdir myproj | ||
13287 | </pre> | ||
13288 | |||
13289 | <p>means that checking out <code>top_proj</code> will get all of <code>myproj</code> | ||
13290 | except <code>a-subdir</code> and <code>b-subdir</code>. | ||
13291 | |||
13292 | </p><li>-d NAME - Names the working directory NAME instead of the module name. | ||
13293 | |||
13294 | <li>-e PROGRAM - Runs PROGRAM whenever files in this module are exported. | ||
13295 | |||
13296 | <li>-i PROGRAM - Runs PROGRAM whenever files in this module are committed. | ||
13297 | The program is given a single argument - the full pathname in the | ||
13298 | repository of the file in question. (See <a href="#commitinfo">commitinfo</a>, | ||
13299 | <a href="#loginfo">loginfo</a>, and <a href="#verifymsg">verifymsg</a> for more sophisticated ways to | ||
13300 | run commit-triggered programs.) | ||
13301 | |||
13302 | <li>-o PROGRAM - Runs PROGRAM whenever files in this module are checked | ||
13303 | out. The program is given a single argument, the name of the module. | ||
13304 | |||
13305 | <li>-s STATUS - Declares a status for the module. When the modules file is | ||
13306 | printed (with cvs checkout -s), the modules are sorted by module status | ||
13307 | and then by name. This option has no other effects in CVS, so go wild. | ||
13308 | You can use it to sort anything - status, person responsible for the | ||
13309 | module, or the module's file language, for example. | ||
13310 | |||
13311 | <li>-t PROGRAM - Runs PROGRAM whenever files in this module are tagged with | ||
13312 | cvs rtag. The program is passed two arguments: the name of the module | ||
13313 | and the tag name. The program is not used for tag, only for rtag. I | ||
13314 | have no idea why this distinction is made. You may find the taginfo | ||
13315 | file more useful if you want to run programs at tag time. | ||
13316 | |||
13317 | <li>-u PROGRAM - Runs PROGRAM whenever a working copy of the module is | ||
13318 | updated from its top-level directory. The program is given a single | ||
13319 | argument, the full path to the module's repository. | ||
13320 | |||
13321 | </ul> | ||
13322 | |||
13323 | <p><hr> | ||
13324 | Node:<a name="notify">notify</a>, | ||
13325 | Next:<a rel=next href="#passwd">passwd</a>, | ||
13326 | Previous:<a rel=previous href="#modules">modules</a>, | ||
13327 | Up:<a rel=up href="#Repository_Administrative_Files">Repository Administrative Files</a> | ||
13328 | <br> | ||
13329 | |||
13330 | <h3>notify</h3> | ||
13331 | |||
13332 | <p>Controls how the notifications for watched files are performed. (You may | ||
13333 | want to read up on the watch and edit commands, or see the section | ||
13334 | <a href="#Watches__CVS_As_Telephone_">Watches (CVS As Telephone)</a> in <a href="#Advanced_CVS">Advanced CVS</a>.) Each line is | ||
13335 | of the usual form: | ||
13336 | |||
13337 | <p>REGULAR_EXPRESSION PROGRAM [ARGUMENTS] | ||
13338 | |||
13339 | <p>A <code>%s</code> in ARGUMENTS is expanded to the name of the user to be | ||
13340 | notified, and the rest of the information regarding the notification is | ||
13341 | passed to PROGRAM on standard input (usually this information is a brief | ||
13342 | message suitable for emailing to the user). (See the section | ||
13343 | <a href="#Shared_Syntax">Shared Syntax</a> earlier in this chapter.) | ||
13344 | |||
13345 | <p>As shipped with CVS, the notify file has one line | ||
13346 | |||
13347 | <pre>ALL mail %s -s "CVS notification" | ||
13348 | </pre> | ||
13349 | |||
13350 | <p>which is often all you need. | ||
13351 | |||
13352 | <p><hr> | ||
13353 | Node:<a name="passwd">passwd</a>, | ||
13354 | Next:<a rel=next href="#rcsinfo">rcsinfo</a>, | ||
13355 | Previous:<a rel=previous href="#notify">notify</a>, | ||
13356 | Up:<a rel=up href="#Repository_Administrative_Files">Repository Administrative Files</a> | ||
13357 | <br> | ||
13358 | |||
13359 | <h3>passwd</h3> | ||
13360 | |||
13361 | <p>Provides authentication information for the pserver access method. Each | ||
13362 | line is of the form: | ||
13363 | |||
13364 | <p>USER:ENCRYPTED_PASSWORD[:SYSTEM_USER] | ||
13365 | |||
13366 | <p>If no SYSTEM_USER is given, USER is taken as the system username. | ||
13367 | |||
13368 | <p><hr> | ||
13369 | Node:<a name="rcsinfo">rcsinfo</a>, | ||
13370 | Next:<a rel=next href="#taginfo">taginfo</a>, | ||
13371 | Previous:<a rel=previous href="#passwd">passwd</a>, | ||
13372 | Up:<a rel=up href="#Repository_Administrative_Files">Repository Administrative Files</a> | ||
13373 | <br> | ||
13374 | |||
13375 | <h3>rcsinfo</h3> | ||
13376 | |||
13377 | <p>Specifies a form that should be filled out for log messages that are | ||
13378 | written with an interactive editor. Each line of rcsinfo looks like: | ||
13379 | |||
13380 | <p>REGULAR_EXPRESSION FILE_CONTAINING_TEMPLATE | ||
13381 | |||
13382 | <p>This template is brought to remote working copies at checkout time, so | ||
13383 | if the template file or rcsinfo file changes after checkout, the remote | ||
13384 | copies won't know about it and will continue to use the old template. | ||
13385 | (See also the section <a href="#Shared_Syntax">Shared Syntax</a> in this chapter.) | ||
13386 | |||
13387 | <p><hr> | ||
13388 | Node:<a name="taginfo">taginfo</a>, | ||
13389 | Next:<a rel=next href="#users">users</a>, | ||
13390 | Previous:<a rel=previous href="#rcsinfo">rcsinfo</a>, | ||
13391 | Up:<a rel=up href="#Repository_Administrative_Files">Repository Administrative Files</a> | ||
13392 | <br> | ||
13393 | |||
13394 | <h3>taginfo</h3> | ||
13395 | |||
13396 | <p>Runs a program at tag time (usually done to check that the tag name | ||
13397 | matches some pattern). Each line is of the form: | ||
13398 | |||
13399 | <p>REGULAR_EXPRESSION PROGRAM | ||
13400 | |||
13401 | <p>The program is handed a set group of arguments. In order, they are the | ||
13402 | tag name, the operation (see below), the repository, and then as many | ||
13403 | file name/revision-number pairs as there are files involved in the tag. | ||
13404 | The file/revision pairs are separated by whitespace, like the rest of | ||
13405 | the arguments. | ||
13406 | |||
13407 | <p>The operation is one of <code>add</code>, <code>mov</code>, or <code>del</code> | ||
13408 | (<code>mov</code> means the -F option to tag was used). | ||
13409 | |||
13410 | <p>If PROGRAM exits with nonzero status, the tag operation will not | ||
13411 | succeed. (See also the section <a href="#Shared_Syntax">Shared Syntax</a> in this chapter.) | ||
13412 | |||
13413 | <p><hr> | ||
13414 | Node:<a name="users">users</a>, | ||
13415 | Next:<a rel=next href="#val-tags">val-tags</a>, | ||
13416 | Previous:<a rel=previous href="#taginfo">taginfo</a>, | ||
13417 | Up:<a rel=up href="#Repository_Administrative_Files">Repository Administrative Files</a> | ||
13418 | <br> | ||
13419 | |||
13420 | <h3>users</h3> | ||
13421 | |||
13422 | <p>Maps usernames to email addresses. Each line looks like: | ||
13423 | |||
13424 | <p>USERNAME:EMAIL_ADDRESS | ||
13425 | |||
13426 | <p>This sends watch notifications to EMAIL_ADDRESS instead of to USERNAME | ||
13427 | at the repository machine. (All this really does is control the | ||
13428 | expansion of %s in the notify file.) If EMAIL_ADDRESS includes | ||
13429 | whitespace, make sure to surround it with quotes. | ||
13430 | |||
13431 | <p>If user aliasing is being used in the passwd file, the username that | ||
13432 | will be matched is the CVS username (the one on the left), not the | ||
13433 | system username (the one on the right, if any). | ||
13434 | |||
13435 | <p><hr> | ||
13436 | Node:<a name="val-tags">val-tags</a>, | ||
13437 | Next:<a rel=next href="#verifymsg">verifymsg</a>, | ||
13438 | Previous:<a rel=previous href="#users">users</a>, | ||
13439 | Up:<a rel=up href="#Repository_Administrative_Files">Repository Administrative Files</a> | ||
13440 | <br> | ||
13441 | |||
13442 | <h3>val-tags</h3> | ||
13443 | |||
13444 | <p>Caches valid tag names for speedier lookups. You should never need to | ||
13445 | edit this file, but you may need to change its permissions, or even | ||
13446 | ownership, if people are having trouble retrieving or creating tags. | ||
13447 | |||
13448 | <p><hr> | ||
13449 | Node:<a name="verifymsg">verifymsg</a>, | ||
13450 | Previous:<a rel=previous href="#val-tags">val-tags</a>, | ||
13451 | Up:<a rel=up href="#Repository_Administrative_Files">Repository Administrative Files</a> | ||
13452 | <br> | ||
13453 | |||
13454 | <h3>verifymsg</h3> | ||
13455 | |||
13456 | <p>Used in conjunction with rcsinfo to verify the format of log messages. | ||
13457 | Each line is of the form: | ||
13458 | |||
13459 | <p>REGULAR_EXPRESSION PROGRAM [ARGUMENTS] | ||
13460 | |||
13461 | <p>The full path to the current log message template (see <a href="#rcsinfo">rcsinfo</a> | ||
13462 | earlier in this chapter) is appended after the last argument written in | ||
13463 | the verifymsg file. If PROGRAM exits with nonzero status, the commit | ||
13464 | fails. | ||
13465 | |||
13466 | <p><hr> | ||
13467 | Node:<a name="Run_Control_Files">Run Control Files</a>, | ||
13468 | Next:<a rel=next href="#Working_Copy_Files">Working Copy Files</a>, | ||
13469 | Previous:<a rel=previous href="#Repository_Administrative_Files">Repository Administrative Files</a>, | ||
13470 | Up:<a rel=up href="#CVS_Reference">CVS Reference</a> | ||
13471 | <br> | ||
13472 | |||
13473 | <h2>Run Control Files</h2> | ||
13474 | |||
13475 | <p>There are a few files on the client (working copy) side that affect | ||
13476 | CVS's behavior. In some cases, they are analogs of repository | ||
13477 | administrative files; in other cases, they control behaviors that are | ||
13478 | only appropriate for the client side. | ||
13479 | |||
13480 | <h3><code>.cvsrc</code></h3> | ||
13481 | |||
13482 | <p>Specifies options that you want to be used automatically with every CVS | ||
13483 | command. The format of each line is | ||
13484 | |||
13485 | <p>COMMAND OPTIONS | ||
13486 | |||
13487 | <p>where each COMMAND is an unabbreviated CVS command, such as checkout or | ||
13488 | update (but not co or up). The OPTIONS are those that you want to | ||
13489 | always be in effect when you run that command. Here is a common | ||
13490 | <code>.cvsrc</code> line: | ||
13491 | |||
13492 | <pre>update -d -P | ||
13493 | </pre> | ||
13494 | |||
13495 | <p>To specify global options, simple use cvs as the COMMAND. | ||
13496 | |||
13497 | <h3><code>.cvsignore</code></h3> | ||
13498 | |||
13499 | <p>Specifies additional ignore patterns. (See <a href="#cvsignore">cvsignore</a> in the | ||
13500 | <a href="#Repository_Administrative_Files">Repository Administrative Files</a> section in this chapter for the | ||
13501 | syntax.) | ||
13502 | |||
13503 | <p>You can have a .cvsignore file in your home directory, which will apply | ||
13504 | every time you use CVS. You can also have directory-specific ones in | ||
13505 | each project directory of a working copy (these last only apply to the | ||
13506 | directory where the .cvsignore is located, and not to its | ||
13507 | subdirectories). | ||
13508 | |||
13509 | <p>(See <a href="#_CVSIGNORE">$CVSIGNORE</a> in the section <a href="#Environment_Variables">Environment Variables</a> | ||
13510 | in this chapter, for a fuller discussion of ignore processing.) | ||
13511 | |||
13512 | <h3><code>.cvspass</code></h3> | ||
13513 | |||
13514 | <p>Stores passwords for each repository accessed via the pserver method. | ||
13515 | Each line is of the form: | ||
13516 | |||
13517 | <p>REPOSITORY LIGHTLY_SCRAMBLED_PASSWORD | ||
13518 | |||
13519 | <p>The password is essentially stored in cleartext - a very mild | ||
13520 | scrambling is done to prevent accidental compromises (such as the root | ||
13521 | user unintentionally looking inside the file). However, this scrambling | ||
13522 | will not deter any serious-minded person from gaining the password if | ||
13523 | they get access to the file. | ||
13524 | |||
13525 | <p>The .cvspass file is portable. You can copy it from one machine to | ||
13526 | another and have all of your passwords at the new machine, without ever | ||
13527 | having run cvs login there. (See also the <a href="#login">login</a> and | ||
13528 | <a href="#logout">logout</a> commands.) | ||
13529 | |||
13530 | <h3><code>.cvswrappers</code></h3> | ||
13531 | |||
13532 | <p>This is a client side version of the cvswrappers file. (See the | ||
13533 | <a href="#Repository_Administrative_Files">Repository Administrative Files</a> section in this chapter.) | ||
13534 | There can be a <code>.cvswrappers</code> file in your home directory and in | ||
13535 | each directory of a working copy directory, just as with | ||
13536 | <code>.cvsignore</code>. | ||
13537 | |||
13538 | <p><hr> | ||
13539 | Node:<a name="Working_Copy_Files">Working Copy Files</a>, | ||
13540 | Next:<a rel=next href="#Environment_Variables">Environment Variables</a>, | ||
13541 | Previous:<a rel=previous href="#Run_Control_Files">Run Control Files</a>, | ||
13542 | Up:<a rel=up href="#CVS_Reference">CVS Reference</a> | ||
13543 | <br> | ||
13544 | |||
13545 | <h2>Working Copy Files</h2> | ||
13546 | |||
13547 | <p>The CVS/ administrative subdirectories in each working copy contain some | ||
13548 | subset of the following files. | ||
13549 | |||
13550 | <ul> | ||
13551 | <li>CVS/Base/ | ||
13552 | <li>CVS/Baserev | ||
13553 | <li>CVS/Baserev.tmp | ||
13554 | <li>CVS/Checkin.prog | ||
13555 | <li>CVS/Entries | ||
13556 | <li>CVS/Entries.Backup | ||
13557 | <li>CVS/Entries.Log | ||
13558 | <li>CVS/Entries.Static | ||
13559 | <li>CVS/Notify | ||
13560 | <li>CVS/Notify.tmp | ||
13561 | <li>CVS/Repository | ||
13562 | <li>CVS/Root | ||
13563 | <li>CVS/Tag | ||
13564 | <li>CVS/Template | ||
13565 | <li>CVS/Update.prog | ||
13566 | </ul> | ||
13567 | |||
13568 | <p>Here is what each file or directory does: | ||
13569 | |||
13570 | <h3><code>CVS/Base/</code> (directory)</h3> | ||
13571 | |||
13572 | <p>If watches are on, <code>cvs edit</code> stores the original copy of the | ||
13573 | file in this directory. That way, <code>cvs unedit</code> can work even | ||
13574 | if it can't reach the server. | ||
13575 | |||
13576 | <h3><code>CVS/Baserev</code></h3> | ||
13577 | |||
13578 | <p>Lists the revision for each file in <code>Base/</code>. Each line looks like | ||
13579 | this: | ||
13580 | |||
13581 | <pre>FILE/REVISION/EXPANSION | ||
13582 | </pre> | ||
13583 | |||
13584 | <p>EXPANSION is currently ignored to allow for, well, future expansion. | ||
13585 | |||
13586 | <h3><code>CVS/Baserev.tmp</code></h3> | ||
13587 | |||
13588 | <p>This is the temp file for the preceding. (See <code>CVS/Notify.tmp</code> or | ||
13589 | <code>CVS/Entries.Backup</code> later on for further explanation.) | ||
13590 | |||
13591 | <h3><code>CVS/Checkin.prog</code></h3> | ||
13592 | |||
13593 | <p>Records the name of the program specified by the -i option in the | ||
13594 | modules file. (See the <a href="#Repository_Administrative_Files">Repository Administrative Files</a> section | ||
13595 | in this chapter.) | ||
13596 | |||
13597 | <h3><code>CVS/Entries</code></h3> | ||
13598 | |||
13599 | <p>Stores the revisions for the files in this directory. Each line is of | ||
13600 | the form: | ||
13601 | |||
13602 | <pre>[CODE_LETTER]/FILE/REVISION/DATE/[KEYWORD_MODE]/[STICKY_OPTION] | ||
13603 | </pre> | ||
13604 | |||
13605 | <p>If CODE_LETTER is present, it must be <code>D</code> for directory (anything | ||
13606 | else is silently ignored by CVS, to allow for future expansion), and the | ||
13607 | rest of the items on the line are absent. | ||
13608 | |||
13609 | <p>This file is always present. | ||
13610 | |||
13611 | <h3><code>CVS/Entries.Backup</code></h3> | ||
13612 | |||
13613 | <p>This is just a temp file. If you're writing some program to modify the | ||
13614 | <code>Entries</code> file, have it write the new contents to | ||
13615 | <code>Entries.backup</code> and then atomically rename it to <code>Entries</code>. | ||
13616 | |||
13617 | <h3><code>CVS/Entries.Log</code></h3> | ||
13618 | |||
13619 | <p>This is basically a patch file to be applied to <code>Entries</code> after | ||
13620 | <code>Entries</code> has been read (this is an efficiency hack, to avoid | ||
13621 | having to rewrite all of <code>Entries</code> for every little change). The | ||
13622 | format is the same as <code>Entries</code>, except that there is an additional | ||
13623 | mandatory code letter at the front of every line: An <code>A</code> means this | ||
13624 | line is to be added to what's in <code>Entries</code>; <code>R</code> means it's to | ||
13625 | be removed from what's in <code>Entries</code>. Any other letters should be | ||
13626 | silently ignored, to allow for future expansion. | ||
13627 | |||
13628 | <h3><code>CVS/Entries.Static</code></h3> | ||
13629 | |||
13630 | <p>If this file exists, it means only part of the directory was fetched | ||
13631 | from the repository, and CVS will not create additional files in that | ||
13632 | directory. This condition can usually be cleared by using | ||
13633 | <code>update -d</code>. | ||
13634 | |||
13635 | <h3><code>CVS/Notify</code></h3> | ||
13636 | |||
13637 | <p>Stores notifications that have not yet been sent to the server. | ||
13638 | |||
13639 | <h3><code>CVS/Notify.tmp</code></h3> | ||
13640 | |||
13641 | <p>Temp file for <code>Notify</code>. The usual procedure for modifying | ||
13642 | <code>Notify</code> is to write out <code>Notify.tmp</code> and then rename it to | ||
13643 | <code>Notify</code>. | ||
13644 | |||
13645 | <h3><code>CVS/Repository</code></h3> | ||
13646 | |||
13647 | <p>The path to the project-specific subdirectory in the repository. This | ||
13648 | may be an absolute path, or it may be relative to the path given in | ||
13649 | Root. | ||
13650 | |||
13651 | <p>This file is always present. | ||
13652 | |||
13653 | <h3><code>CVS/Root</code></h3> | ||
13654 | |||
13655 | <p>This is the repository; that is, the value of the <code>$CVSROOT</code> | ||
13656 | environment variable or the argument to the -d global option. | ||
13657 | |||
13658 | <p>This file is always present. | ||
13659 | |||
13660 | <h3><code>CVS/Tag</code></h3> | ||
13661 | |||
13662 | <p>If there is a sticky tag or date on this directory, it is recorded in | ||
13663 | the first line of the file. The first character is a single letter | ||
13664 | indicating the type of tag: <code>T</code>, <code>N</code>, or <code>D</code>, for branch | ||
13665 | tag, nonbranch tag, or date respectively. The rest of the line is the | ||
13666 | tag or date itself. | ||
13667 | |||
13668 | <h3><code>CVS/Template</code></h3> | ||
13669 | |||
13670 | <p>Contains a log message template as specified by the rcsinfo file. (See | ||
13671 | <a href="#Repository_Administrative_Files">Repository Administrative Files</a> earlier in this chapter.) It | ||
13672 | is relevant only for remote working copies; working copies on the same | ||
13673 | machine as the repository just read rcsinfo directly. | ||
13674 | |||
13675 | <h3><code>CVS/Update.prog</code></h3> | ||
13676 | |||
13677 | <p>Records the name of the program specified by the -u option in the | ||
13678 | modules file. (See the <a href="#Repository_Administrative_Files">Repository Administrative Files</a> section | ||
13679 | in this chapter.) | ||
13680 | |||
13681 | <p><hr> | ||
13682 | Node:<a name="Environment_Variables">Environment Variables</a>, | ||
13683 | Previous:<a rel=previous href="#Working_Copy_Files">Working Copy Files</a>, | ||
13684 | Up:<a rel=up href="#CVS_Reference">CVS Reference</a> | ||
13685 | <br> | ||
13686 | |||
13687 | <h2>Environment Variables</h2> | ||
13688 | |||
13689 | <p>These are all the environment variables that affect CVS. | ||
13690 | |||
13691 | <ul> | ||
13692 | <li><a href="#_COMSPEC">$COMSPEC</a>: | ||
13693 | <li><a href="#_CVS_CLIENT_LOG">$CVS_CLIENT_LOG</a>: | ||
13694 | <li><a href="#_CVS_CLIENT_PORT">$CVS_CLIENT_PORT</a>: | ||
13695 | <li><a href="#_CVSEDITOR">$CVSEDITOR</a>: | ||
13696 | <li><a href="#_CVSIGNORE">$CVSIGNORE</a>: | ||
13697 | <li><a href="#_CVS_IGNORE_REMOTE_ROOT">$CVS_IGNORE_REMOTE_ROOT</a>: | ||
13698 | <li><a href="#_CVS_PASSFILE">$CVS_PASSFILE</a>: | ||
13699 | <li><a href="#_CVS_RCMD_PORT">$CVS_RCMD_PORT</a>: | ||
13700 | <li><a href="#_CVSREAD">$CVSREAD</a>: | ||
13701 | <li><a href="#_CVSROOT">$CVSROOT</a>: | ||
13702 | <li><a href="#_CVS_RSH">$CVS_RSH</a>: | ||
13703 | <li><a href="#_CVS_SERVER">$CVS_SERVER</a>: | ||
13704 | <li><a href="#_CVS_SERVER_SLEEP">$CVS_SERVER_SLEEP</a>: | ||
13705 | <li><a href="#_CVSUMASK">$CVSUMASK</a>: | ||
13706 | <li><a href="#_CVSWRAPPERS">$CVSWRAPPERS</a>: | ||
13707 | <li><a href="#_EDITOR">$EDITOR</a>: | ||
13708 | <li><a href="#_HOME__HOMEDRIVE___HOMEPATH_">$HOME %HOMEDRIVE% %HOMEPATH%</a>: | ||
13709 | <li><a href="#_PATH">$PATH</a>: | ||
13710 | <li><a href="#_TEMP__TMP__TMPDIR">$TEMP $TMP $TMPDIR</a>: | ||
13711 | <li><a href="#_VISUAL">$VISUAL</a>: | ||
13712 | </ul> | ||
13713 | |||
13714 | <p><hr> | ||
13715 | Node:<a name="_COMSPEC">$COMSPEC</a>, | ||
13716 | Next:<a rel=next href="#_CVS_CLIENT_LOG">$CVS_CLIENT_LOG</a>, | ||
13717 | Up:<a rel=up href="#Environment_Variables">Environment Variables</a> | ||
13718 | <br> | ||
13719 | |||
13720 | <h3>$COMSPEC</h3> | ||
13721 | |||
13722 | <p>This is used in OS/2 only; it specifies the name of the command | ||
13723 | interpreter. It defaults to <code>CMD.EXE</code>. | ||
13724 | |||
13725 | <p><hr> | ||
13726 | Node:<a name="_CVS_CLIENT_LOG">$CVS_CLIENT_LOG</a>, | ||
13727 | Next:<a rel=next href="#_CVS_CLIENT_PORT">$CVS_CLIENT_PORT</a>, | ||
13728 | Previous:<a rel=previous href="#_COMSPEC">$COMSPEC</a>, | ||
13729 | Up:<a rel=up href="#Environment_Variables">Environment Variables</a> | ||
13730 | <br> | ||
13731 | |||
13732 | <h3>$CVS_CLIENT_LOG</h3> | ||
13733 | |||
13734 | <p>Used for debugging the client/server protocol. Set this variable to a | ||
13735 | file name before you start using CVS; all traffic to the server will be | ||
13736 | logged in filename.in, and everything from the server will be logged in | ||
13737 | filename.out. | ||
13738 | |||
13739 | <p><hr> | ||
13740 | Node:<a name="_CVS_CLIENT_PORT">$CVS_CLIENT_PORT</a>, | ||
13741 | Next:<a rel=next href="#_CVSEDITOR">$CVSEDITOR</a>, | ||
13742 | Previous:<a rel=previous href="#_CVS_CLIENT_LOG">$CVS_CLIENT_LOG</a>, | ||
13743 | Up:<a rel=up href="#Environment_Variables">Environment Variables</a> | ||
13744 | <br> | ||
13745 | |||
13746 | <h3>$CVS_CLIENT_PORT</h3> | ||
13747 | |||
13748 | <p>Used in Kerberos-authenticated client/server access. | ||
13749 | |||
13750 | <p><hr> | ||
13751 | Node:<a name="_CVSEDITOR">$CVSEDITOR</a>, | ||
13752 | Next:<a rel=next href="#_CVSIGNORE">$CVSIGNORE</a>, | ||
13753 | Previous:<a rel=previous href="#_CVS_CLIENT_PORT">$CVS_CLIENT_PORT</a>, | ||
13754 | Up:<a rel=up href="#Environment_Variables">Environment Variables</a> | ||
13755 | <br> | ||
13756 | |||
13757 | <h3>$CVSEDITOR</h3> | ||
13758 | |||
13759 | <p>Specifies the program to use to edit log messages for commits. This | ||
13760 | overrides <code>$EDITOR</code> and <code>$VISUAL</code>. | ||
13761 | |||
13762 | <p><hr> | ||
13763 | Node:<a name="_CVSIGNORE">$CVSIGNORE</a>, | ||
13764 | Next:<a rel=next href="#_CVS_IGNORE_REMOTE_ROOT">$CVS_IGNORE_REMOTE_ROOT</a>, | ||
13765 | Previous:<a rel=previous href="#_CVSEDITOR">$CVSEDITOR</a>, | ||
13766 | Up:<a rel=up href="#Environment_Variables">Environment Variables</a> | ||
13767 | <br> | ||
13768 | |||
13769 | <h3>$CVSIGNORE</h3> | ||
13770 | |||
13771 | <p>A whitespace-separated list of file names and wildcard patterns that CVS | ||
13772 | should ignore. (See also the -I option to the <a href="#import">import</a> command.) | ||
13773 | |||
13774 | <p>This variable is appended last to the ignore list during a command. The | ||
13775 | list is built up in this order: <code>CVSROOT/cvsignore</code>, the | ||
13776 | <code>.cvsignore</code> file in your home directory, the <code>$CVSIGNORE</code> | ||
13777 | variable, any -I command option, and finally the contents of | ||
13778 | <code>.cvsignore</code> files in the working copy used as CVS works in each | ||
13779 | directory. A <code>!</code> as the ignore specification at any point | ||
13780 | nullifies the entire ignore list built up to that point. | ||
13781 | |||
13782 | <p><hr> | ||
13783 | Node:<a name="_CVS_IGNORE_REMOTE_ROOT">$CVS_IGNORE_REMOTE_ROOT</a>, | ||
13784 | Next:<a rel=next href="#_CVS_PASSFILE">$CVS_PASSFILE</a>, | ||
13785 | Previous:<a rel=previous href="#_CVSIGNORE">$CVSIGNORE</a>, | ||
13786 | Up:<a rel=up href="#Environment_Variables">Environment Variables</a> | ||
13787 | <br> | ||
13788 | |||
13789 | <h3>$CVS_IGNORE_REMOTE_ROOT</h3> | ||
13790 | |||
13791 | <p>Recently obsolete. | ||
13792 | |||
13793 | <p><hr> | ||
13794 | Node:<a name="_CVS_PASSFILE">$CVS_PASSFILE</a>, | ||
13795 | Next:<a rel=next href="#_CVS_RCMD_PORT">$CVS_RCMD_PORT</a>, | ||
13796 | Previous:<a rel=previous href="#_CVS_IGNORE_REMOTE_ROOT">$CVS_IGNORE_REMOTE_ROOT</a>, | ||
13797 | Up:<a rel=up href="#Environment_Variables">Environment Variables</a> | ||
13798 | <br> | ||
13799 | |||
13800 | <h3>$CVS_PASSFILE</h3> | ||
13801 | |||
13802 | <p>Tells CVS to use some file other than .cvspass in your home directory. | ||
13803 | (See the file <code>.cvspass</code> in the <a href="#Run_Control_Files">Run Control Files</a> section in | ||
13804 | this chapter.) | ||
13805 | |||
13806 | <p><hr> | ||
13807 | Node:<a name="_CVS_RCMD_PORT">$CVS_RCMD_PORT</a>, | ||
13808 | Next:<a rel=next href="#_CVSREAD">$CVSREAD</a>, | ||
13809 | Previous:<a rel=previous href="#_CVS_PASSFILE">$CVS_PASSFILE</a>, | ||
13810 | Up:<a rel=up href="#Environment_Variables">Environment Variables</a> | ||
13811 | <br> | ||
13812 | |||
13813 | <h3>$CVS_RCMD_PORT</h3> | ||
13814 | |||
13815 | <p>Specifies the port number to contact the rcmd daemon on the server side. | ||
13816 | (This variable is currently ignored in Unix CVS clients.) | ||
13817 | |||
13818 | <p><hr> | ||
13819 | Node:<a name="_CVSREAD">$CVSREAD</a>, | ||
13820 | Next:<a rel=next href="#_CVSROOT">$CVSROOT</a>, | ||
13821 | Previous:<a rel=previous href="#_CVS_RCMD_PORT">$CVS_RCMD_PORT</a>, | ||
13822 | Up:<a rel=up href="#Environment_Variables">Environment Variables</a> | ||
13823 | <br> | ||
13824 | |||
13825 | <h3>$CVSREAD</h3> | ||
13826 | |||
13827 | <p>Makes working copy files read-only on checkout and update, if possible | ||
13828 | (the default is for them to be read-write). (See also the -r global | ||
13829 | option.) | ||
13830 | |||
13831 | <p><hr> | ||
13832 | Node:<a name="_CVSROOT">$CVSROOT</a>, | ||
13833 | Next:<a rel=next href="#_CVS_RSH">$CVS_RSH</a>, | ||
13834 | Previous:<a rel=previous href="#_CVSREAD">$CVSREAD</a>, | ||
13835 | Up:<a rel=up href="#Environment_Variables">Environment Variables</a> | ||
13836 | <br> | ||
13837 | |||
13838 | <h3>$CVSROOT</h3> | ||
13839 | |||
13840 | <p>This specifies the path to the repository. This is overridden with the | ||
13841 | -d global option and by the ambient repository for a given working copy. | ||
13842 | The path to the repository may be preceded by an access method, | ||
13843 | username, and host, according to the following syntax: | ||
13844 | |||
13845 | <pre>[[:METHOD:][[USER@]HOST]:]/REPOSITORY_PATH | ||
13846 | </pre> | ||
13847 | |||
13848 | <p>See the -d global option, in the section <a href="#Global_Options">Global Options</a> near | ||
13849 | the beginning of this chapter, for a list of valid methods. | ||
13850 | |||
13851 | <p><hr> | ||
13852 | Node:<a name="_CVS_RSH">$CVS_RSH</a>, | ||
13853 | Next:<a rel=next href="#_CVS_SERVER">$CVS_SERVER</a>, | ||
13854 | Previous:<a rel=previous href="#_CVSROOT">$CVSROOT</a>, | ||
13855 | Up:<a rel=up href="#Environment_Variables">Environment Variables</a> | ||
13856 | <br> | ||
13857 | |||
13858 | <h3>$CVS_RSH</h3> | ||
13859 | |||
13860 | <p>Specifies an external program for connecting to the server when using | ||
13861 | the <code>:ext:</code> access method. Defaults to <code>rsh</code>, but <code>ssh</code> | ||
13862 | is a common replacement value. | ||
13863 | |||
13864 | <p><hr> | ||
13865 | Node:<a name="_CVS_SERVER">$CVS_SERVER</a>, | ||
13866 | Next:<a rel=next href="#_CVS_SERVER_SLEEP">$CVS_SERVER_SLEEP</a>, | ||
13867 | Previous:<a rel=previous href="#_CVS_RSH">$CVS_RSH</a>, | ||
13868 | Up:<a rel=up href="#Environment_Variables">Environment Variables</a> | ||
13869 | <br> | ||
13870 | |||
13871 | <h3>$CVS_SERVER</h3> | ||
13872 | |||
13873 | <p>Program to invoke for CVS on the server side. Defaults to <code>cvs</code>, | ||
13874 | of course. | ||
13875 | |||
13876 | <p><hr> | ||
13877 | Node:<a name="_CVS_SERVER_SLEEP">$CVS_SERVER_SLEEP</a>, | ||
13878 | Next:<a rel=next href="#_CVSUMASK">$CVSUMASK</a>, | ||
13879 | Previous:<a rel=previous href="#_CVS_SERVER">$CVS_SERVER</a>, | ||
13880 | Up:<a rel=up href="#Environment_Variables">Environment Variables</a> | ||
13881 | <br> | ||
13882 | |||
13883 | <h3>$CVS_SERVER_SLEEP</h3> | ||
13884 | |||
13885 | <p>Delays the start of the server child process by the specified number of | ||
13886 | seconds. This is used only for debugging, to allow time for a debugger | ||
13887 | to connect. | ||
13888 | |||
13889 | <p><hr> | ||
13890 | Node:<a name="_CVSUMASK">$CVSUMASK</a>, | ||
13891 | Next:<a rel=next href="#_CVSWRAPPERS">$CVSWRAPPERS</a>, | ||
13892 | Previous:<a rel=previous href="#_CVS_SERVER_SLEEP">$CVS_SERVER_SLEEP</a>, | ||
13893 | Up:<a rel=up href="#Environment_Variables">Environment Variables</a> | ||
13894 | <br> | ||
13895 | |||
13896 | <h3>$CVSUMASK</h3> | ||
13897 | |||
13898 | <p>Permissions for files and directories in the repository. (You probably | ||
13899 | don't want to set this; it doesn't work for client/server anyway.) | ||
13900 | |||
13901 | <p><hr> | ||
13902 | Node:<a name="_CVSWRAPPERS">$CVSWRAPPERS</a>, | ||
13903 | Next:<a rel=next href="#_EDITOR">$EDITOR</a>, | ||
13904 | Previous:<a rel=previous href="#_CVSUMASK">$CVSUMASK</a>, | ||
13905 | Up:<a rel=up href="#Environment_Variables">Environment Variables</a> | ||
13906 | <br> | ||
13907 | |||
13908 | <h3>$CVSWRAPPERS</h3> | ||
13909 | |||
13910 | <p>A whitespace-separated list of file names, wildcards, and arguments that | ||
13911 | CVS should use as wrappers. (See <a href="#cvswrappers">cvswrappers</a> in the | ||
13912 | <a href="#Repository_Administrative_Files">Repository Administrative Files</a> section in this chapter for | ||
13913 | more information.) | ||
13914 | |||
13915 | <p><hr> | ||
13916 | Node:<a name="_EDITOR">$EDITOR</a>, | ||
13917 | Next:<a rel=next href="#_HOME__HOMEDRIVE___HOMEPATH_">$HOME %HOMEDRIVE% %HOMEPATH%</a>, | ||
13918 | Previous:<a rel=previous href="#_CVSWRAPPERS">$CVSWRAPPERS</a>, | ||
13919 | Up:<a rel=up href="#Environment_Variables">Environment Variables</a> | ||
13920 | <br> | ||
13921 | |||
13922 | <h3>$EDITOR</h3> | ||
13923 | |||
13924 | <p>(See <a href="#_CVSEDITOR">$CVSEDITOR</a>.) | ||
13925 | |||
13926 | <p><hr> | ||
13927 | Node:<a name="_HOME__HOMEDRIVE___HOMEPATH_">$HOME %HOMEDRIVE% %HOMEPATH%</a>, | ||
13928 | Next:<a rel=next href="#_PATH">$PATH</a>, | ||
13929 | Previous:<a rel=previous href="#_EDITOR">$EDITOR</a>, | ||
13930 | Up:<a rel=up href="#Environment_Variables">Environment Variables</a> | ||
13931 | <br> | ||
13932 | |||
13933 | <h3>$HOME %HOMEDRIVE% %HOMEPATH%</h3> | ||
13934 | |||
13935 | <p>Where the <code>.cvsrc</code>, <code>.cvspass</code>, and other such files are found | ||
13936 | (under Unix, only <code>$HOME</code> is used). In Windows NT, | ||
13937 | <code>%HOMEDRIVE%</code> and <code>%HOMEPATH%</code> might be set for you; in | ||
13938 | Windows 95, you may need to set them for yourself. | ||
13939 | |||
13940 | <p>In Windows 95, you may also need to set <code>%HOME%</code>. Make sure not to | ||
13941 | give it a trailing backslash; use set <code>HOME=C:</code> or something | ||
13942 | similar. | ||
13943 | |||
13944 | <p><hr> | ||
13945 | Node:<a name="_PATH">$PATH</a>, | ||
13946 | Next:<a rel=next href="#_TEMP__TMP__TMPDIR">$TEMP $TMP $TMPDIR</a>, | ||
13947 | Previous:<a rel=previous href="#_HOME__HOMEDRIVE___HOMEPATH_">$HOME %HOMEDRIVE% %HOMEPATH%</a>, | ||
13948 | Up:<a rel=up href="#Environment_Variables">Environment Variables</a> | ||
13949 | <br> | ||
13950 | |||
13951 | <h3>$PATH</h3> | ||
13952 | |||
13953 | <p>Obsolete. | ||
13954 | |||
13955 | <p><hr> | ||
13956 | Node:<a name="_TEMP__TMP__TMPDIR">$TEMP $TMP $TMPDIR</a>, | ||
13957 | Next:<a rel=next href="#_VISUAL">$VISUAL</a>, | ||
13958 | Previous:<a rel=previous href="#_PATH">$PATH</a>, | ||
13959 | Up:<a rel=up href="#Environment_Variables">Environment Variables</a> | ||
13960 | <br> | ||
13961 | |||
13962 | <h3>$TEMP $TMP $TMPDIR</h3> | ||
13963 | |||
13964 | <p>Where temporary files go (the server uses TMPDIR; Windows NT uses TMP). | ||
13965 | Setting this on the client side will not affect the server. Setting | ||
13966 | this on either side will not affect where CVS stores temporary lock | ||
13967 | files. (See <a href="#config">config</a> in the <a href="#Repository_Administrative_Files">Repository Administrative Files</a> section in this chapter for more information.) | ||
13968 | |||
13969 | <p><hr> | ||
13970 | Node:<a name="_VISUAL">$VISUAL</a>, | ||
13971 | Previous:<a rel=previous href="#_TEMP__TMP__TMPDIR">$TEMP $TMP $TMPDIR</a>, | ||
13972 | Up:<a rel=up href="#Environment_Variables">Environment Variables</a> | ||
13973 | <br> | ||
13974 | |||
13975 | <h3>$VISUAL</h3> | ||
13976 | |||
13977 | <p>(See <a href="#_CVSEDITOR">$CVSEDITOR</a>.) | ||
13978 | |||
13979 | <p><hr> | ||
13980 | Node:<a name="Third-Party_Tools">Third-Party Tools</a>, | ||
13981 | Next:<a rel=next href="#Index">Index</a>, | ||
13982 | Previous:<a rel=previous href="#CVS_Reference">CVS Reference</a>, | ||
13983 | Up:<a rel=up href="#Top">Top</a> | ||
13984 | <br> | ||
13985 | |||
13986 | <h1>Third-Party Tools</h1> | ||
13987 | |||
13988 | <p>Many people have written programs to augment CVS. I call these | ||
13989 | <dfn>third-party tools</dfn> because they have their own maintainers, | ||
13990 | separate from the CVS development team. Most of these programs are not | ||
13991 | distributed with CVS, although some are. This chapter covers | ||
13992 | third-party tools that I have found useful, but that are not distributed | ||
13993 | with CVS. | ||
13994 | |||
13995 | <p>Although there are some very popular and widely used non-command-line or | ||
13996 | non-Unix interfaces to CVS (download sites are listed in <a href="#Repository_Administration">Repository Administration</a>), this chapter does not discuss most of them. Their | ||
13997 | popularity makes it easy to find out more about them from mailing lists | ||
13998 | and newsgroups. One exception to this is the Emacs pcl-cvs interface, | ||
13999 | which is very useful, but sometimes tricky to install. | ||
14000 | |||
14001 | <ul> | ||
14002 | <li><a href="#pcl-cvs_--_An_Emacs_Interface_To_CVS">pcl-cvs -- An Emacs Interface To CVS</a>: | ||
14003 | <li><a href="#cvsutils_--_General_Utilities_For_Use_With_CVS">cvsutils -- General Utilities For Use With CVS</a>: | ||
14004 | <li><a href="#cvs2cl_--_Generate_GNU-Style_ChangeLogs">cvs2cl -- Generate GNU-Style ChangeLogs</a>: | ||
14005 | <li><a href="#cvslock_--_Lock_Repositories_For_Atomicity">cvslock -- Lock Repositories For Atomicity</a>: | ||
14006 | <li><a href="#cvsq_--_Queue_CVS_Commands_For_Later_Connection">cvsq -- Queue CVS Commands For Later Connection</a>: | ||
14007 | <li><a href="#Other_Packages">Other Packages</a>: | ||
14008 | <li><a href="#Writing_Your_Own_Tools">Writing Your Own Tools</a>: | ||
14009 | </ul> | ||
14010 | |||
14011 | <p><hr> | ||
14012 | Node:<a name="pcl-cvs_--_An_Emacs_Interface_To_CVS">pcl-cvs -- An Emacs Interface To CVS</a>, | ||
14013 | Next:<a rel=next href="#cvsutils_--_General_Utilities_For_Use_With_CVS">cvsutils -- General Utilities For Use With CVS</a>, | ||
14014 | Up:<a rel=up href="#Third-Party_Tools">Third-Party Tools</a> | ||
14015 | <br> | ||
14016 | |||
14017 | <h2>pcl-cvs - An Emacs Interface To CVS</h2> | ||
14018 | |||
14019 | <p>Depends on: Emacs, Elib | ||
14020 | |||
14021 | <p>URLs: | ||
14022 | |||
14023 | <ul> | ||
14024 | <li><a href="ftp://rum.cs.yale.edu/pub/monnier/pcl-cvs/">ftp://rum.cs.yale.edu/pub/monnier/pcl-cvs/</a> | ||
14025 | <li><a href="ftp://ftp.lysator.liu.se/pub/emacs/pcl-cvs-1.05.tar.gz">ftp://ftp.lysator.liu.se/pub/emacs/pcl-cvs-1.05.tar.gz</a> | ||
14026 | <li><a href="ftp://ftp.red-bean.com/pub/kfogel/pcl-cvs-1.05.tar.gz">ftp://ftp.red-bean.com/pub/kfogel/pcl-cvs-1.05.tar.gz</a> | ||
14027 | </ul> | ||
14028 | |||
14029 | <p>Authors: Per Cederqvist and Stefan Monnier (current maintainer) | ||
14030 | |||
14031 | <p><code>pcl-cvs</code> is one of two Emacs/CVS interfaces. The other is the | ||
14032 | native VC (Version Control) interface built into Emacs. I prefer | ||
14033 | pcl-cvs because it was written exclusively for CVS and, therefore, works | ||
14034 | smoothly with the CVS way of doing things. VC, on the other hand, was | ||
14035 | designed to work with several different back-end version control systems | ||
14036 | - RCS and SCCS, as well as CVS - and is not really "tuned" for CVS. | ||
14037 | For example, VC presents a file-based rather than a directory-based | ||
14038 | interface to revision control. | ||
14039 | |||
14040 | <p>The advantages of pcl-cvs are strong enough that many people choose to | ||
14041 | download and install it rather than use VC. Unfortunately, pcl-cvs has | ||
14042 | two disadvantages: It can be a bit tricky to install (much of this | ||
14043 | section is devoted to overcoming possible installation hurdles), and its | ||
14044 | recent releases are a bit unstable. | ||
14045 | |||
14046 | <p>The latter problem is likely to be temporary, but it does raise the | ||
14047 | question of which version to use. Stefan Monnier has just recently | ||
14048 | taken over the pcl-cvs maintainership; the latest release, 2.9.6 | ||
14049 | (available from the first URL in the preceding list), was a bit bumpy | ||
14050 | when I tried it. No doubt the problems will be smoothed out soon, but | ||
14051 | in the meantime, you might want to use an older version. Because I've | ||
14052 | been using Version 1.05 daily for a long time now and it's performed | ||
14053 | quite well, I'm going to document that version here. Fortunately, the | ||
14054 | installation procedures don't change much from version to version. If | ||
14055 | you decide to use pcl-cvs, I suggest that you check Monnier's download | ||
14056 | site for a version newer than 2.9.6; if there is one, try it out before | ||
14057 | regressing all the way to 1.05. | ||
14058 | |||
14059 | <p>You'll notice that two URLs are given for Version 1.05. The first is | ||
14060 | Per Cederqvist's site, where he still makes available an old archive of | ||
14061 | pcl-cvs. However, since I'm not sure how much longer his archive will | ||
14062 | stay around, I'm also making the 1.05 distribution available from | ||
14063 | ftp.red-bean.com. | ||
14064 | |||
14065 | <p>Although the rest of these instructions use examples from a Version 1.05 | ||
14066 | distribution, they should apply to later versions as well. | ||
14067 | |||
14068 | <ul> | ||
14069 | <li><a href="#Installing_pcl-cvs">Installing pcl-cvs</a>: | ||
14070 | <li><a href="#Using_pcl-cvs">Using pcl-cvs</a>: | ||
14071 | <li><a href="#Error_Handling_In_pcl-cvs">Error Handling In pcl-cvs</a>: | ||
14072 | <li><a href="#The_Future_Of_pcl-cvs">The Future Of pcl-cvs</a>: | ||
14073 | </ul> | ||
14074 | |||
14075 | <p><hr> | ||
14076 | Node:<a name="Installing_pcl-cvs">Installing pcl-cvs</a>, | ||
14077 | Next:<a rel=next href="#Using_pcl-cvs">Using pcl-cvs</a>, | ||
14078 | Up:<a rel=up href="#pcl-cvs_--_An_Emacs_Interface_To_CVS">pcl-cvs -- An Emacs Interface To CVS</a> | ||
14079 | <br> | ||
14080 | |||
14081 | <h3>Installing pcl-cvs</h3> | ||
14082 | |||
14083 | <p>If you don't normally deal with Emacs installation and site-maintenance | ||
14084 | issues, the pcl-cvs installation procedure may seem a bit daunting. A | ||
14085 | little background on how Emacs works may help. | ||
14086 | |||
14087 | <p>Most higher-level Emacs features are written in a language called "Emacs | ||
14088 | Lisp" (Emacs itself is essentially an interpreter for this language). | ||
14089 | People add new features to Emacs by distributing files of Emacs Lisp | ||
14090 | code. <code>pcl-cvs</code> is written in this language, and it depends on a | ||
14091 | library of useful, generic Emacs Lisp functions called <dfn>Elib</dfn> (also | ||
14092 | written in part by Per Cederqvist, but distributed separately from | ||
14093 | pcl-cvs). | ||
14094 | |||
14095 | <p>Elib is not included in the regular Emacs distribution (at least not FSF | ||
14096 | Emacs; I don't know about XEmacs), so you may have to download and | ||
14097 | install it yourself before you can use pcl-cvs. You can get it from | ||
14098 | <a href="ftp://ftp.lysator.liu.se/pub/emacs/elib-1.0.tar.gz">ftp://ftp.lysator.liu.se/pub/emacs/elib-1.0.tar.gz</a>. Installation | ||
14099 | instructions are contained within the package. | ||
14100 | |||
14101 | <p>Once Elib is installed, you're ready to build and install pcl-cvs. | ||
14102 | These instructions applies both to Version 1.05 and the 2.x series | ||
14103 | (although you should check the NEWS and INSTALL files in newer | ||
14104 | distributions to see what's changed). | ||
14105 | |||
14106 | <p>First, unpack pcl-cvs (I'm using Version 1.05, but it could just as | ||
14107 | easily have been 2.9.6) | ||
14108 | |||
14109 | <pre>floss$ zcat pcl-cvs-1.05.tar.gz | tar xvf - | ||
14110 | pcl-cvs-1.05/ | ||
14111 | pcl-cvs-1.05/README | ||
14112 | pcl-cvs-1.05/NEWS | ||
14113 | pcl-cvs-1.05/INSTALL | ||
14114 | pcl-cvs-1.05/ChangeLog | ||
14115 | pcl-cvs-1.05/pcl-cvs.el | ||
14116 | pcl-cvs-1.05/pcl-cvs.texinfo | ||
14117 | pcl-cvs-1.05/compile-all.el | ||
14118 | pcl-cvs-1.05/pcl-cvs-lucid.el | ||
14119 | pcl-cvs-1.05/pcl-cvs-startup.el | ||
14120 | pcl-cvs-1.05/pcl-cvs.info | ||
14121 | pcl-cvs-1.05/Makefile | ||
14122 | pcl-cvs-1.05/texinfo.tex | ||
14123 | </pre> | ||
14124 | |||
14125 | <p>and go into the source tree's top level: | ||
14126 | |||
14127 | <pre>floss$ cd pcl-cvs-1.05/ | ||
14128 | </pre> | ||
14129 | |||
14130 | <p>A Makefile is supplied there. According to the instructions in the | ||
14131 | INSTALL file, you're supposed to edit a few paths at the top of the | ||
14132 | Makefile and then run: | ||
14133 | |||
14134 | <pre>floss$ make install | ||
14135 | </pre> | ||
14136 | |||
14137 | <p>If that works, great. However, this sometimes results in an error (the | ||
14138 | pcl-cvs code itself is very portable, but its installation procedures | ||
14139 | sometimes are not). Do this if you get an error: | ||
14140 | |||
14141 | <pre>floss$ make clean | ||
14142 | floss$ make | ||
14143 | </pre> | ||
14144 | |||
14145 | <p>If all goes well, these commands accomplish a significant part of the | ||
14146 | installation by byte-compiling all of the Emacs Lisp files. | ||
14147 | (Byte-compiling converts a file of human-readable Emacs Lisp code - an | ||
14148 | .el file - into a more compact and efficient representation - an .elc | ||
14149 | file. Emacs can load and run an .elc file with better performance than | ||
14150 | it can a plain .el file.) | ||
14151 | |||
14152 | <p>I'll proceed as though the byte-compilation stage has succeeded. If the | ||
14153 | byte compilation does not appear to succeed, don't worry: The .elc files | ||
14154 | are a luxury, not a necessity. They improve performance slightly, but | ||
14155 | you can run pcl-cvs from the raw .el files with no problem. | ||
14156 | |||
14157 | <p>If the make install failed, the next step is to get the Emacs Lisp | ||
14158 | (whether .el or .elc) into a directory where Emacs can load it | ||
14159 | automatically. Emacs has a designated directory on the system for | ||
14160 | locally installed Lisp. To find this directory - it will have a file | ||
14161 | named <code>default.el</code> in it - check the following locations, in this | ||
14162 | order: | ||
14163 | |||
14164 | <ol type=1 start=1> | ||
14165 | </p><li>/usr/share/emacs/site-lisp/ | ||
14166 | <li>/usr/local/share/emacs/site-lisp/ | ||
14167 | <li>/usr/lib/emacs/site-lisp/ | ||
14168 | <li>/usr/local/lib/emacs/site-lisp/ | ||
14169 | </ol> | ||
14170 | |||
14171 | <p>Once you've found your site-lisp directory, copy all of the Lisp files | ||
14172 | to it (you may have to be root to do this): | ||
14173 | |||
14174 | <pre>floss# cp -f *.el *.elc /usr/share/emacs/site-lisp/ | ||
14175 | </pre> | ||
14176 | |||
14177 | <p>The last step is to tell Emacs about the entry points to pcl-cvs (the | ||
14178 | main one being the function cvs-update), so it will know to load the | ||
14179 | pcl-cvs code on demand. Because Emacs always reads the default.el file | ||
14180 | when it starts up, that's where you need to list the pcl-cvs entry | ||
14181 | points. | ||
14182 | |||
14183 | <p>Fortunately, pcl-cvs provides the necessary content for default.el. | ||
14184 | Simply put the contents of pcl-cvs-startup.el into default.el (or | ||
14185 | perhaps into your .emacs, if you're just installing this for yourself) | ||
14186 | and restart your Emacs. | ||
14187 | |||
14188 | <p>You may also want to copy the .info files into your info tree and add | ||
14189 | pcl-cvs to the table of contents in the dir file. | ||
14190 | |||
14191 | <p><hr> | ||
14192 | Node:<a name="Using_pcl-cvs">Using pcl-cvs</a>, | ||
14193 | Next:<a rel=next href="#Error_Handling_In_pcl-cvs">Error Handling In pcl-cvs</a>, | ||
14194 | Previous:<a rel=previous href="#Installing_pcl-cvs">Installing pcl-cvs</a>, | ||
14195 | Up:<a rel=up href="#pcl-cvs_--_An_Emacs_Interface_To_CVS">pcl-cvs -- An Emacs Interface To CVS</a> | ||
14196 | <br> | ||
14197 | |||
14198 | <h3>Using pcl-cvs</h3> | ||
14199 | |||
14200 | <p>Once installed, pcl-cvs is very easy to use. You just run the function | ||
14201 | cvs-update, and pcl-cvs brings up a buffer showing what files in your | ||
14202 | working copy have been modified or updated. From there, you can commit, | ||
14203 | do diffs, and so on. | ||
14204 | |||
14205 | <p>Because cvs-update is the main entry point, I suggest that you bind it | ||
14206 | to a convenient key sequence before going any further. I have it bound | ||
14207 | to <kbd>Ctrl+c v</kbd> in my .emacs: | ||
14208 | |||
14209 | <pre>(global-set-key "\C-cv" 'cvs-update) | ||
14210 | </pre> | ||
14211 | |||
14212 | <p>Otherwise, you can run it by typing <kbd>M-x cvs-update</kbd> (also known as | ||
14213 | <kbd>Esc-x cvs-update</kbd>). | ||
14214 | |||
14215 | <p>When invoked, cvs-update runs cvs update as if in the directory of the | ||
14216 | file in the current buffer - just as if you typed cvs update on the | ||
14217 | command line in that directory. Here's an example of what you might see | ||
14218 | inside Emacs: | ||
14219 | |||
14220 | <pre>PCL-CVS release 1.05 from CVS release $Name$. | ||
14221 | Copyright (C) 1992, 1993 Per Cederqvist | ||
14222 | Pcl-cvs comes with absolutely no warranty; for details consult the manual. | ||
14223 | This is free software, and you are welcome to redistribute it under certain | ||
14224 | conditions; again, consult the TeXinfo manual for details. | ||
14225 | Modified ci README.txt | ||
14226 | Modified ci fish.c | ||
14227 | ---------- End ---- | ||
14228 | </pre> | ||
14229 | |||
14230 | <p>Two files have been locally modified (some versions of pcl-cvs show the | ||
14231 | subdirectories where the files are located). The next logical action is | ||
14232 | to commit one or both of the files, which is what the ci on each line | ||
14233 | means. To commit one of them, go to its line and type <kbd>c</kbd>. You are | ||
14234 | brought to a log message buffer, where you can type a log message as | ||
14235 | long as you want (real log message editing is the major advantage of | ||
14236 | pcl-cvs over the command line). Type <kbd>Ctrl+c Ctrl+c</kbd> when done to | ||
14237 | complete the commit. | ||
14238 | |||
14239 | <p>If you want to commit multiple files at once, sharing a log message, | ||
14240 | first use m to mark the files that you intend to commit. An asterisk | ||
14241 | appears next to each file as you mark it: | ||
14242 | |||
14243 | <pre>PCL-CVS release 1.05 from CVS release $Name$. | ||
14244 | Copyright (C) 1992, 1993 Per Cederqvist | ||
14245 | Pcl-cvs comes with absolutely no warranty; for details consult the manual. | ||
14246 | This is free software, and you are welcome to redistribute it under certain | ||
14247 | conditions; again, consult the TeXinfo manual for details. | ||
14248 | * Modified ci README.txt | ||
14249 | * Modified ci fish.c | ||
14250 | ---------- End ---- | ||
14251 | </pre> | ||
14252 | |||
14253 | <p>Now when you type c anywhere, it applies to all (and only) the marked | ||
14254 | files. Write the log message and commit them with <kbd>Ctrl+c Ctrl+c</kbd> | ||
14255 | as before. | ||
14256 | |||
14257 | <p>You can also type <kbd>d</kbd> to run cvs diff on a file (or on marked files) | ||
14258 | and <kbd>f</kbd> to bring a file into Emacs for editing. Other commands are | ||
14259 | available; type <kbd>Ctrl+h</kbd> m in the update buffer to see what else you | ||
14260 | can do. | ||
14261 | |||
14262 | <p><hr> | ||
14263 | Node:<a name="Error_Handling_In_pcl-cvs">Error Handling In pcl-cvs</a>, | ||
14264 | Next:<a rel=next href="#The_Future_Of_pcl-cvs">The Future Of pcl-cvs</a>, | ||
14265 | Previous:<a rel=previous href="#Using_pcl-cvs">Using pcl-cvs</a>, | ||
14266 | Up:<a rel=up href="#pcl-cvs_--_An_Emacs_Interface_To_CVS">pcl-cvs -- An Emacs Interface To CVS</a> | ||
14267 | <br> | ||
14268 | |||
14269 | <h3>Error Handling In pcl-cvs</h3> | ||
14270 | |||
14271 | <p>The pcl-cvs program has historically had an odd way of dealing with | ||
14272 | error and informational messages from CVS (although this may be | ||
14273 | corrected in the latest versions). When it encounters a message from | ||
14274 | CVS that it doesn't know about, it gets hysterical and throws you into a | ||
14275 | mail buffer, ready to send a pregenerated bug report to the author of | ||
14276 | pcl-cvs. Unfortunately, among the CVS messages that pcl-cvs may not | ||
14277 | know about are the ones associated with conflicting merges, which, | ||
14278 | although not common, certainly do occur from time to time. | ||
14279 | |||
14280 | <p>If pcl-cvs suddenly dumps you into a mail buffer, don't panic. Read | ||
14281 | over the contents of the buffer carefully - the offending CVS output | ||
14282 | should be in there somewhere. If it looks like a merge, you can just | ||
14283 | get rid of the mail buffer and rerun cvs-update. It should now succeed, | ||
14284 | because CVS won't output any merge messages (because the merge has | ||
14285 | already taken place). | ||
14286 | |||
14287 | <p>(Update: this problem appears to have been fixed in more recent versions | ||
14288 | of pcl-cvs, so very probably you can ignore this entire warning.) | ||
14289 | |||
14290 | <p><hr> | ||
14291 | Node:<a name="The_Future_Of_pcl-cvs">The Future Of pcl-cvs</a>, | ||
14292 | Previous:<a rel=previous href="#Error_Handling_In_pcl-cvs">Error Handling In pcl-cvs</a>, | ||
14293 | Up:<a rel=up href="#pcl-cvs_--_An_Emacs_Interface_To_CVS">pcl-cvs -- An Emacs Interface To CVS</a> | ||
14294 | <br> | ||
14295 | |||
14296 | <h3>The Future Of pcl-cvs</h3> | ||
14297 | |||
14298 | <p>Although I may be giving you the impression that pcl-cvs is barely | ||
14299 | maintained and a risky investment, the instability appears to be | ||
14300 | temporary. Stefan Monnier is a responsive maintainer (I contacted him | ||
14301 | several times during the writing of this chapter, and he always answered | ||
14302 | right away; he is already making headway on some of the bugs in Version | ||
14303 | 2.9.6). Very likely by the time this is published, you will be able to | ||
14304 | download Version 2.9.7 or later with confidence. | ||
14305 | |||
14306 | <p>In fact, I just now got an encouraging email on this topic from Greg | ||
14307 | Woods, a former maintainer of pcl-cvs, reprinted here with his | ||
14308 | permission: | ||
14309 | |||
14310 | <pre>From: woods@most.weird.com (Greg A. Woods) | ||
14311 | Subject: Re: pcl-cvs maintenance status, stability of recent "release"s? | ||
14312 | To: kfogel@red-bean.com | ||
14313 | Date: Sun, 29 Aug 1999 18:59:19 -0400 (EDT) | ||
14314 | |||
14315 | [...] | ||
14316 | I've been using Stefan's releases for some time now, and indeed I have | ||
14317 | abandoned my own branch of it. | ||
14318 | |||
14319 | He's done a lot of really good work on PCL-CVS and except for a few odd | ||
14320 | quirks in the 2.9.6 version I'm using daily now it is quite usable (and | ||
14321 | is approximately infinitely more usable with modern CVS than the one | ||
14322 | that was in the CVS distribution! ;-). | ||
14323 | |||
14324 | I've added a pcl-cvs.README file to my FTP site to point out that the | ||
14325 | files there are indeed quite old (at least in Internet time! ;-) and to | ||
14326 | give a pointer to Stefan's FTP site too. | ||
14327 | |||
14328 | [...] | ||
14329 | </pre> | ||
14330 | |||
14331 | <p>In a later email, Greg said that the FSF is considering including | ||
14332 | pcl-cvs in their next release of Emacs (20.5), which would render most | ||
14333 | of the preceding installation advice obsolete. Sigh. It's hard to keep | ||
14334 | up with free software, sometimes. | ||
14335 | |||
14336 | <p><hr> | ||
14337 | Node:<a name="cvsutils_--_General_Utilities_For_Use_With_CVS">cvsutils -- General Utilities For Use With CVS</a>, | ||
14338 | Next:<a rel=next href="#cvs2cl_--_Generate_GNU-Style_ChangeLogs">cvs2cl -- Generate GNU-Style ChangeLogs</a>, | ||
14339 | Previous:<a rel=previous href="#pcl-cvs_--_An_Emacs_Interface_To_CVS">pcl-cvs -- An Emacs Interface To CVS</a>, | ||
14340 | Up:<a rel=up href="#Third-Party_Tools">Third-Party Tools</a> | ||
14341 | <br> | ||
14342 | |||
14343 | <h2>cvsutils - General Utilities For Use With CVS</h2> | ||
14344 | |||
14345 | <p>Depends on: Perl | ||
14346 | |||
14347 | <p>URLs: | ||
14348 | |||
14349 | <ul> | ||
14350 | <li><a href="http://www.red-bean.com/cvsutils">http://www.red-bean.com/cvsutils</a> | ||
14351 | </ul> | ||
14352 | |||
14353 | <p>Authors: Tom Tromey (original author) and Pavel Roskin (current maintainer) | ||
14354 | |||
14355 | <p>The suite of small programs called <code>cvsutils</code> generally (although | ||
14356 | not always) performs <dfn>offline</dfn> operations in the CVS working copy. | ||
14357 | Offline operations are those that can be done without contacting the | ||
14358 | repository, while still leaving the working copy in a consistent state | ||
14359 | for the next time the repository is contacted. Offline behavior can be | ||
14360 | extremely handy when your network connection to the repository is slow | ||
14361 | or unreliable. | ||
14362 | |||
14363 | <p>The cvsutils programs are listed below in approximate order of | ||
14364 | usefulness (according to my opinion), with the more useful ones coming | ||
14365 | first. Coincidentally, this also arranges them by safety. Safety is an | ||
14366 | issue because some of these utilities can, in their normal course of | ||
14367 | operation, cause you to lose local modifications or files from your | ||
14368 | working copy. Therefore, read the descriptions carefully before using | ||
14369 | these utilities. | ||
14370 | |||
14371 | <p>This documentation is accurate as of Version 0.1.4. Be sure to read the | ||
14372 | README file in any later versions for more up-to-date information. | ||
14373 | |||
14374 | <ul> | ||
14375 | <li><a href="#cvsu">cvsu</a>: | ||
14376 | <li><a href="#cvsdo">cvsdo</a>: | ||
14377 | <li><a href="#cvschroot">cvschroot</a>: | ||
14378 | <li><a href="#cvsrmadm">cvsrmadm</a>: | ||
14379 | <li><a href="#cvspurge">cvspurge</a>: | ||
14380 | <li><a href="#cvsdiscard">cvsdiscard</a>: | ||
14381 | <li><a href="#cvsco">cvsco</a>: | ||
14382 | <li><a href="#cvsdate">cvsdate</a>: | ||
14383 | </ul> | ||
14384 | |||
14385 | <p><hr> | ||
14386 | Node:<a name="cvsu">cvsu</a>, | ||
14387 | Next:<a rel=next href="#cvsdo">cvsdo</a>, | ||
14388 | Up:<a rel=up href="#cvsutils_--_General_Utilities_For_Use_With_CVS">cvsutils -- General Utilities For Use With CVS</a> | ||
14389 | <br> | ||
14390 | |||
14391 | <h3>cvsu</h3> | ||
14392 | |||
14393 | <p>Danger level: None | ||
14394 | |||
14395 | <p>Contacts repository: No | ||
14396 | |||
14397 | <p>This does an offline cvs update by comparing the timestamps of files on | ||
14398 | disk with their timestamps recorded in CVS/Entries. You can thus tell | ||
14399 | which files have been locally modified and which files are not known to | ||
14400 | be under CVS control. Unlike <code>cvs update</code>, cvsu does not bring | ||
14401 | down changes from the repository. | ||
14402 | |||
14403 | <p>Although it can take various options, cvsu is most commonly invoked | ||
14404 | without any options: | ||
14405 | |||
14406 | <pre>floss$ cvsu | ||
14407 | ? ./bar | ||
14408 | ? ./chapter-10.html | ||
14409 | M ./chapter-10.sgml | ||
14410 | D ./out | ||
14411 | ? ./safe.sh | ||
14412 | D ./tools | ||
14413 | </pre> | ||
14414 | |||
14415 | <p>The left-side codes are like the output of cvs update, except that | ||
14416 | <code>D</code> means directory. This example shows that chapter-10.sgml has | ||
14417 | been modified locally. What the example doesn't show is that cvsu ran | ||
14418 | instantly, whereas a normal cvs update would have required half a minute | ||
14419 | or so over my slow modem line. Run | ||
14420 | |||
14421 | <pre>floss$ cvsu --help | ||
14422 | </pre> | ||
14423 | |||
14424 | <p>to see a list of options. | ||
14425 | |||
14426 | <p><hr> | ||
14427 | Node:<a name="cvsdo">cvsdo</a>, | ||
14428 | Next:<a rel=next href="#cvschroot">cvschroot</a>, | ||
14429 | Previous:<a rel=previous href="#cvsu">cvsu</a>, | ||
14430 | Up:<a rel=up href="#cvsutils_--_General_Utilities_For_Use_With_CVS">cvsutils -- General Utilities For Use With CVS</a> | ||
14431 | <br> | ||
14432 | |||
14433 | <h3>cvsdo</h3> | ||
14434 | |||
14435 | <p>Danger level: Low to none | ||
14436 | |||
14437 | <p>Contacts repository: No | ||
14438 | |||
14439 | <p>This can simulate the working copy effects of cvs add and cvs remove, | ||
14440 | but without contacting the repository. Of course, you'd still have to | ||
14441 | commit the changes to make them take effect in the repository, but at | ||
14442 | least the add and remove commands themselves can be sped up this way. | ||
14443 | Here's how to use it | ||
14444 | |||
14445 | <pre>floss$ cvsdo add FILENAME | ||
14446 | </pre> | ||
14447 | |||
14448 | <p>or | ||
14449 | |||
14450 | <pre>floss$ cvsdo remove FILENAME | ||
14451 | </pre> | ||
14452 | |||
14453 | <p>To see a list of further options, run: | ||
14454 | |||
14455 | <pre>floss$ cvsdo --help | ||
14456 | </pre> | ||
14457 | |||
14458 | <p><hr> | ||
14459 | Node:<a name="cvschroot">cvschroot</a>, | ||
14460 | Next:<a rel=next href="#cvsrmadm">cvsrmadm</a>, | ||
14461 | Previous:<a rel=previous href="#cvsdo">cvsdo</a>, | ||
14462 | Up:<a rel=up href="#cvsutils_--_General_Utilities_For_Use_With_CVS">cvsutils -- General Utilities For Use With CVS</a> | ||
14463 | <br> | ||
14464 | |||
14465 | <h3>cvschroot</h3> | ||
14466 | |||
14467 | <p>Danger level: Low | ||
14468 | |||
14469 | <p>Contacts repository: No | ||
14470 | |||
14471 | <p>This deals with a repository move by tweaking the working copy to point | ||
14472 | to the new repository. This is useful when a repository is copied en | ||
14473 | masse to a new location. When that happens, none of the revisions are | ||
14474 | affected, but the CVS/Root (and possibly the CVS/Repository) file of | ||
14475 | every working copy must be updated to point to the new location. Using | ||
14476 | cvschroot is a lot faster than checking out a new copy. Another | ||
14477 | advantage is that it doesn't lose your local changes. | ||
14478 | |||
14479 | <p>Usage: | ||
14480 | |||
14481 | <pre>floss$ cvschroot NEW_REPOS | ||
14482 | </pre> | ||
14483 | |||
14484 | <p>For example: | ||
14485 | |||
14486 | <pre>floss$ cvschroot :pserver:newuser@newhost.wherever.com:/home/cvs/myproj | ||
14487 | </pre> | ||
14488 | |||
14489 | <p><hr> | ||
14490 | Node:<a name="cvsrmadm">cvsrmadm</a>, | ||
14491 | Next:<a rel=next href="#cvspurge">cvspurge</a>, | ||
14492 | Previous:<a rel=previous href="#cvschroot">cvschroot</a>, | ||
14493 | Up:<a rel=up href="#cvsutils_--_General_Utilities_For_Use_With_CVS">cvsutils -- General Utilities For Use With CVS</a> | ||
14494 | <br> | ||
14495 | |||
14496 | <h3>cvsrmadm</h3> | ||
14497 | |||
14498 | <p>Danger level: Low to medium | ||
14499 | |||
14500 | <p>Contacts repository: No | ||
14501 | |||
14502 | <p>This removes all of the CVS/ administrative subdirectories in your | ||
14503 | working copy, leaving behind a tree similar to that created by cvs | ||
14504 | export. | ||
14505 | |||
14506 | <p>Although you won't lose any local changes by using cvsrmadm, your | ||
14507 | working copy will no longer be a working copy. | ||
14508 | |||
14509 | <p>Use with caution. | ||
14510 | |||
14511 | <p><hr> | ||
14512 | Node:<a name="cvspurge">cvspurge</a>, | ||
14513 | Next:<a rel=next href="#cvsdiscard">cvsdiscard</a>, | ||
14514 | Previous:<a rel=previous href="#cvsrmadm">cvsrmadm</a>, | ||
14515 | Up:<a rel=up href="#cvsutils_--_General_Utilities_For_Use_With_CVS">cvsutils -- General Utilities For Use With CVS</a> | ||
14516 | <br> | ||
14517 | |||
14518 | <h3>cvspurge</h3> | ||
14519 | |||
14520 | <p>Danger level: Medium | ||
14521 | |||
14522 | <p>Contacts repository: No | ||
14523 | |||
14524 | <p>This removes all non-CVS-controlled files in your working copy. It does | ||
14525 | not undo any local changes to CVS-controlled files. | ||
14526 | |||
14527 | <p>Use with caution. | ||
14528 | |||
14529 | <p><hr> | ||
14530 | Node:<a name="cvsdiscard">cvsdiscard</a>, | ||
14531 | Next:<a rel=next href="#cvsco">cvsco</a>, | ||
14532 | Previous:<a rel=previous href="#cvspurge">cvspurge</a>, | ||
14533 | Up:<a rel=up href="#cvsutils_--_General_Utilities_For_Use_With_CVS">cvsutils -- General Utilities For Use With CVS</a> | ||
14534 | <br> | ||
14535 | |||
14536 | <h3>cvsdiscard</h3> | ||
14537 | |||
14538 | <p>Danger level: Medium to high | ||
14539 | |||
14540 | <p>Contacts repository: Maybe | ||
14541 | |||
14542 | <p>This is the complement of cvspurge. Instead of removing unknown files | ||
14543 | but keeping your local changes, cvsdiscard undoes any local changes | ||
14544 | (replacing those files with fresh copies from the repository), but keeps | ||
14545 | unknown files. | ||
14546 | |||
14547 | <p>Use with extreme caution. | ||
14548 | |||
14549 | <p><hr> | ||
14550 | Node:<a name="cvsco">cvsco</a>, | ||
14551 | Next:<a rel=next href="#cvsdate">cvsdate</a>, | ||
14552 | Previous:<a rel=previous href="#cvsdiscard">cvsdiscard</a>, | ||
14553 | Up:<a rel=up href="#cvsutils_--_General_Utilities_For_Use_With_CVS">cvsutils -- General Utilities For Use With CVS</a> | ||
14554 | <br> | ||
14555 | |||
14556 | <h3>cvsco</h3> | ||
14557 | |||
14558 | <p>Danger level: High | ||
14559 | |||
14560 | <p>Contacts repository: Maybe | ||
14561 | |||
14562 | <p>This is the union of cvspurge and cvsdiscard. It undoes any local | ||
14563 | changes and removes unknown files from the working copy. | ||
14564 | |||
14565 | <p>Use with truly paranoid caution. | ||
14566 | |||
14567 | <p><hr> | ||
14568 | Node:<a name="cvsdate">cvsdate</a>, | ||
14569 | Previous:<a rel=previous href="#cvsco">cvsco</a>, | ||
14570 | Up:<a rel=up href="#cvsutils_--_General_Utilities_For_Use_With_CVS">cvsutils -- General Utilities For Use With CVS</a> | ||
14571 | <br> | ||
14572 | |||
14573 | <h3>cvsdate</h3> | ||
14574 | |||
14575 | <p>This script is apparently incomplete and possibly may never be finished. | ||
14576 | (See the README file for details.) | ||
14577 | |||
14578 | <p><hr> | ||
14579 | Node:<a name="cvs2cl_--_Generate_GNU-Style_ChangeLogs">cvs2cl -- Generate GNU-Style ChangeLogs</a>, | ||
14580 | Next:<a rel=next href="#cvslock_--_Lock_Repositories_For_Atomicity">cvslock -- Lock Repositories For Atomicity</a>, | ||
14581 | Previous:<a rel=previous href="#cvsutils_--_General_Utilities_For_Use_With_CVS">cvsutils -- General Utilities For Use With CVS</a>, | ||
14582 | Up:<a rel=up href="#Third-Party_Tools">Third-Party Tools</a> | ||
14583 | <br> | ||
14584 | |||
14585 | <h2>cvs2cl - Generate GNU-Style ChangeLogs</h2> | ||
14586 | |||
14587 | <p>Depends on: Perl | ||
14588 | |||
14589 | <p>URL: <a href="http://www.red-bean.com/~kfogel/cvs2cl.shtml">http://www.red-bean.com/~kfogel/cvs2cl.shtml</a> | ||
14590 | |||
14591 | <p>cvs2cl.pl condenses and reformats the output of cvs log to create a | ||
14592 | GNU-style ChangeLog file for your project. ChangeLogs are | ||
14593 | chronologically organized documents showing the change history of a | ||
14594 | project, with a format designed specifically for human-readability (see | ||
14595 | the following examples). | ||
14596 | |||
14597 | <p>The problem with the <code>cvs log</code> command is that it presents its | ||
14598 | output on a per-file basis, with no acknowledgement that the same log | ||
14599 | message, appearing at roughly the same time in different files, implies | ||
14600 | that those revisions were all part of a single commit. Thus, reading | ||
14601 | over log output to get an overview of project development is a hopeless | ||
14602 | task - you can really only see the history of one file at a time. | ||
14603 | |||
14604 | <p>In the ChangeLog produced by cvs2cl.pl, identical log messages are | ||
14605 | unified, so that a single commit involving a group of files shows up as | ||
14606 | one entry. For example: | ||
14607 | |||
14608 | <pre>floss$ cvs2cl.pl -r | ||
14609 | cvs log: Logging . | ||
14610 | cvs log: Logging a-subdir | ||
14611 | cvs log: Logging a-subdir/subsubdir | ||
14612 | cvs log: Logging b-subdir | ||
14613 | floss$ cat ChangeLog | ||
14614 | ... | ||
14615 | 1999-08-29 05:44 jrandom | ||
14616 | |||
14617 | * README (1.6), hello.c (2.1), a-subdir/whatever.c (2.1), | ||
14618 | a-subdir/subsubdir/fish.c (2.1): Committing from pcl-cvs 2.9, just | ||
14619 | for kicks. | ||
14620 | |||
14621 | 1999-08-23 22:48 jrandom | ||
14622 | |||
14623 | * README (1.5): [no log message] | ||
14624 | |||
14625 | 1999-08-22 19:34 jrandom | ||
14626 | |||
14627 | * README (1.4): trivial change | ||
14628 | ... | ||
14629 | floss$ | ||
14630 | </pre> | ||
14631 | |||
14632 | <p>The first entry shows that four files were committed at once, with the | ||
14633 | log message, "Committing from pcl-cvs 2.9, just for kicks.". (The -r | ||
14634 | option was used to show the revision number of each file associated with | ||
14635 | that log message.) | ||
14636 | |||
14637 | <p>Like CVS itself, cvs2cl.pl takes the current directory as an implied | ||
14638 | argument but acts on individual files if given file name arguments. | ||
14639 | Following are a few of the most commonly used options. | ||
14640 | |||
14641 | <ul> | ||
14642 | |||
14643 | <li> | ||
14644 | <code>h</code>, <code>--help</code> | ||
14645 | |||
14646 | <p>Show usage (including a complete list of options). | ||
14647 | |||
14648 | </p><li> | ||
14649 | <code>-r</code>, <code>--revisions</code> | ||
14650 | |||
14651 | <p>Show revision numbers in output. If used in conjunction with -b, | ||
14652 | branches are shown as BRANCHNAME.N, where N is the revision on the | ||
14653 | branch. | ||
14654 | |||
14655 | </p><li> | ||
14656 | <code>-t</code>, <code>--tags</code> | ||
14657 | |||
14658 | <p>Show tags (symbolic names) for revisions that have them. | ||
14659 | |||
14660 | </p><li> | ||
14661 | <code>-b</code>, <code>--branches</code> | ||
14662 | |||
14663 | <p>Show the branch name for revisions on that branch. (See also -r.) | ||
14664 | |||
14665 | </p><li> | ||
14666 | <code>-g OPTS</code>, <code>--global-opts OPTS</code> | ||
14667 | |||
14668 | <p>Pass OPTS as global arguments to cvs. Internally, cvs2cl.pl invokes cvs | ||
14669 | to get the raw log data; thus, OPTS are passed right after the cvs in | ||
14670 | that invocation. For example, to achieve quiet behavior and | ||
14671 | compression, you can do this: | ||
14672 | |||
14673 | <pre>floss$ cvs2cl.pl -g "-Q -z3" | ||
14674 | </pre> | ||
14675 | |||
14676 | </p><li> | ||
14677 | <code>-l OPTS</code>, <code>--log-opts OPTS</code> | ||
14678 | |||
14679 | <p>Similar to -g, except that OPTS are passed as command options instead of | ||
14680 | global options. To generate a ChangeLog showing only commits that | ||
14681 | happened between July 26 and August 15, you can do this: | ||
14682 | |||
14683 | <pre>floss$ cvs2cl.pl -l "'-d1999-07-26<1999-08-15'" | ||
14684 | </pre> | ||
14685 | |||
14686 | <p>Notice the double-layered quoting - this is necessary in Unix because | ||
14687 | the shell that invokes cvs log (inside cvs2cl.pl) interprets the | ||
14688 | <code><</code> as a shell redirection symbol. Therefore, the quotes have to | ||
14689 | be passed as part of the argument, making it necessary to surround the | ||
14690 | whole thing with an additional set of quotes. | ||
14691 | |||
14692 | </p><li> | ||
14693 | <code>-d</code>, <code>--distributed</code> | ||
14694 | |||
14695 | <p>Put an individual ChangeLog in each subdirectory, covering only commits | ||
14696 | in that subdirectory (as opposed to building one ChangeLog that covers | ||
14697 | the directory where cvs2cl.pl was invoked and all subdirectories | ||
14698 | underneath it). | ||
14699 | |||
14700 | </ul> | ||
14701 | |||
14702 | <p><hr> | ||
14703 | Node:<a name="cvsq_--_Queue_CVS_Commands_For_Later_Connection">cvsq -- Queue CVS Commands For Later Connection</a>, | ||
14704 | Next:<a rel=next href="#Other_Packages">Other Packages</a>, | ||
14705 | Previous:<a rel=previous href="#cvslock_--_Lock_Repositories_For_Atomicity">cvslock -- Lock Repositories For Atomicity</a>, | ||
14706 | Up:<a rel=up href="#Third-Party_Tools">Third-Party Tools</a> | ||
14707 | <br> | ||
14708 | |||
14709 | <h2>cvsq - Queue CVS Commands For Later Connection</h2> | ||
14710 | |||
14711 | <p>Depends on: Bash | ||
14712 | |||
14713 | <p>URL: <a href="http://www.volny.cz/v.slavik/lt/cvsq.html">http://www.volny.cz/v.slavik/lt/cvsq.html</a> | ||
14714 | |||
14715 | <p>Vaclav Slavik <v.slavik@volny.cz>, the author of cvsq, has this to say | ||
14716 | about it: | ||
14717 | |||
14718 | <p>cvsq stands for "cvs queued" and it is a small bash script that wraps | ||
14719 | around Cyclic's CVS. It makes working with CVS repository a bit easier | ||
14720 | for people connected via dial-up, because it can queue CVS commands and | ||
14721 | pass them to "real cvs" later. | ||
14722 | |||
14723 | <p>For example, you can commit files immediately after editing them, when being | ||
14724 | offline, so you don't forget about them: | ||
14725 | |||
14726 | <pre> cvsq commit -m "change 1" file1.c | ||
14727 | cvsq commit -m "change 2" file2.c | ||
14728 | cvsq commit -m "change 3" file3.c | ||
14729 | </pre> | ||
14730 | |||
14731 | <p>And then, when you go online, you simply type | ||
14732 | |||
14733 | <pre> cvsq upload | ||
14734 | </pre> | ||
14735 | |||
14736 | <p>and all changes will be commited into the repository. If uploading of a | ||
14737 | particular file fails, it won't be lost - instead, you'll see error | ||
14738 | message and the file will stay in cvsq queue. | ||
14739 | |||
14740 | <p>You can use cvsq even for commands that make no sense when offline - in | ||
14741 | that case, the command is immediately passed to cvs and not queued. For | ||
14742 | example, you can call cvsq update and it won't be put into the queue but | ||
14743 | executed immediately. In fact, you can start using cvsq as a | ||
14744 | replacement for cvs. | ||
14745 | |||
14746 | <p>cvsq is in public domain. | ||
14747 | |||
14748 | <p><hr> | ||
14749 | Node:<a name="cvslock_--_Lock_Repositories_For_Atomicity">cvslock -- Lock Repositories For Atomicity</a>, | ||
14750 | Next:<a rel=next href="#cvsq_--_Queue_CVS_Commands_For_Later_Connection">cvsq -- Queue CVS Commands For Later Connection</a>, | ||
14751 | Previous:<a rel=previous href="#cvs2cl_--_Generate_GNU-Style_ChangeLogs">cvs2cl -- Generate GNU-Style ChangeLogs</a>, | ||
14752 | Up:<a rel=up href="#Third-Party_Tools">Third-Party Tools</a> | ||
14753 | <br> | ||
14754 | |||
14755 | <h2>cvslock - Lock Repositories For Atomicity</h2> | ||
14756 | |||
14757 | <p>Depends on: C compiler for installation; nothing for runtime | ||
14758 | |||
14759 | <p>URL: <a href="ftp://riemann.iam.uni-bonn.de/pub/users/roessler/cvslock/">ftp://riemann.iam.uni-bonn.de/pub/users/roessler/cvslock/</a> | ||
14760 | |||
14761 | <p>This program locks a CVS repository (either for reading or writing) in | ||
14762 | the same way that CVS does, so that CVS will honor the locks. This can | ||
14763 | be useful when, for example, you need to make a copy of the whole | ||
14764 | repository and want to avoid catching parts of commits or other people's | ||
14765 | lockfiles. | ||
14766 | |||
14767 | <p>The cvslock distribution is packaged extremely well and can be installed | ||
14768 | according to the usual GNU procedures. Here's a transcript of an | ||
14769 | install session: | ||
14770 | |||
14771 | <pre>floss$ zcat cvslock-0.1.tar.gz | tar xvf - | ||
14772 | cvslock-0.1/ | ||
14773 | cvslock-0.1/Makefile.in | ||
14774 | cvslock-0.1/README | ||
14775 | cvslock-0.1/COPYING | ||
14776 | cvslock-0.1/Makefile.am | ||
14777 | cvslock-0.1/acconfig.h | ||
14778 | cvslock-0.1/aclocal.m4 | ||
14779 | cvslock-0.1/config.h.in | ||
14780 | cvslock-0.1/configure | ||
14781 | cvslock-0.1/configure.in | ||
14782 | cvslock-0.1/install-sh | ||
14783 | cvslock-0.1/missing | ||
14784 | cvslock-0.1/mkinstalldirs | ||
14785 | cvslock-0.1/stamp-h.in | ||
14786 | cvslock-0.1/cvslock.c | ||
14787 | cvslock-0.1/cvslock.1 | ||
14788 | cvslock-0.1/snprintf.c | ||
14789 | cvslock-0.1/cvslssh | ||
14790 | cvslock-0.1/VERSION | ||
14791 | floss$ cd cvslock-0.1 | ||
14792 | floss$ ./configure | ||
14793 | ... | ||
14794 | floss$ make | ||
14795 | gcc -DHAVE_CONFIG_H -I. -I. -I. -g -O2 -c cvslock.c | ||
14796 | gcc -g -O2 -o cvslock cvslock.o | ||
14797 | floss$ make install | ||
14798 | ... | ||
14799 | floss$ | ||
14800 | </pre> | ||
14801 | |||
14802 | <p>(Note that you may have to do the make install step as root). | ||
14803 | |||
14804 | <p>Now, cvslock is installed as /usr/local/bin/cvslock. When you invoke | ||
14805 | it, you can specify the repository with -d or via the $CVSROOT | ||
14806 | environment variable, just as with CVS itself (the following examples | ||
14807 | use -d). Its only required argument is the name of the directory to | ||
14808 | lock, relative to the top of the repository. That directory and all of | ||
14809 | its subdirectories will be locked. In this example, there are no | ||
14810 | subdirectories, so only one lockfile is created: | ||
14811 | |||
14812 | <pre>floss$ ls /usr/local/newrepos/myproj/b-subdir/ | ||
14813 | random.c,v | ||
14814 | floss$ cvslock -d /usr/local/newrepos myproj/b-subdir | ||
14815 | floss$ ls /usr/local/newrepos/myproj/b-subdir/ | ||
14816 | #cvs.rfl.cvslock.floss.27378 random.c,v | ||
14817 | floss$ cvslock -u -p 27378 -d /usr/local/newrepos myproj/b-subdir | ||
14818 | floss$ ls /usr/local/newrepos/myproj/b-subdir/ | ||
14819 | random.c,v | ||
14820 | floss$ | ||
14821 | </pre> | ||
14822 | |||
14823 | <p>Notice that when I cleared the lock (-u for <code>unlock</code>), I had to | ||
14824 | specify <code>-p 27378</code>. That's because cvslock uses Unix process | ||
14825 | IDs when creating lockfile names to ensure that its locks are unique. | ||
14826 | When you unlock, you have to tell cvslock which lock instance to remove, | ||
14827 | even if there's only one instance present. Thus, the -p flag tells | ||
14828 | cvslock which previous instance of itself it's cleaning up after (you | ||
14829 | can use -p with or without -u, though). | ||
14830 | |||
14831 | <p>If you're going to be working in the repository for a while, doing | ||
14832 | various operations directly in the file system, you can use the -s | ||
14833 | option to have cvslock start up a new shell for you. It then consults | ||
14834 | the <code>$SHELL</code> environment variable in your current shell to | ||
14835 | determine which shell to use: | ||
14836 | |||
14837 | <pre>floss$ cvslock -s -d /usr/local/newrepos myproj | ||
14838 | </pre> | ||
14839 | |||
14840 | <p>The locks remain present until you exit the shell, at which time they | ||
14841 | are automatically removed. You can also use the -c option to execute a | ||
14842 | command while the repository is locked. Just as with -s, the locks are | ||
14843 | put in place before the command starts and removed when it's finished. | ||
14844 | In the following example, we lock the repository just long enough to | ||
14845 | display a listing of all of the lockfiles: | ||
14846 | |||
14847 | <pre>floss$ cvslock -c 'find . -name "*cvslock*" ' -d /usr/local/newrepos myproj | ||
14848 | cvslock: '/usr/local/newrepos/myproj' locked successfully. | ||
14849 | cvslock: Starting 'find . -name "*cvslock*" -print'... | ||
14850 | ./a-subdir/subsubdir/#cvs.rfl.cvslock.floss.27452 | ||
14851 | ./a-subdir/#cvs.rfl.cvslock.floss.27452 | ||
14852 | ./b-subdir/#cvs.rfl.cvslock.floss.27452 | ||
14853 | ./#cvs.rfl.cvslock.floss.27452 | ||
14854 | floss$ find /usr/local/newrepos/myproj -name "*cvslock*" -print | ||
14855 | floss$ | ||
14856 | </pre> | ||
14857 | |||
14858 | <p>The command (the argument to the -c option) is run with the specified | ||
14859 | repository directory as its working directory. | ||
14860 | |||
14861 | <p>By default, cvslock creates read-locks. You can tell it to use | ||
14862 | write-locks instead by passing the -W option. (You can pass -R to | ||
14863 | specify read-locks, but that's the default anyway.) Always remove any | ||
14864 | locks when you're finished, so that other users' CVS processes don't | ||
14865 | wait needlessly. | ||
14866 | |||
14867 | <p>Note that cvslock must be run on the machine where the repository | ||
14868 | resides - you cannot specify a remote repository. (For more | ||
14869 | information, run <code>man cvslock</code>, which is a manual page | ||
14870 | installed when you ran <code>make install</code>.) | ||
14871 | |||
14872 | <p><hr> | ||
14873 | Node:<a name="Other_Packages">Other Packages</a>, | ||
14874 | Next:<a rel=next href="#Writing_Your_Own_Tools">Writing Your Own Tools</a>, | ||
14875 | Previous:<a rel=previous href="#cvsq_--_Queue_CVS_Commands_For_Later_Connection">cvsq -- Queue CVS Commands For Later Connection</a>, | ||
14876 | Up:<a rel=up href="#Third-Party_Tools">Third-Party Tools</a> | ||
14877 | <br> | ||
14878 | |||
14879 | <h2>Other Packages</h2> | ||
14880 | |||
14881 | <p>Many other third-party packages are available for CVS. Following are | ||
14882 | pointers to some of these. | ||
14883 | |||
14884 | <h2>CVSUp (Part Of The FreeBSD Project)</h2> | ||
14885 | |||
14886 | <p>CVSUp is an efficient generic mirroring tool with special built-in | ||
14887 | support for mirroring CVS repositories. The FreeBSD operating system | ||
14888 | uses it to distribute changes from their master repository, so users can | ||
14889 | keep up to date conveniently. | ||
14890 | |||
14891 | <p>For more information on CVSUp in general, check out | ||
14892 | <a href="http://www.polstra.com/projects/freeware/CVSup/">http://www.polstra.com/projects/freeware/CVSup/</a>. | ||
14893 | |||
14894 | <p>For its use in FreeBSD in particular, see | ||
14895 | <a href="http://www.freebsd.org/handbook/synching.html#CVSUP">http://www.freebsd.org/handbook/synching.html#CVSUP</a>. | ||
14896 | |||
14897 | <h2>CVSWeb: A Web Interface To CVS Repositories</h2> | ||
14898 | |||
14899 | <p>CVSWeb provides a Web interface to browsing CVS repositories. A more | ||
14900 | accurate name might be "RCSWeb", because what it actually does is allow | ||
14901 | you to browse revisions directly in a repository, viewing log messages | ||
14902 | and diffs. Although I've never found it to be a particularly compelling | ||
14903 | interface myself, I have to admit that it is intuitive enough and a lot | ||
14904 | of sites use it. | ||
14905 | |||
14906 | <p>Although the software was originally written by Bill Fenner, the version | ||
14907 | most actively under development right now seems to be Henner Zeller's, | ||
14908 | at <a href="http://linux.fh-heilbronn.de/~zeller/cgi/cvsweb.cgi/">http://linux.fh-heilbronn.de/~zeller/cgi/cvsweb.cgi/</a>. | ||
14909 | |||
14910 | <p>You may also want to visit Fenner's original site at | ||
14911 | <a href="http://www.freebsd.org/~fenner/cvsweb/">http://www.freebsd.org/~fenner/cvsweb/</a> and possibly Cyclic | ||
14912 | Software's summary of the CVSWeb scene at | ||
14913 | <a href="http://www.cyclic.com/cyclic-pages/web-cvsweb.html">http://www.cyclic.com/cyclic-pages/web-cvsweb.html</a>. | ||
14914 | |||
14915 | <p>Finally, if you'd like to see CVSWeb in action, a good example can be | ||
14916 | browsed at <a href="http://sourceware.cygnus.com/cgi-bin/cvsweb.cgi/">http://sourceware.cygnus.com/cgi-bin/cvsweb.cgi/</a>. | ||
14917 | |||
14918 | <h2>The CVS contrib/ Directory</h2> | ||
14919 | |||
14920 | <p>As mentioned in <a href="#Repository_Administration">Repository Administration</a>, a number of third-party | ||
14921 | tools are shipped with CVS and are collected in the contrib/ directory. | ||
14922 | Although I'm not aware of any formal rule for determining which tools | ||
14923 | are distributed with CVS, an effort may be in process to gather most of | ||
14924 | the widely used third-party tools and put them in contrib/ so people | ||
14925 | know where to find them. Until that happens, the best way to find such | ||
14926 | tools is to look in contrib/, look at various CVS Web sites, and ask on | ||
14927 | the mailing list. | ||
14928 | |||
14929 | <p><hr> | ||
14930 | Node:<a name="Writing_Your_Own_Tools">Writing Your Own Tools</a>, | ||
14931 | Previous:<a rel=previous href="#Other_Packages">Other Packages</a>, | ||
14932 | Up:<a rel=up href="#Third-Party_Tools">Third-Party Tools</a> | ||
14933 | <br> | ||
14934 | |||
14935 | <h2>Writing Your Own Tools</h2> | ||
14936 | |||
14937 | <p>CVS can at times seem like a bewildering collection of improvised | ||
14938 | standards. There's RCS format, various output formats (history, | ||
14939 | annotate, log, update, and so on), several repository administrative | ||
14940 | file formats, working copy administrative file formats, the | ||
14941 | client/server protocol, the lockfile protocol.... (Are you numb yet? I | ||
14942 | could keep going, you know.) | ||
14943 | |||
14944 | <p>Fortunately, these standards remain fairly consistent from release to | ||
14945 | release - so if you're trying to write a tool to work with CVS, you at | ||
14946 | least don't have to worry about hitting a moving target. For every | ||
14947 | internal standard, there are usually a few people on the | ||
14948 | <a href="mailto:info-cvs@gnu.org">info-cvs@gnu.org</a> mailing list who know it extremely well | ||
14949 | (several of them helped me out during the writing of this book). There | ||
14950 | is also the documentation that comes with the CVS distribution | ||
14951 | (especially doc/cvs.texinfo, doc/cvsclient.texi, and doc/RCSFILES). | ||
14952 | Finally, there is the CVS source code itself, the last word on any | ||
14953 | question of implementation or behavior. | ||
14954 | |||
14955 | <p>With all of this at your disposal, there's no reason to hesitate. If | ||
14956 | you can think of some utility that would make your life with CVS easier, | ||
14957 | go ahead and write it - chances are other people have been wanting it, | ||
14958 | too. Unlike a change to CVS itself, a small, standalone external | ||
14959 | utility can get wide distribution very quickly, resulting in quicker | ||
14960 | feedback for its author and faster bug fixes for all of the users. | ||
14961 | |||
14962 | <p><hr> | ||
14963 | Node:<a name="Index">Index</a>, | ||
14964 | Next:<a rel=next href="#GNU_General_Public_License">GNU General Public License</a>, | ||
14965 | Previous:<a rel=previous href="#Third-Party_Tools">Third-Party Tools</a>, | ||
14966 | Up:<a rel=up href="#Top">Top</a> | ||
14967 | <br> | ||
14968 | |||
14969 | <h1>Index</h1> | ||
14970 | |||
14971 | <p>Sorry, the index is still in progress. | ||
14972 | |||
14973 | <p>Since the online format is searchable anyway, I decided the | ||
14974 | incompleteness of the index need not delay the release of the chapters. | ||
14975 | I hope to have the index finished reasonably soon. Volunteer indexers | ||
14976 | are certainly welcome, too - please email | ||
14977 | <a href="mailto:bug-cvsbook@red-bean.com">bug-cvsbook@red-bean.com</a> if you're interested. | ||
14978 | |||
14979 | <p><hr> | ||
14980 | Node:<a name="GNU_General_Public_License">GNU General Public License</a>, | ||
14981 | Next:<a rel=next href="#GNU_Free_Documentation_License">GNU Free Documentation License</a>, | ||
14982 | Previous:<a rel=previous href="#Index">Index</a>, | ||
14983 | Up:<a rel=up href="#Top">Top</a> | ||
14984 | <br> | ||
14985 | |||
14986 | <h1>GNU General Public License</h1> | ||
14987 | |||
14988 | <pre>GNU General Public License | ||
14989 | |||
14990 | Version 2, June 1991 | ||
14991 | |||
14992 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. | ||
14993 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA | ||
14994 | |||
14995 | Everyone is permitted to copy and distribute verbatim copies | ||
14996 | of this license document, but changing it is not allowed. | ||
14997 | |||
14998 | Preamble | ||
14999 | |||
15000 | The licenses for most software are designed to take away your freedom to | ||
15001 | share and change it. By contrast, the GNU General Public License is intended | ||
15002 | to guarantee your freedom to share and change free software--to make sure | ||
15003 | the software is free for all its users. This General Public License applies | ||
15004 | to most of the Free Software Foundation's software and to any other program | ||
15005 | whose authors commit to using it. (Some other Free Software Foundation | ||
15006 | software is covered by the GNU Library General Public License instead.) You | ||
15007 | can apply it to your programs, too. | ||
15008 | |||
15009 | When we speak of free software, we are referring to freedom, not price. Our | ||
15010 | General Public Licenses are designed to make sure that you have the freedom | ||
15011 | to distribute copies of free software (and charge for this service if you | ||
15012 | wish), that you receive source code or can get it if you want it, that you | ||
15013 | can change the software or use pieces of it in new free programs; and that | ||
15014 | you know you can do these things. | ||
15015 | |||
15016 | To protect your rights, we need to make restrictions that forbid anyone to | ||
15017 | deny you these rights or to ask you to surrender the rights. These | ||
15018 | restrictions translate to certain responsibilities for you if you distribute | ||
15019 | copies of the software, or if you modify it. | ||
15020 | |||
15021 | For example, if you distribute copies of such a program, whether gratis or | ||
15022 | for a fee, you must give the recipients all the rights that you have. You | ||
15023 | must make sure that they, too, receive or can get the source code. And you | ||
15024 | must show them these terms so they know their rights. | ||
15025 | |||
15026 | We protect your rights with two steps: (1) copyright the software, and (2) | ||
15027 | offer you this license which gives you legal permission to copy, distribute | ||
15028 | and/or modify the software. | ||
15029 | |||
15030 | Also, for each author's protection and ours, we want to make certain that | ||
15031 | everyone understands that there is no warranty for this free software. If | ||
15032 | the software is modified by someone else and passed on, we want its | ||
15033 | recipients to know that what they have is not the original, so that any | ||
15034 | problems introduced by others will not reflect on the original authors' | ||
15035 | reputations. | ||
15036 | |||
15037 | Finally, any free program is threatened constantly by software patents. We | ||
15038 | wish to avoid the danger that redistributors of a free program will | ||
15039 | individually obtain patent licenses, in effect making the program | ||
15040 | proprietary. To prevent this, we have made it clear that any patent must be | ||
15041 | licensed for everyone's free use or not licensed at all. | ||
15042 | |||
15043 | The precise terms and conditions for copying, distribution and modification | ||
15044 | follow. | ||
15045 | |||
15046 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION | ||
15047 | |||
15048 | 0. This License applies to any program or other work which contains a notice | ||
15049 | placed by the copyright holder saying it may be distributed under the terms | ||
15050 | of this General Public License. The "Program", below, refers to any such | ||
15051 | program or work, and a "work based on the Program" means either the Program | ||
15052 | or any derivative work under copyright law: that is to say, a work | ||
15053 | containing the Program or a portion of it, either verbatim or with | ||
15054 | modifications and/or translated into another language. (Hereinafter, | ||
15055 | translation is included without limitation in the term "modification".) Each | ||
15056 | licensee is addressed as "you". | ||
15057 | |||
15058 | Activities other than copying, distribution and modification are not covered | ||
15059 | by this License; they are outside its scope. The act of running the Program | ||
15060 | is not restricted, and the output from the Program is covered only if its | ||
15061 | contents constitute a work based on the Program (independent of having been | ||
15062 | made by running the Program). Whether that is true depends on what the | ||
15063 | Program does. | ||
15064 | |||
15065 | 1. You may copy and distribute verbatim copies of the Program's source code | ||
15066 | as you receive it, in any medium, provided that you conspicuously and | ||
15067 | appropriately publish on each copy an appropriate copyright notice and | ||
15068 | disclaimer of warranty; keep intact all the notices that refer to this | ||
15069 | License and to the absence of any warranty; and give any other recipients of | ||
15070 | the Program a copy of this License along with the Program. | ||
15071 | |||
15072 | You may charge a fee for the physical act of transferring a copy, and you | ||
15073 | may at your option offer warranty protection in exchange for a fee. | ||
15074 | |||
15075 | 2. You may modify your copy or copies of the Program or any portion of it, | ||
15076 | thus forming a work based on the Program, and copy and distribute such | ||
15077 | modifications or work under the terms of Section 1 above, provided that you | ||
15078 | also meet all of these conditions: | ||
15079 | |||
15080 | * a) You must cause the modified files to carry prominent notices stating | ||
15081 | that you changed the files and the date of any change. | ||
15082 | |||
15083 | * b) You must cause any work that you distribute or publish, that in | ||
15084 | whole or in part contains or is derived from the Program or any part | ||
15085 | thereof, to be licensed as a whole at no charge to all third parties | ||
15086 | under the terms of this License. | ||
15087 | |||
15088 | * c) If the modified program normally reads commands interactively when | ||
15089 | run, you must cause it, when started running for such interactive use | ||
15090 | in the most ordinary way, to print or display an announcement including | ||
15091 | an appropriate copyright notice and a notice that there is no warranty | ||
15092 | (or else, saying that you provide a warranty) and that users may | ||
15093 | redistribute the program under these conditions, and telling the user | ||
15094 | how to view a copy of this License. (Exception: if the Program itself | ||
15095 | is interactive but does not normally print such an announcement, your | ||
15096 | work based on the Program is not required to print an announcement.) | ||
15097 | |||
15098 | These requirements apply to the modified work as a whole. If identifiable | ||
15099 | sections of that work are not derived from the Program, and can be | ||
15100 | reasonably considered independent and separate works in themselves, then | ||
15101 | this License, and its terms, do not apply to those sections when you | ||
15102 | distribute them as separate works. But when you distribute the same sections | ||
15103 | as part of a whole which is a work based on the Program, the distribution of | ||
15104 | the whole must be on the terms of this License, whose permissions for other | ||
15105 | licensees extend to the entire whole, and thus to each and every part | ||
15106 | regardless of who wrote it. | ||
15107 | |||
15108 | Thus, it is not the intent of this section to claim rights or contest your | ||
15109 | rights to work written entirely by you; rather, the intent is to exercise | ||
15110 | the right to control the distribution of derivative or collective works | ||
15111 | based on the Program. | ||
15112 | |||
15113 | In addition, mere aggregation of another work not based on the Program with | ||
15114 | the Program (or with a work based on the Program) on a volume of a storage | ||
15115 | or distribution medium does not bring the other work under the scope of this | ||
15116 | License. | ||
15117 | |||
15118 | 3. You may copy and distribute the Program (or a work based on it, under | ||
15119 | Section 2) in object code or executable form under the terms of Sections 1 | ||
15120 | and 2 above provided that you also do one of the following: | ||
15121 | |||
15122 | * a) Accompany it with the complete corresponding machine-readable source | ||
15123 | code, which must be distributed under the terms of Sections 1 and 2 | ||
15124 | above on a medium customarily used for software interchange; or, | ||
15125 | |||
15126 | * b) Accompany it with a written offer, valid for at least three years, | ||
15127 | to give any third party, for a charge no more than your cost of | ||
15128 | physically performing source distribution, a complete machine-readable | ||
15129 | copy of the corresponding source code, to be distributed under the | ||
15130 | terms of Sections 1 and 2 above on a medium customarily used for | ||
15131 | software interchange; or, | ||
15132 | |||
15133 | * c) Accompany it with the information you received as to the offer to | ||
15134 | distribute corresponding source code. (This alternative is allowed only | ||
15135 | for noncommercial distribution and only if you received the program in | ||
15136 | object code or executable form with such an offer, in accord with | ||
15137 | Subsection b above.) | ||
15138 | |||
15139 | The source code for a work means the preferred form of the work for making | ||
15140 | modifications to it. For an executable work, complete source code means all | ||
15141 | the source code for all modules it contains, plus any associated interface | ||
15142 | definition files, plus the scripts used to control compilation and | ||
15143 | installation of the executable. However, as a special exception, the source | ||
15144 | code distributed need not include anything that is normally distributed (in | ||
15145 | either source or binary form) with the major components (compiler, kernel, | ||
15146 | and so on) of the operating system on which the executable runs, unless that | ||
15147 | component itself accompanies the executable. | ||
15148 | |||
15149 | If distribution of executable or object code is made by offering access to | ||
15150 | copy from a designated place, then offering equivalent access to copy the | ||
15151 | source code from the same place counts as distribution of the source code, | ||
15152 | even though third parties are not compelled to copy the source along with | ||
15153 | the object code. | ||
15154 | |||
15155 | 4. You may not copy, modify, sublicense, or distribute the Program except as | ||
15156 | expressly provided under this License. Any attempt otherwise to copy, | ||
15157 | modify, sublicense or distribute the Program is void, and will automatically | ||
15158 | terminate your rights under this License. However, parties who have received | ||
15159 | copies, or rights, from you under this License will not have their licenses | ||
15160 | terminated so long as such parties remain in full compliance. | ||
15161 | |||
15162 | 5. You are not required to accept this License, since you have not signed | ||
15163 | it. However, nothing else grants you permission to modify or distribute the | ||
15164 | Program or its derivative works. These actions are prohibited by law if you | ||
15165 | do not accept this License. Therefore, by modifying or distributing the | ||
15166 | Program (or any work based on the Program), you indicate your acceptance of | ||
15167 | this License to do so, and all its terms and conditions for copying, | ||
15168 | distributing or modifying the Program or works based on it. | ||
15169 | |||
15170 | 6. Each time you redistribute the Program (or any work based on the | ||
15171 | Program), the recipient automatically receives a license from the original | ||
15172 | licensor to copy, distribute or modify the Program subject to these terms | ||
15173 | and conditions. You may not impose any further restrictions on the | ||
15174 | recipients' exercise of the rights granted herein. You are not responsible | ||
15175 | for enforcing compliance by third parties to this License. | ||
15176 | |||
15177 | 7. If, as a consequence of a court judgment or allegation of patent | ||
15178 | infringement or for any other reason (not limited to patent issues), | ||
15179 | conditions are imposed on you (whether by court order, agreement or | ||
15180 | otherwise) that contradict the conditions of this License, they do not | ||
15181 | excuse you from the conditions of this License. If you cannot distribute so | ||
15182 | as to satisfy simultaneously your obligations under this License and any | ||
15183 | other pertinent obligations, then as a consequence you may not distribute | ||
15184 | the Program at all. For example, if a patent license would not permit | ||
15185 | royalty-free redistribution of the Program by all those who receive copies | ||
15186 | directly or indirectly through you, then the only way you could satisfy both | ||
15187 | it and this License would be to refrain entirely from distribution of the | ||
15188 | Program. | ||
15189 | |||
15190 | If any portion of this section is held invalid or unenforceable under any | ||
15191 | particular circumstance, the balance of the section is intended to apply and | ||
15192 | the section as a whole is intended to apply in other circumstances. | ||
15193 | |||
15194 | It is not the purpose of this section to induce you to infringe any patents | ||
15195 | or other property right claims or to contest validity of any such claims; | ||
15196 | this section has the sole purpose of protecting the integrity of the free | ||
15197 | software distribution system, which is implemented by public license | ||
15198 | practices. Many people have made generous contributions to the wide range of | ||
15199 | software distributed through that system in reliance on consistent | ||
15200 | application of that system; it is up to the author/donor to decide if he or | ||
15201 | she is willing to distribute software through any other system and a | ||
15202 | licensee cannot impose that choice. | ||
15203 | |||
15204 | This section is intended to make thoroughly clear what is believed to be a | ||
15205 | consequence of the rest of this License. | ||
15206 | |||
15207 | 8. If the distribution and/or use of the Program is restricted in certain | ||
15208 | countries either by patents or by copyrighted interfaces, the original | ||
15209 | copyright holder who places the Program under this License may add an | ||
15210 | explicit geographical distribution limitation excluding those countries, so | ||
15211 | that distribution is permitted only in or among countries not thus excluded. | ||
15212 | In such case, this License incorporates the limitation as if written in the | ||
15213 | body of this License. | ||
15214 | |||
15215 | 9. The Free Software Foundation may publish revised and/or new versions of | ||
15216 | the General Public License from time to time. Such new versions will be | ||
15217 | similar in spirit to the present version, but may differ in detail to | ||
15218 | address new problems or concerns. | ||
15219 | |||
15220 | Each version is given a distinguishing version number. If the Program | ||
15221 | specifies a version number of this License which applies to it and "any | ||
15222 | later version", you have the option of following the terms and conditions | ||
15223 | either of that version or of any later version published by the Free | ||
15224 | Software Foundation. If the Program does not specify a version number of | ||
15225 | this License, you may choose any version ever published by the Free Software | ||
15226 | Foundation. | ||
15227 | |||
15228 | 10. If you wish to incorporate parts of the Program into other free programs | ||
15229 | whose distribution conditions are different, write to the author to ask for | ||
15230 | permission. For software which is copyrighted by the Free Software | ||
15231 | Foundation, write to the Free Software Foundation; we sometimes make | ||
15232 | exceptions for this. Our decision will be guided by the two goals of | ||
15233 | preserving the free status of all derivatives of our free software and of | ||
15234 | promoting the sharing and reuse of software generally. | ||
15235 | |||
15236 | NO WARRANTY | ||
15237 | |||
15238 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR | ||
15239 | THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN | ||
15240 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES | ||
15241 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED | ||
15242 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
15243 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO | ||
15244 | THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM | ||
15245 | PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR | ||
15246 | CORRECTION. | ||
15247 | |||
15248 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING | ||
15249 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR | ||
15250 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, | ||
15251 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING | ||
15252 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO | ||
15253 | LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR | ||
15254 | THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER | ||
15255 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE | ||
15256 | POSSIBILITY OF SUCH DAMAGES. | ||
15257 | |||
15258 | END OF TERMS AND CONDITIONS | ||
15259 | |||
15260 | How to Apply These Terms to Your New Programs | ||
15261 | |||
15262 | If you develop a new program, and you want it to be of the greatest possible | ||
15263 | use to the public, the best way to achieve this is to make it free software | ||
15264 | which everyone can redistribute and change under these terms. | ||
15265 | |||
15266 | To do so, attach the following notices to the program. It is safest to | ||
15267 | attach them to the start of each source file to most effectively convey the | ||
15268 | exclusion of warranty; and each file should have at least the "copyright" | ||
15269 | line and a pointer to where the full notice is found. | ||
15270 | |||
15271 | one line to give the program's name and an idea of what it does. | ||
15272 | Copyright (C) yyyy name of author | ||
15273 | |||
15274 | This program is free software; you can redistribute it and/or | ||
15275 | modify it under the terms of the GNU General Public License | ||
15276 | as published by the Free Software Foundation; either version 2 | ||
15277 | of the License, or (at your option) any later version. | ||
15278 | |||
15279 | This program is distributed in the hope that it will be useful, | ||
15280 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15281 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15282 | GNU General Public License for more details. | ||
15283 | |||
15284 | You should have received a copy of the GNU General Public License | ||
15285 | along with this program; if not, write to the Free Software | ||
15286 | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
15287 | |||
15288 | Also add information on how to contact you by electronic and paper mail. | ||
15289 | |||
15290 | If the program is interactive, make it output a short notice like this when | ||
15291 | it starts in an interactive mode: | ||
15292 | |||
15293 | Gnomovision version 69, Copyright (C) yyyy name of author | ||
15294 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details | ||
15295 | type `show w'. This is free software, and you are welcome | ||
15296 | to redistribute it under certain conditions; type `show c' | ||
15297 | for details. | ||
15298 | |||
15299 | The hypothetical commands `show w' and `show c' should show the appropriate | ||
15300 | parts of the General Public License. Of course, the commands you use may be | ||
15301 | called something other than `show w' and `show c'; they could even be | ||
15302 | mouse-clicks or menu items--whatever suits your program. | ||
15303 | |||
15304 | You should also get your employer (if you work as a programmer) or your | ||
15305 | school, if any, to sign a "copyright disclaimer" for the program, if | ||
15306 | necessary. Here is a sample; alter the names: | ||
15307 | |||
15308 | Yoyodyne, Inc., hereby disclaims all copyright | ||
15309 | interest in the program `Gnomovision' | ||
15310 | (which makes passes at compilers) written | ||
15311 | by James Hacker. | ||
15312 | |||
15313 | signature of Ty Coon, 1 April 1989 | ||
15314 | Ty Coon, President of Vice | ||
15315 | |||
15316 | This General Public License does not permit incorporating your program into | ||
15317 | proprietary programs. If your program is a subroutine library, you may | ||
15318 | consider it more useful to permit linking proprietary applications with the | ||
15319 | library. If this is what you want to do, use the GNU Library General Public | ||
15320 | License instead of this License. | ||
15321 | |||
15322 | </pre> | ||
15323 | |||
15324 | <p><hr> | ||
15325 | Node:<a name="GNU_Free_Documentation_License">GNU Free Documentation License</a>, | ||
15326 | Previous:<a rel=previous href="#GNU_General_Public_License">GNU General Public License</a>, | ||
15327 | Up:<a rel=up href="#Top">Top</a> | ||
15328 | <br> | ||
15329 | |||
15330 | <h1>GNU Free Documentation License</h1> | ||
15331 | |||
15332 | <pre>GNU Free Documentation License | ||
15333 | |||
15334 | Version 1.1, March 2000 | ||
15335 | |||
15336 | Copyright (C) 2000 Free Software Foundation, Inc. | ||
15337 | 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
15338 | Everyone is permitted to copy and distribute verbatim copies | ||
15339 | of this license document, but changing it is not allowed. | ||
15340 | |||
15341 | 0. PREAMBLE | ||
15342 | |||
15343 | The purpose of this License is to make a manual, textbook, or other written | ||
15344 | document "free" in the sense of freedom: to assure everyone the effective | ||
15345 | freedom to copy and redistribute it, with or without modifying it, either | ||
15346 | commercially or noncommercially. Secondarily, this License preserves for the | ||
15347 | author and publisher a way to get credit for their work, while not being | ||
15348 | considered responsible for modifications made by others. | ||
15349 | |||
15350 | This License is a kind of "copyleft", which means that derivative works of | ||
15351 | the document must themselves be free in the same sense. It complements the | ||
15352 | GNU General Public License, which is a copyleft license designed for free | ||
15353 | software. | ||
15354 | |||
15355 | We have designed this License in order to use it for manuals for free | ||
15356 | software, because free software needs free documentation: a free program | ||
15357 | should come with manuals providing the same freedoms that the software does. | ||
15358 | But this License is not limited to software manuals; it can be used for any | ||
15359 | textual work, regardless of subject matter or whether it is published as a | ||
15360 | printed book. We recommend this License principally for works whose purpose | ||
15361 | is instruction or reference. | ||
15362 | |||
15363 | 1. APPLICABILITY AND DEFINITIONS | ||
15364 | |||
15365 | This License applies to any manual or other work that contains a notice | ||
15366 | placed by the copyright holder saying it can be distributed under the terms | ||
15367 | of this License. The "Document", below, refers to any such manual or work. | ||
15368 | Any member of the public is a licensee, and is addressed as "you". | ||
15369 | |||
15370 | A "Modified Version" of the Document means any work containing the Document | ||
15371 | or a portion of it, either copied verbatim, or with modifications and/or | ||
15372 | translated into another language. | ||
15373 | |||
15374 | A "Secondary Section" is a named appendix or a front-matter section of the | ||
15375 | Document that deals exclusively with the relationship of the publishers or | ||
15376 | authors of the Document to the Document's overall subject (or to related | ||
15377 | matters) and contains nothing that could fall directly within that overall | ||
15378 | subject. (For example, if the Document is in part a textbook of mathematics, | ||
15379 | a Secondary Section may not explain any mathematics.) The relationship could | ||
15380 | be a matter of historical connection with the subject or with related | ||
15381 | matters, or of legal, commercial, philosophical, ethical or political | ||
15382 | position regarding them. | ||
15383 | |||
15384 | The "Invariant Sections" are certain Secondary Sections whose titles are | ||
15385 | designated, as being those of Invariant Sections, in the notice that says | ||
15386 | that the Document is released under this License. | ||
15387 | |||
15388 | The "Cover Texts" are certain short passages of text that are listed, as | ||
15389 | Front-Cover Texts or Back-Cover Texts, in the notice that says that the | ||
15390 | Document is released under this License. | ||
15391 | |||
15392 | A "Transparent" copy of the Document means a machine-readable copy, | ||
15393 | represented in a format whose specification is available to the general | ||
15394 | public, whose contents can be viewed and edited directly and | ||
15395 | straightforwardly with generic text editors or (for images composed of | ||
15396 | pixels) generic paint programs or (for drawings) some widely available | ||
15397 | drawing editor, and that is suitable for input to text formatters or for | ||
15398 | automatic translation to a variety of formats suitable for input to text | ||
15399 | formatters. A copy made in an otherwise Transparent file format whose markup | ||
15400 | has been designed to thwart or discourage subsequent modification by readers | ||
15401 | is not Transparent. A copy that is not "Transparent" is called "Opaque". | ||
15402 | |||
15403 | Examples of suitable formats for Transparent copies include plain ASCII | ||
15404 | without markup, Texinfo input format, LaTeX input format, SGML or XML using | ||
15405 | a publicly available DTD, and standard-conforming simple HTML designed for | ||
15406 | human modification. Opaque formats include PostScript, PDF, proprietary | ||
15407 | formats that can be read and edited only by proprietary word processors, | ||
15408 | SGML or XML for which the DTD and/or processing tools are not generally | ||
15409 | available, and the machine-generated HTML produced by some word processors | ||
15410 | for output purposes only. | ||
15411 | |||
15412 | The "Title Page" means, for a printed book, the title page itself, plus such | ||
15413 | following pages as are needed to hold, legibly, the material this License | ||
15414 | requires to appear in the title page. For works in formats which do not have | ||
15415 | any title page as such, "Title Page" means the text near the most prominent | ||
15416 | appearance of the work's title, preceding the beginning of the body of the | ||
15417 | text. | ||
15418 | |||
15419 | 2. VERBATIM COPYING | ||
15420 | |||
15421 | You may copy and distribute the Document in any medium, either commercially | ||
15422 | or noncommercially, provided that this License, the copyright notices, and | ||
15423 | the license notice saying this License applies to the Document are | ||
15424 | reproduced in all copies, and that you add no other conditions whatsoever to | ||
15425 | those of this License. You may not use technical measures to obstruct or | ||
15426 | control the reading or further copying of the copies you make or distribute. | ||
15427 | However, you may accept compensation in exchange for copies. If you | ||
15428 | distribute a large enough number of copies you must also follow the | ||
15429 | conditions in section 3. | ||
15430 | |||
15431 | You may also lend copies, under the same conditions stated above, and you | ||
15432 | may publicly display copies. | ||
15433 | |||
15434 | 3. COPYING IN QUANTITY | ||
15435 | |||
15436 | If you publish printed copies of the Document numbering more than 100, and | ||
15437 | the Document's license notice requires Cover Texts, you must enclose the | ||
15438 | copies in covers that carry, clearly and legibly, all these Cover Texts: | ||
15439 | Front-Cover Texts on the front cover, and Back-Cover Texts on the back | ||
15440 | cover. Both covers must also clearly and legibly identify you as the | ||
15441 | publisher of these copies. The front cover must present the full title with | ||
15442 | all words of the title equally prominent and visible. You may add other | ||
15443 | material on the covers in addition. Copying with changes limited to the | ||
15444 | covers, as long as they preserve the title of the Document and satisfy these | ||
15445 | conditions, can be treated as verbatim copying in other respects. | ||
15446 | |||
15447 | If the required texts for either cover are too voluminous to fit legibly, | ||
15448 | you should put the first ones listed (as many as fit reasonably) on the | ||
15449 | actual cover, and continue the rest onto adjacent pages. | ||
15450 | |||
15451 | If you publish or distribute Opaque copies of the Document numbering more | ||
15452 | than 100, you must either include a machine-readable Transparent copy along | ||
15453 | with each Opaque copy, or state in or with each Opaque copy a | ||
15454 | publicly-accessible computer-network location containing a complete | ||
15455 | Transparent copy of the Document, free of added material, which the general | ||
15456 | network-using public has access to download anonymously at no charge using | ||
15457 | public-standard network protocols. If you use the latter option, you must | ||
15458 | take reasonably prudent steps, when you begin distribution of Opaque copies | ||
15459 | in quantity, to ensure that this Transparent copy will remain thus | ||
15460 | accessible at the stated location until at least one year after the last | ||
15461 | time you distribute an Opaque copy (directly or through your agents or | ||
15462 | retailers) of that edition to the public. | ||
15463 | |||
15464 | It is requested, but not required, that you contact the authors of the | ||
15465 | Document well before redistributing any large number of copies, to give them | ||
15466 | a chance to provide you with an updated version of the Document. | ||
15467 | |||
15468 | 4. MODIFICATIONS | ||
15469 | |||
15470 | You may copy and distribute a Modified Version of the Document under the | ||
15471 | conditions of sections 2 and 3 above, provided that you release the Modified | ||
15472 | Version under precisely this License, with the Modified Version filling the | ||
15473 | role of the Document, thus licensing distribution and modification of the | ||
15474 | Modified Version to whoever possesses a copy of it. In addition, you must do | ||
15475 | these things in the Modified Version: | ||
15476 | |||
15477 | * A. Use in the Title Page (and on the covers, if any) a title distinct | ||
15478 | from that of the Document, and from those of previous versions (which | ||
15479 | should, if there were any, be listed in the History section of the | ||
15480 | Document). You may use the same title as a previous version if the | ||
15481 | original publisher of that version gives permission. | ||
15482 | * B. List on the Title Page, as authors, one or more persons or entities | ||
15483 | responsible for authorship of the modifications in the Modified | ||
15484 | Version, together with at least five of the principal authors of the | ||
15485 | Document (all of its principal authors, if it has less than five). | ||
15486 | * C. State on the Title page the name of the publisher of the Modified | ||
15487 | Version, as the publisher. | ||
15488 | * D. Preserve all the copyright notices of the Document. | ||
15489 | * E. Add an appropriate copyright notice for your modifications adjacent | ||
15490 | to the other copyright notices. | ||
15491 | * F. Include, immediately after the copyright notices, a license notice | ||
15492 | giving the public permission to use the Modified Version under the | ||
15493 | terms of this License, in the form shown in the Addendum below. | ||
15494 | * G. Preserve in that license notice the full lists of Invariant Sections | ||
15495 | and required Cover Texts given in the Document's license notice. | ||
15496 | * H. Include an unaltered copy of this License. | ||
15497 | * I. Preserve the section entitled "History", and its title, and add to | ||
15498 | it an item stating at least the title, year, new authors, and publisher | ||
15499 | of the Modified Version as given on the Title Page. If there is no | ||
15500 | section entitled "History" in the Document, create one stating the | ||
15501 | title, year, authors, and publisher of the Document as given on its | ||
15502 | Title Page, then add an item describing the Modified Version as stated | ||
15503 | in the previous sentence. | ||
15504 | * J. Preserve the network location, if any, given in the Document for | ||
15505 | public access to a Transparent copy of the Document, and likewise the | ||
15506 | network locations given in the Document for previous versions it was | ||
15507 | based on. These may be placed in the "History" section. You may omit a | ||
15508 | network location for a work that was published at least four years | ||
15509 | before the Document itself, or if the original publisher of the version | ||
15510 | it refers to gives permission. | ||
15511 | * K. In any section entitled "Acknowledgements" or "Dedications", | ||
15512 | preserve the section's title, and preserve in the section all the | ||
15513 | substance and tone of each of the contributor acknowledgements and/or | ||
15514 | dedications given therein. | ||
15515 | * L. Preserve all the Invariant Sections of the Document, unaltered in | ||
15516 | their text and in their titles. Section numbers or the equivalent are | ||
15517 | not considered part of the section titles. | ||
15518 | * M. Delete any section entitled "Endorsements". Such a section may not | ||
15519 | be included in the Modified Version. | ||
15520 | * N. Do not retitle any existing section as "Endorsements" or to conflict | ||
15521 | in title with any Invariant Section. | ||
15522 | |||
15523 | If the Modified Version includes new front-matter sections or appendices | ||
15524 | that qualify as Secondary Sections and contain no material copied from the | ||
15525 | Document, you may at your option designate some or all of these sections as | ||
15526 | invariant. To do this, add their titles to the list of Invariant Sections in | ||
15527 | the Modified Version's license notice. These titles must be distinct from | ||
15528 | any other section titles. | ||
15529 | |||
15530 | You may add a section entitled "Endorsements", provided it contains nothing | ||
15531 | but endorsements of your Modified Version by various parties--for example, | ||
15532 | statements of peer review or that the text has been approved by an | ||
15533 | organization as the authoritative definition of a standard. | ||
15534 | |||
15535 | You may add a passage of up to five words as a Front-Cover Text, and a | ||
15536 | passage of up to 25 words as a Back-Cover Text, to the end of the list of | ||
15537 | Cover Texts in the Modified Version. Only one passage of Front-Cover Text | ||
15538 | and one of Back-Cover Text may be added by (or through arrangements made by) | ||
15539 | any one entity. If the Document already includes a cover text for the same | ||
15540 | cover, previously added by you or by arrangement made by the same entity you | ||
15541 | are acting on behalf of, you may not add another; but you may replace the | ||
15542 | old one, on explicit permission from the previous publisher that added the | ||
15543 | old one. | ||
15544 | |||
15545 | The author(s) and publisher(s) of the Document do not by this License give | ||
15546 | permission to use their names for publicity for or to assert or imply | ||
15547 | endorsement of any Modified Version. | ||
15548 | |||
15549 | 5. COMBINING DOCUMENTS | ||
15550 | |||
15551 | You may combine the Document with other documents released under this | ||
15552 | License, under the terms defined in section 4 above for modified versions, | ||
15553 | provided that you include in the combination all of the Invariant Sections | ||
15554 | of all of the original documents, unmodified, and list them all as Invariant | ||
15555 | Sections of your combined work in its license notice. | ||
15556 | |||
15557 | The combined work need only contain one copy of this License, and multiple | ||
15558 | identical Invariant Sections may be replaced with a single copy. If there | ||
15559 | are multiple Invariant Sections with the same name but different contents, | ||
15560 | make the title of each such section unique by adding at the end of it, in | ||
15561 | parentheses, the name of the original author or publisher of that section if | ||
15562 | known, or else a unique number. Make the same adjustment to the section | ||
15563 | titles in the list of Invariant Sections in the license notice of the | ||
15564 | combined work. | ||
15565 | |||
15566 | In the combination, you must combine any sections entitled "History" in the | ||
15567 | various original documents, forming one section entitled "History"; likewise | ||
15568 | combine any sections entitled "Acknowledgements", and any sections entitled | ||
15569 | "Dedications". You must delete all sections entitled "Endorsements." | ||
15570 | |||
15571 | 6. COLLECTIONS OF DOCUMENTS | ||
15572 | |||
15573 | You may make a collection consisting of the Document and other documents | ||
15574 | released under this License, and replace the individual copies of this | ||
15575 | License in the various documents with a single copy that is included in the | ||
15576 | collection, provided that you follow the rules of this License for verbatim | ||
15577 | copying of each of the documents in all other respects. | ||
15578 | |||
15579 | You may extract a single document from such a collection, and distribute it | ||
15580 | individually under this License, provided you insert a copy of this License | ||
15581 | into the extracted document, and follow this License in all other respects | ||
15582 | regarding verbatim copying of that document. | ||
15583 | |||
15584 | 7. AGGREGATION WITH INDEPENDENT WORKS | ||
15585 | |||
15586 | A compilation of the Document or its derivatives with other separate and | ||
15587 | independent documents or works, in or on a volume of a storage or | ||
15588 | distribution medium, does not as a whole count as a Modified Version of the | ||
15589 | Document, provided no compilation copyright is claimed for the compilation. | ||
15590 | Such a compilation is called an "aggregate", and this License does not apply | ||
15591 | to the other self-contained works thus compiled with the Document, on | ||
15592 | account of their being thus compiled, if they are not themselves derivative | ||
15593 | works of the Document. If the Cover Text requirement of section 3 is | ||
15594 | applicable to these copies of the Document, then if the Document is less | ||
15595 | than one quarter of the entire aggregate, the Document's Cover Texts may be | ||
15596 | placed on covers that surround only the Document within the aggregate. | ||
15597 | Otherwise they must appear on covers around the whole aggregate. | ||
15598 | |||
15599 | 8. TRANSLATION | ||
15600 | |||
15601 | Translation is considered a kind of modification, so you may distribute | ||
15602 | translations of the Document under the terms of section 4. Replacing | ||
15603 | Invariant Sections with translations requires special permission from their | ||
15604 | copyright holders, but you may include translations of some or all Invariant | ||
15605 | Sections in addition to the original versions of these Invariant Sections. | ||
15606 | You may include a translation of this License provided that you also include | ||
15607 | the original English version of this License. In case of a disagreement | ||
15608 | between the translation and the original English version of this License, | ||
15609 | the original English version will prevail. | ||
15610 | |||
15611 | 9. TERMINATION | ||
15612 | |||
15613 | You may not copy, modify, sublicense, or distribute the Document except as | ||
15614 | expressly provided for under this License. Any other attempt to copy, | ||
15615 | modify, sublicense or distribute the Document is void, and will | ||
15616 | automatically terminate your rights under this License. However, parties who | ||
15617 | have received copies, or rights, from you under this License will not have | ||
15618 | their licenses terminated so long as such parties remain in full compliance. | ||
15619 | |||
15620 | 10. FUTURE REVISIONS OF THIS LICENSE | ||
15621 | |||
15622 | The Free Software Foundation may publish new, revised versions of the GNU | ||
15623 | Free Documentation License from time to time. Such new versions will be | ||
15624 | similar in spirit to the present version, but may differ in detail to | ||
15625 | address new problems or concerns. See http://www.gnu.org/copyleft/. | ||
15626 | |||
15627 | Each version of the License is given a distinguishing version number. If the | ||
15628 | Document specifies that a particular numbered version of this License "or | ||
15629 | any later version" applies to it, you have the option of following the terms | ||
15630 | and conditions either of that specified version or of any later version that | ||
15631 | has been published (not as a draft) by the Free Software Foundation. If the | ||
15632 | Document does not specify a version number of this License, you may choose | ||
15633 | any version ever published (not as a draft) by the Free Software Foundation. | ||
15634 | |||
15635 | How to use this License for your documents | ||
15636 | |||
15637 | To use this License in a document you have written, include a copy of the | ||
15638 | License in the document and put the following copyright and license notices | ||
15639 | just after the title page: | ||
15640 | |||
15641 | Copyright (c) YEAR YOUR NAME. | ||
15642 | Permission is granted to copy, distribute and/or modify this document | ||
15643 | under the terms of the GNU Free Documentation License, Version 1.1 | ||
15644 | or any later version published by the Free Software Foundation; | ||
15645 | with the Invariant Sections being LIST THEIR TITLES, with the | ||
15646 | Front-Cover Texts being LIST, and with the Back-Cover Texts being LIST. | ||
15647 | A copy of the license is included in the section entitled "GNU | ||
15648 | Free Documentation License". | ||
15649 | |||
15650 | If you have no Invariant Sections, write "with no Invariant Sections" | ||
15651 | instead of saying which ones are invariant. If you have no Front-Cover | ||
15652 | Texts, write "no Front-Cover Texts" instead of "Front-Cover Texts being | ||
15653 | LIST"; likewise for Back-Cover Texts. | ||
15654 | |||
15655 | If your document contains nontrivial examples of program code, we recommend | ||
15656 | releasing these examples in parallel under your choice of free software | ||
15657 | license, such as the GNU General Public License, to permit their use in free | ||
15658 | software. | ||
15659 | |||
15660 | </pre> | ||
15661 | |||
15662 | </body></html> | ||
15663 | |||
diff --git a/development/tmake_ref.html b/development/tmake_ref.html new file mode 100644 index 0000000..4bf82b3 --- a/dev/null +++ b/development/tmake_ref.html | |||
@@ -0,0 +1,478 @@ | |||
1 | <!doctype HTML public "-//W3C//DTD HTML 3.2//EN"> | ||
2 | <html><head><title> | ||
3 | Reference Manual - tmake | ||
4 | </title></head><body bgcolor="#ffffff"> | ||
5 | <p><h1 align=center>Reference Manual - tmake</h1> | ||
6 | |||
7 | <hr> | ||
8 | <h2>Project Variable Reference</h2> | ||
9 | |||
10 | <h4><a name="ALL_DEPS"></a>ALL_DEPS</h4> | ||
11 | Specifies additional dependencies for the makefile target "all:".<p> | ||
12 | |||
13 | |||
14 | <h4><a name="CLEAN_FILES"></a>CLEAN_FILES</h4> | ||
15 | Specifies additional files to be removed for "make clean".<p> | ||
16 | Example:<pre> | ||
17 | CLEAN_FILES = core *~ | ||
18 | </pre> | ||
19 | |||
20 | |||
21 | <h4><a name="CONFIG"></a>CONFIG</h4> | ||
22 | Sets the make configuration. It tells the tmake templates what compiler | ||
23 | options to use and which extra libraries to link in.<p> | ||
24 | These options control the compilation flags: | ||
25 | <p> | ||
26 | <table border="0"> | ||
27 | <tr> | ||
28 | <td> </td> | ||
29 | <td>release</td> | ||
30 | <td> </td> | ||
31 | <td>Compile with optimization enabled, ignored if | ||
32 | "debug" is specified.</td> | ||
33 | </tr> | ||
34 | <tr> | ||
35 | <td> </td> | ||
36 | <td>debug</td> | ||
37 | <td> </td> | ||
38 | <td>Compile with debug options enabled.</td> | ||
39 | </tr> | ||
40 | <tr> | ||
41 | <td> </td> | ||
42 | <td>warn_on</td> | ||
43 | <td> </td> | ||
44 | <td>The compiler should emit more warnings than normally, ignored if | ||
45 | "warn_off" is specified.</td> | ||
46 | </tr> | ||
47 | <tr> | ||
48 | <td> </td> | ||
49 | <td>warn_off</td> | ||
50 | <td> </td> | ||
51 | <td>The compiler should emit no warnings or as few as possible.</td> | ||
52 | </tr> | ||
53 | </table> | ||
54 | |||
55 | <p> | ||
56 | These options defines the application/library type: | ||
57 | <p> | ||
58 | <table border="0"> | ||
59 | <tr> | ||
60 | <td> </td> | ||
61 | <td>qt</td> | ||
62 | <td> </td> | ||
63 | <td>The target is a Qt application/library and requires Qt header | ||
64 | files/library.</td> | ||
65 | </tr> | ||
66 | <tr> | ||
67 | <td> </td> | ||
68 | <td>opengl</td> | ||
69 | <td> </td> | ||
70 | <td>The target requires the OpenGL (or Mesa) headers/libraries.</td> | ||
71 | </tr> | ||
72 | <tr> | ||
73 | <td> </td> | ||
74 | <td>x11</td> | ||
75 | <td> </td> | ||
76 | <td>The target is a X11 application (app.t only).</td> | ||
77 | </tr> | ||
78 | <tr> | ||
79 | <td> </td> | ||
80 | <td>windows</td> | ||
81 | <td> </td> | ||
82 | <td>The target is a Win32 window application (app.t only).</td> | ||
83 | </tr> | ||
84 | <tr> | ||
85 | <td> </td> | ||
86 | <td>console</td> | ||
87 | <td> </td> | ||
88 | <td>The target is a Win32 console application (app.t only).</td> | ||
89 | </tr> | ||
90 | <tr> | ||
91 | <td> </td> | ||
92 | <td>dll</td> | ||
93 | <td> </td> | ||
94 | <td>The target is a shared object/DLL (app.t only).</td> | ||
95 | </tr> | ||
96 | <tr> | ||
97 | <td> </td> | ||
98 | <td>staticlib</td> | ||
99 | <td> </td> | ||
100 | <td>The target is a static library (lib.t only).</td> | ||
101 | </tr> | ||
102 | <tr> | ||
103 | <td> </td> | ||
104 | <td>thread</td> | ||
105 | <td> </td> | ||
106 | <td>The target is a multi-threaded application/library.</td> | ||
107 | </tr> | ||
108 | </table> | ||
109 | |||
110 | |||
111 | <h4><a name="DEFINES"></a>DEFINES</h4> | ||
112 | Specifies C/C++ macros (-D compiler option). On Windows you need | ||
113 | to let DEFINES contain "QT_DLL" if you are building a Qt program | ||
114 | which should link with the Qt DLL. | ||
115 | |||
116 | |||
117 | <h4><a name="DEF_FILE"></a>DEF_FILE</h4> | ||
118 | Win32/app.t only: Specifies a .def file. | ||
119 | |||
120 | |||
121 | <h4><a name="DESTDIR"></a>DESTDIR</h4> | ||
122 | Specifies where to put the target file. | ||
123 | Example:<pre> | ||
124 | DESTDIR = ../../lib | ||
125 | </pre> | ||
126 | You must create this directory before running make. | ||
127 | |||
128 | |||
129 | <h4><a name="DISTFILES"></a>DISTFILES</h4> | ||
130 | Adds other files to the distribution archive ("dist target"). | ||
131 | The source files and project file are always included in the | ||
132 | distribution archive. | ||
133 | Example:<pre> | ||
134 | DISTFILES = CHANGES README | ||
135 | </pre> | ||
136 | |||
137 | |||
138 | <h4><a name="HEADERS"></a>HEADERS</h4> | ||
139 | Defines the header files of the project. | ||
140 | |||
141 | |||
142 | <h4><a name="INCPATH"></a>INCPATH</h4> | ||
143 | This variable is generated from <code>INCLUDEPATH</code>. The ';' or ':' | ||
144 | separators have been replaced by ' ' (single space). This makes it | ||
145 | easier to split. qtapp.t and other templates expand | ||
146 | <code>INCPATH</code> to set -I options for the C++ compiler. | ||
147 | |||
148 | |||
149 | <h4><a name="INCLUDEPATH"></a>INCLUDEPATH</h4> | ||
150 | This variable specifies the #include directories. It can be set in the | ||
151 | project file, or by the <a href="#AddIncludePath">AddIncludePath()</a> | ||
152 | function.<p> | ||
153 | Example:<pre> | ||
154 | INCLUDEPATH = c:\msdev\include d:\stl\include | ||
155 | </pre> | ||
156 | Use ';' or space as the directory separator. | ||
157 | |||
158 | |||
159 | <h4><a name="LIBS"></a>LIBS</h4> | ||
160 | Defines additional libraries to be linked in when creating an application | ||
161 | or a shared library. You probably want to use a platform qualifier since | ||
162 | libraries are specified differently on Unix and Win32.<p> | ||
163 | Example:<pre> | ||
164 | unix:LIBS = -lXext -lm | ||
165 | win32:LIBS = ole32.lib | ||
166 | </pre> | ||
167 | |||
168 | |||
169 | <h4><a name="MOC_DIR"></a>MOC_DIR</h4> | ||
170 | Specifies where to put the temporary moc output files. By default they | ||
171 | are stored in the directory where the moc input files are. | ||
172 | <p> | ||
173 | Example:<pre> | ||
174 | MOC_DIR = tmp | ||
175 | </pre> | ||
176 | You must create this directory before running make. | ||
177 | <p> | ||
178 | See also: <a href="#OBJECTS_DIR">OBJECTS_DIR</a>. | ||
179 | |||
180 | |||
181 | <h4><a name="OBJECTS"></a>OBJECTS</h4> | ||
182 | This varialble is generated from <code>SOURCES</code> by the StdInit() function. | ||
183 | The extension of each source file has been replaced by .o (Unix) or .obj | ||
184 | (Win32).<p> | ||
185 | Example:<pre> | ||
186 | SOURCES = a.x b.y | ||
187 | </pre> | ||
188 | Then <code>OBJECTS</code> become "a.o b.o" on Unix and "a.obj b.obj" on | ||
189 | Win32. | ||
190 | |||
191 | |||
192 | <h4><a name="OBJECTS_DIR"></a>OBJECTS_DIR</h4> | ||
193 | Specifies where to put object files. By default they are stored in | ||
194 | the directory where the source files are.<p> | ||
195 | Example:<pre> | ||
196 | OBJECTS_DIR = tmp | ||
197 | </pre> | ||
198 | You must create this directory before running make. | ||
199 | <p> | ||
200 | See also: <a href="#MOC_DIR">MOC_DIR</a>. | ||
201 | |||
202 | |||
203 | <h4><a name="OBJMOC"></a>OBJMOC</h4> | ||
204 | This variable is generated by the <a href="#StdInit">StdInit()</a> function if | ||
205 | <code>$moc_aware</code> is true. <code>OBJMOC</code> contains the name of | ||
206 | all intermediate moc object files.<p> | ||
207 | Example:<pre> | ||
208 | HEADERS = demo.h | ||
209 | SOURCES = demo.cpp main.cpp | ||
210 | </pre> | ||
211 | If <tt>demo.h</tt> and <tt>main.cpp</tt> define classes that use signals | ||
212 | and slots (i.e. the <code>Q_OBJECT</code> "keyword" is found in these two | ||
213 | files), <code>OBJMOC</code> becomes:<pre> | ||
214 | OBJMOC = moc_demo.obj | ||
215 | </pre> | ||
216 | See also: <a href="#SRCMOC">SRCMOC</a>. | ||
217 | |||
218 | |||
219 | <h4><a name="PROJECT"></a>PROJECT</h4> | ||
220 | This is the name of the project. It defaults to the name of the project | ||
221 | file, excluding the .pro extension. | ||
222 | |||
223 | |||
224 | <h4><a name="RC_FILE"></a>RC_FILE</h4> | ||
225 | Win32/app.t only: Specifies a .rc file. Cannot be used with the RES_FILE | ||
226 | variable. | ||
227 | |||
228 | |||
229 | <h4><a name="RES_FILE"></a>RES_FILE</h4> | ||
230 | Win32/app.t only: Specifies a .res file. You can either specify a | ||
231 | .rc file or one or more .res files. | ||
232 | |||
233 | |||
234 | <h4><a name="SOURCES"></a>SOURCES</h4> | ||
235 | Defines the source files of the project. | ||
236 | |||
237 | |||
238 | <h4><a name="SRCMOC"></a>SRCMOC</h4> | ||
239 | This variable is generated by the <a href="#StdInit">StdInit()</a> function if | ||
240 | <code>CONFIG</code> contains "qt". <code>SRCMOC</code> contains the name of | ||
241 | all intermediate moc files.<p> | ||
242 | Example:<pre> | ||
243 | HEADERS = demo.h | ||
244 | SOURCES = demo.cpp main.cpp | ||
245 | </pre> | ||
246 | If <tt>demo.h</tt> and <tt>main.cpp</tt> define classes that use signals | ||
247 | and slots (i.e. the <code>Q_OBJECT</code> "keyword" is found in these two | ||
248 | files), <code>SRCMOC</code> becomes:<pre> | ||
249 | SRCMOC = moc_demo.cpp main.moc | ||
250 | </pre> | ||
251 | See also: <a href="#OBJMOC">OBJMOC</a>. | ||
252 | |||
253 | |||
254 | <h4><a name="TARGET"></a>TARGET</h4> | ||
255 | Sets the makefile target, i.e. what program to build. | ||
256 | |||
257 | |||
258 | <h4><a name="TEMPLATE"></a>TEMPLATE</h4> | ||
259 | Sets the default template. This can be overridden by the tmake -t | ||
260 | <a href="tmake.html#usage">option</a>. | ||
261 | |||
262 | |||
263 | <h4><a name="TMAKE_CC"></a>TMAKE_CC</h4> | ||
264 | Contains the name of the compiler. | ||
265 | |||
266 | |||
267 | <h4><a name="TMAKE_CFLAGS"></a>TMAKE_CFLAGS</h4> | ||
268 | Contains the default compiler flags. | ||
269 | |||
270 | |||
271 | <h4><a name="TMAKE_FILEVARS"></a>TMAKE_FILEVARS</h4> | ||
272 | Tells tmake which variables contain file names. This is because tmake | ||
273 | on Windows replace the directory separator / with \. | ||
274 | |||
275 | |||
276 | <hr> | ||
277 | <h2>Function Reference</h2> | ||
278 | This section contains a brief description of some important | ||
279 | tmake functions used by the templates. | ||
280 | |||
281 | |||
282 | <h3><a name="AddIncludePath"></a>AddIncludePath(path)</h3> | ||
283 | Adds <em>path</em> to the include path variable, | ||
284 | <a href="#INCLUDEPATH">INCLUDEPATH</a>. The include path is used | ||
285 | for two purposes:<ol> | ||
286 | <li>Searching files when generating include dependencies. | ||
287 | <li>Setting -I options for the C/C++ compiler. | ||
288 | </ol> | ||
289 | <p> | ||
290 | Example:<pre> | ||
291 | #$ AddIncludePath('$QTDIR/include;/local/include'); | ||
292 | </pre> | ||
293 | |||
294 | |||
295 | <h3>BuildMocObj(objects,sources)</h3> | ||
296 | Creates build rules for moc source files. Generates | ||
297 | include dependencies.<p> | ||
298 | Example:<pre> | ||
299 | #$ BuildMocObj($project{"OBJMOC"},$project{"SRCMOC"}); | ||
300 | </pre>Output:<pre> | ||
301 | moc_hello.o: moc_hello.cpp \ | ||
302 | hello.h \ | ||
303 | ... | ||
304 | </pre> | ||
305 | |||
306 | <h3>BuildMocSrc(files)</h3> | ||
307 | Creates moc source files from C++ files containing classes that | ||
308 | define signals and slots. For a header file <tt>x.h</tt>, the | ||
309 | generated moc file is called <tt>moc_x.h</tt>. For a source file | ||
310 | <tt>y.cpp</tt>, the generates moc file is called <tt>y.moc</tt> and | ||
311 | should be #include'd by <tt>y.cpp</tt>.<p> | ||
312 | Example:<pre> | ||
313 | #$ BuildMocSrc($project{"HEADERS"}); | ||
314 | #$ BuildMocSrc($project{"SOURCES"}); | ||
315 | </pre>Output:<pre> | ||
316 | moc_hello.cpp: hello.h | ||
317 | $(MOC) hello.h -o moc_hello.cpp | ||
318 | </pre> | ||
319 | |||
320 | |||
321 | <h3>BuildObj(objects,sources)</h3> | ||
322 | Creates build rules for source files. Generates | ||
323 | include dependencies.<p> | ||
324 | Example:<pre> | ||
325 | #$ BuildObj($project{"OBJECTS"},$project{"SOURCES"}); | ||
326 | </pre>Output:<pre> | ||
327 | hello.o: hello.cpp \ | ||
328 | hello.h \ | ||
329 | ... | ||
330 | |||
331 | main.o: main.cpp \ | ||
332 | hello.h \ | ||
333 | ... | ||
334 | </pre> | ||
335 | |||
336 | |||
337 | <h3>Config(string)</h3> | ||
338 | Returns true if the <code>CONFIG</code> variable contains the given string. | ||
339 | <p>Example:<pre> | ||
340 | #$ if ( Config("release") { } | ||
341 | </pre> | ||
342 | |||
343 | |||
344 | <h3>DisableOutput()</h3> | ||
345 | Call this function to force tmake to generate no output until | ||
346 | EnableOutput() is called. | ||
347 | <p>Example:<pre> | ||
348 | #$ Config("debug") && DisableOutput(); | ||
349 | Anything here is skipped if CONFIG contains "debug". | ||
350 | #$ Config("debug") && EnableOutput(); | ||
351 | </pre> | ||
352 | |||
353 | |||
354 | <h3>EnableOutput()</h3> | ||
355 | Enables tmake output after DisableOutput() was called. | ||
356 | |||
357 | |||
358 | <h3>Expand(var)</h3> | ||
359 | Expands a project variable. Equivalent to <code>$text = $project{$var}</code>. | ||
360 | <p>Example:<pre> | ||
361 | VERSION = #$ Expand("VERSION"); | ||
362 | </pre>Output:<pre> | ||
363 | VERSION = 1.1 | ||
364 | </pre> | ||
365 | |||
366 | <h3>ExpandGlue(var,prepend,glue,append)</h3> | ||
367 | Expands a $project{} variable, splits on whitespace | ||
368 | and joins with $glue. $prepend is put at the start | ||
369 | of the string and $append is put at the end of the | ||
370 | string. The resulting string ($text) becomes "" if | ||
371 | the project variable is empty or not defined.<p> | ||
372 | Example:<pre> | ||
373 | clear: | ||
374 | #$ ExpandGlue("OBJECTS","-del","\n\t-del ",""); | ||
375 | </pre>Output (Windows NT):<pre> | ||
376 | clear: | ||
377 | -del hello.obj | ||
378 | -del main.obj | ||
379 | </pre> | ||
380 | |||
381 | |||
382 | <h3>ExpandList(var)</h3> | ||
383 | This function is suitable for expanding lists of files. | ||
384 | Equivalent with <code>ExpandGlue($var,""," \\\n\t\t","")</code>.<p> | ||
385 | Example:<pre> | ||
386 | OBJECTS = #$ ExpandList("OBJECTS"); | ||
387 | </pre>Output:<pre> | ||
388 | OBJECTS = hello.o \ | ||
389 | main.o | ||
390 | </pre> | ||
391 | |||
392 | |||
393 | <h3>ExpandPath(var,prepend,glue,append)</h3> | ||
394 | Similar to ExpandGlue, except that it splits the items on a semicolon | ||
395 | instead of space (if the variable contains at least one semicolon). | ||
396 | |||
397 | |||
398 | <h3>IncludeTemplate(file)</h3> | ||
399 | Includes a template file. The ".t" extension is optional.<p> | ||
400 | Example:<pre> | ||
401 | #$ IncludeTemplate("mytemplate"); | ||
402 | </pre> | ||
403 | |||
404 | |||
405 | <h3>Now()</h3> | ||
406 | Sets $text to the current date and time.<p> | ||
407 | Example:<pre> | ||
408 | # Generated at #$ Now() | ||
409 | </pre>Output:<pre> | ||
410 | # Generated at 12:58, 1996/11/19 | ||
411 | </pre> | ||
412 | |||
413 | |||
414 | <h3>Project(strings)</h3> | ||
415 | This is a powerful function for setting and reading project | ||
416 | variables. Returns the resulting project variables (joined with space | ||
417 | between). | ||
418 | <p>Examples:<pre> | ||
419 | # Get a project variable: | ||
420 | $s = Project("TEMPLATE"); -> $s = "TEMPLATE" | ||
421 | |||
422 | # Set a project variable: | ||
423 | Project("TEMPLATE = lib"); -> TEMPLATE = lib | ||
424 | Project("CONFIG =";) -> CONFIG empty | ||
425 | |||
426 | # Append to a project variable: | ||
427 | Project("CONFIG = qt"); -> CONFIG = qt | ||
428 | Project("CONFIG += debug"); -> CONFIG = qt debug | ||
429 | |||
430 | # Append to a project variable if it does not contain the value already: | ||
431 | Project("CONFIG = qt release"); -> CONFIG = qt release | ||
432 | Project("CONFIG *= qt"); -> CONFIG = qt release | ||
433 | Project("CONFIG *= opengl"); -> CONFIG = qt release opengl | ||
434 | |||
435 | # Subtract from a project variable: | ||
436 | Project("THINGS = abc xyz"); -> THINGS = abc xyz | ||
437 | Project("THINGS -= abc"); -> THINGS = xyz | ||
438 | |||
439 | # Search/replace on a project variable: | ||
440 | Project("CONFIG = tq opengl"); -> CONFIG = tq opengl | ||
441 | Project("CONFIG /= s/tq/qt/"); -> CONFIG = qt opengl | ||
442 | |||
443 | # The operations can be performed on several project variables at a time. | ||
444 | |||
445 | Project("TEMPLATE = app", "CONFIG *= opengl", "THINGS += klm"); | ||
446 | </pre> | ||
447 | |||
448 | |||
449 | <h3><a name="ScanProject"></a>ScanProject(file)</h3> | ||
450 | Scans a project file and stores the project variables and values in the | ||
451 | global associative <code>%project</code> array. | ||
452 | |||
453 | |||
454 | <h3><a name="StdInit"></a>StdInit()</h3> | ||
455 | Standard initialization of tmake. StdInit() should be | ||
456 | called from one of the first lines in the template.<p> | ||
457 | |||
458 | This function creates some new project variables:<ul> | ||
459 | <li><code><a href="#OBJECTS">OBJECTS</a></code> | ||
460 | - Object files corresponding to | ||
461 | <code><a href="#SOURCES">SOURCES</a></code>. | ||
462 | <li><code><a href="#SRCMOC">SRCMOC</a></code> - moc source files. | ||
463 | <li><code><a href="#OBJMOC">OBJMOC</a></code> - moc object files. | ||
464 | </ul> | ||
465 | |||
466 | The moc-related variables are created only if <code>CONFIG</code> contains "qt" | ||
467 | |||
468 | |||
469 | <h3>Substitute(string)</h3> | ||
470 | This function takes a string and substitutes any occurrence of $$var | ||
471 | with the actual content of the variable. Returns the substituted string. | ||
472 | Also sets $text. | ||
473 | <p> | ||
474 | Important: Use single quotes around the string, otherwise perl will expand | ||
475 | any $vars it finds. | ||
476 | <p>Example:<pre> | ||
477 | Substitute('Project name: $$PROJECT, uses template $$TEMPLATE'); | ||
478 | </pre> | ||