35 Each of above mentioned tools have sets of feature which it offers in unique way. For this session we are going to concentrate on hg (mercurial). After covering the basics of hg, one can easily try other tools, and use what-ever he/she is most comfortable with. |
35 Each of above mentioned tools have sets of feature which it offers in unique way. For this session we are going to concentrate on hg (mercurial). After covering the basics of hg, one can easily try other tools, and use what-ever he/she is most comfortable with. |
36 |
36 |
37 Learning the Lingo |
37 Learning the Lingo |
38 ================== |
38 ================== |
39 |
39 |
40 Each Version Control uses its own nomenclature for more or less the same features. Here are some of terms which are going to used through out the rest of session: |
40 Here are some of terms which are going to used through out the rest of session: |
41 |
41 |
42 Basic Setup |
42 Basic Setup |
43 ----------- |
43 ----------- |
44 |
44 |
|
45 (should we include at all terms used by vcs's other than hg?) |
|
46 |
45 Repository(repo): |
47 Repository(repo): |
46 The database/folder storing the files. |
48 The folder with all the files. |
47 Server: |
49 Server: |
48 The computer storing the repo. |
50 The system with the main(mother) repo. |
49 Client: |
|
50 The computer connecting to the repo. |
|
51 Working Set/Working Copy: |
|
52 Your local directory of files, where you make changes. This is what is present on client side. |
|
53 Trunk/Main: |
51 Trunk/Main: |
54 The “primary” location for code in the repo. Think of code as a family tree — the “trunk” is the main line. This is generally what is present on server. |
52 The “primary” location for code in the repo. Think of code as a family tree — the “trunk” is the main line. This is generally what is present on server. |
55 |
53 |
56 Basic Actions |
54 Basic Actions |
57 ------------- |
55 ------------- |
58 |
56 |
59 Add: |
57 Add: |
60 Put a file into the repo for the first time, i.e. begin tracking it with Version Control. |
58 Put a file into the repo for the first time, i.e. begin tracking it with Version Control. |
|
59 Head/Tip: |
|
60 The latest version of the repo(Die Hard 4.1) |
61 Revision: |
61 Revision: |
62 What version a file is on. |
62 What version a file is on. |
63 Head/Tip: |
63 Clone: |
64 The latest revision of the repo. |
64 Creating initial copy of the repo onto a local machine. |
65 Check out: |
|
66 Initial download of repo onto machine. |
|
67 Commit: |
65 Commit: |
68 Upload a file to repository(if it has changed). The file gets a new revision number, and people can “check out” the latest one. |
66 Committing the changes done to the repo in terms of contents of the files or adding/removing of the files. |
69 Checking Message: |
67 Logs/History: |
70 A short message describing what was changed. |
68 Logs of all the past changes done to the repo. |
71 Change log/History: |
69 Update: |
72 A list of changes made to a file since it was created. |
70 Updating the local repo with the main one, includes both, adding changing done by us or importing changes done by others. |
73 Update/Sync: |
|
74 Synchronize local files with the latest from the repository on server. This get the latest revisions of all files. |
|
75 Revert: |
71 Revert: |
76 Throw away the local changes and reload the latest version from the repository. |
72 Going back to previous committed state of file. |
77 |
73 |
78 Advanced Actions: |
74 Advanced Actions: |
79 ----------------- |
75 ----------------- |
80 |
76 |
81 Branch: |
77 Branch: |
82 Create a separate copy of a file/folder for private use (bug fixing, testing, etc). |
78 Create a separate copy of the repo for private use (bug fixing, testing, etc). |
83 Diff/Change: |
79 Diff/Change: |
84 Finding the differences between two files. Useful for seeing what changed between revisions. |
80 Finding the differences between two versions of a file. |
85 Merge (or patch): |
81 Merge (or patch): |
86 Apply the changes from one file to another, to bring it up-to-date. |
82 Apply the changes from one branch to another, to bring it up-to-date. |
87 Conflict: |
83 Conflict: |
88 When pending changes to a file contradict each other (both changes cannot be applied). |
84 When pending changes to a file contradict each other (both changes cannot be applied). |
89 Resolve: |
|
90 Fixing the changes that contradict each other and checking in the correct version. |
|
91 |
85 |
92 Types of Version Control: |
86 Types of Version Control: |
93 ------------------------- |
87 ------------------------- |
94 |
88 |
|
89 (should we have this part at all?) |
95 Based on how source/code management is carried out in a tool there are two categories of Version Control Systems(VCS): |
90 Based on how source/code management is carried out in a tool there are two categories of Version Control Systems(VCS): |
96 |
91 |
97 - Centralized VCS: |
92 - Centralized VCS: |
98 In this kind of system all the revision control functions are performed on a shared server. If two developers try to change the same file at the same time, without some method of managing access the developers may end up overwriting each other's work. Centralized revision control systems solve this problem in one of two different "source management models": file locking and version merging. Both svn and cvs follows this kind of management. |
93 In this kind of system all the revision control functions are performed on a shared server. If two developers try to change the same file at the same time, without some method of managing access the developers may end up overwriting each others work. Centralized revision control systems solve this problem in one of two different "source management models": file locking and version merging. Both svn and cvs follows this kind of management. |
99 |
94 |
100 - Distributed VCS: |
95 - Distributed VCS: |
101 In a distributed model, every developer has their own repo. Diffs, commits, and reverts are all done locally, one needs Internet only to share the changes with others. It makes work faster, handles branching and merging in better way, with less management. hg, bzr and git uses this work flow. |
96 In a distributed model, every developer has their own repo. Diffs, commits, and reverts are all done locally, one needs Internet only to share the changes with others. It makes work faster, handles branching and merging in better way, with less management. hg, bzr and git uses this work flow. |
102 |
97 |
103 Get Going with Hg: |
98 Get Going with Hg: |
104 ================== |
99 ================== |
105 |
100 |
106 Why hg? |
101 Why hg? |
107 ------- |
102 ------- |
108 |
103 |
109 - It is easy to learn and use. |
104 - easy to learn and use. |
110 - It is lightweight. |
105 - lightweight. |
111 - It scales excellently. |
106 - scales excellently. |
112 - It is based on Python. |
107 - based on Python. |
113 |
108 |
114 A small point to notice here, hg cant track binary files for changes, one can add them to repo, but wont be able to track changes made to it. And hg considers, odt, pdf files as binary. |
109 A small point to notice here, hg cant track binary files for changes, one can add them to repo, but wont be able to track changes made to it. And hg considers, odt, pdf files as binary. |
|
110 |
|
111 Installation: |
|
112 ------------- |
|
113 |
|
114 - For Linux based systems, hg is available in most of package management. So for say Ubuntu systems:: |
|
115 |
|
116 $ sudo apt-get install mercurial |
|
117 |
|
118 will be all you need to install hg. Similarly Fedora users can use yum to install hg. |
|
119 |
|
120 - For Windows and Mac OS X systems the setup can be downloaded from http://mercurial.selenic.com/downloads/ and standard installation can be followed. |
115 |
121 |
116 Getting Started: |
122 Getting Started: |
117 ---------------- |
123 ---------------- |
118 |
124 |
119 Following command tells the version of hg installed on machine: :: |
125 After installation is complete lets get started with using. First things first, lets pay our homage to *man* pages as per rituals: :: |
120 |
126 |
121 $hg version |
127 $ man hg |
122 |
128 |
123 Mercurial Distributed SCM (version 1.1.2) |
129 This will give us manuscript of all the options available with *hg*. We can either look through all of it, or a better way will be to use built-in help system of *hg*. Say to get brief list of all commands, along with a description of what each does we can use :: |
124 Copyright (C) 2005-2008 Matt Mackall <mpm@selenic.com> and others |
130 |
125 This is free software; see the source for copying conditions. There is NO |
131 $ hg help |
126 warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
127 |
|
128 Built-in help, Mercurial provides a built-in help system. Following command will print a brief list of commands, along with a description of what each does. :: |
|
129 |
|
130 $hg help |
|
131 |
132 |
132 Mercurial Distributed SCM |
133 Mercurial Distributed SCM |
133 list of commands: |
134 list of commands: |
134 add add the specified files on the next commit |
135 add add the specified files on the next commit |
135 addremove ----------------------- |
136 addremove ----------------------- |
|
137 ------------------------------------ |
|
138 heads show current repository heads or show branch heads |
|
139 ------------------------------------ |
136 |
140 |
137 For specific command, just follow the command name after the help. :: |
141 For specific command, just follow the command name after the help. :: |
138 |
142 |
139 $hg help diff |
143 $ hg help diff |
140 hg diff [OPTION]... [-r REV1 [-r REV2]] [FILE]... |
144 hg diff [OPTION]... [-r REV1 [-r REV2]] [FILE]... |
141 |
145 |
142 diff repository (or selected files) |
146 diff repository (or selected files) |
143 Show differences between revisions for the specified files. |
147 Show differences between revisions for the specified files. |
144 Differences between files are shown using the unified diff format. |
148 Differences between files are shown using the unified diff format. |
145 NOTE:____________ |
149 NOTE:____________ |
146 |
150 |
147 Let there be Repository: |
151 Let there be Repository: |
148 ------------------------ |
152 ------------------------ |
149 |
153 |
150 In Mercurial, everything happens inside a repository. The repository for a project contains all of the files that “belong to” that project, along with a historical record of the project's files. A repository is simply a directory tree in file-system that Mercurial treats as special. |
154 In Mercurial, everything happens inside a repository. The repository for a project contains all of the files that “belong to” that project, along with a historical record of the project's files. A repository is simply a directory which Mercurial treats as special. |
151 |
155 |
152 There can be two ways to create a repo, either getting local copy for existing repo available on Internet or machine, or creating a new repo. For getting already existing repo hg uses command *"clone"* :: |
156 There can be two ways to create a repo, either downloading a copy of existing repo available on Internet, or creating/starting a new repo. |
153 |
157 |
154 $hg clone http://hg.serpentine.com/tutorial/hello localCopyhello |
158 Say we have a directory which we want to bring under version control, so we start a new repository using *hg init*: :: |
|
159 |
|
160 $ ls -a circulate/ |
|
161 . .. lena.png pendulum.txt points.txt pos.txt sslc1.py sslc1.txt |
|
162 $ cd circulate/ |
|
163 $ hg init |
|
164 $ ls -a |
|
165 . .. .hg lena.png pendulum.txt points.txt pos.txt sslc1.py sslc1.txt |
|
166 |
|
167 *.hg* directory indicates that this new dir is now a repo.This is where Mercurial keeps all of its metadata for the repository.The contents of the .hg directory and its subdirectories are private to Mercurial. Rest all files are for the user to use them as they pleases. |
|
168 |
|
169 For getting already existing repo hg uses command *"clone"* :: |
|
170 |
|
171 $ hg clone http://hg.serpentine.com/tutorial/hello localCopyhello |
155 |
172 |
156 requesting all changes |
173 requesting all changes |
157 adding changesets |
174 adding changesets |
158 adding manifests |
175 adding manifests |
159 adding file changes |
176 adding file changes |
260 tag: tip |
257 tag: tip |
261 user: Bryan O'Sullivan <bos@serpentine.com> |
258 user: Bryan O'Sullivan <bos@serpentine.com> |
262 date: Sat Aug 16 22:16:53 2008 +0200 |
259 date: Sat Aug 16 22:16:53 2008 +0200 |
263 summary: Trim comments. |
260 summary: Trim comments. |
264 |
261 |
265 The hg log command's -v (or --verbose) option gives you this extra detail. :: |
262 -v option with "log" gives some extra details related to a changeset. |
266 |
|
267 $ hg log -v -r 3 |
|
268 changeset: 3:0272e0d5a517 |
|
269 user: Bryan O'Sullivan <bos@serpentine.com> |
|
270 date: Sat Aug 16 22:08:02 2008 +0200 |
|
271 files: Makefile |
|
272 description: |
|
273 Get make to generate the final binary from a .o file. |
|
274 |
263 |
275 Making Changes: |
264 Making Changes: |
276 --------------- |
265 --------------- |
277 |
266 |
278 There is feviStick.py file in repo created above with name Fevicol. *status(alias st)* command prints the revision history of the specified files or the entire project:: |
267 Lets follow a simple exercise of *managing letters* using hg. We create a new directory and start revision tracking on it.:: |
279 |
268 |
280 $ cd Fevicol |
269 $ mkdir letter |
281 $ hg log |
270 $ cd letter |
282 $ hg status |
271 $ touch letter.tex |
283 ? feviStick.py |
272 $ hg init |
284 |
273 |
285 "?" sign in front of file indicates that this file is not yet part of track record. *add* command is used to add new files to repo. :: |
274 Now lets try to create a local clone of this repository:: |
286 |
275 |
287 $ hg add feviStick.py |
276 $ hg clone letter letter-clone |
288 $ hg st |
277 updating working directory |
289 A feviStick.py |
278 0 files updated, 0 files merged, |
290 |
279 0 files removed, 0 files unresolved |
291 So file is now part of repository(A symbol). Use *commit (alias ci)* command to make changes effective(this command would be explained in more details in later parts). :: |
280 |
292 |
281 So here, message says 0 files updated but we have just created a *tex* file inside it. Lets try to see status of our main repository by using *status(st)* command:: |
293 $ hg ci -u "Shantanu <shantanu@fossee.in>" -m "First commit." |
282 |
|
283 $ cd letter |
|
284 $ hg st |
|
285 ? letter.tex |
|
286 |
|
287 "?" sign in front of file indicates that this file is alien to hg, as in we have to *add* it to repo by:: |
|
288 |
|
289 $ hg add letter.tex |
|
290 $ hg st |
|
291 A letter.tex |
|
292 |
|
293 So file is now part of repository(A symbol). We *commit (alias ci)* it to repo and make changes effective :: |
|
294 |
|
295 $ hg ci -u "Shantanu <shantanu@fossee.in>" |
|
296 -m "First commit." |
294 $ hg log |
297 $ hg log |
295 changeset: 0:84f5e91f4de1 |
298 changeset: 0:210664b4ed58 |
296 tag: tip |
299 tag: tip |
297 user: Shantanu <shantanu@fossee.in> |
300 user: Shantanu <shantanu@fossee.in> |
298 date: Fri Aug 21 23:37:13 2009 +0530 |
301 date: Tue Feb 23 19:41:45 2010 +0530 |
299 summary: First commit. |
302 summary: First commit. |
300 |
303 |
|
304 Some arguments passed to *ci* command are worth noticing: |
|
305 - *u* is to provide name and email contact information of person making changes! |
|
306 - *m* is to provide one-line summary of changeset. |
|
307 |
|
308 If we don't give these options, *ci* will take us to a default editor, there we have to specify a commit *message* in first line, then we can edit other information like username, once done just exit the editor and changes are committed to the repo. Now these changes will be visible in logs. |
|
309 |
301 Similar to add there are other commands available for file management in repo. *copy (alias cp)* command is used to mark files as copied for the next commit. :: |
310 Similar to add there are other commands available for file management in repo. *copy (alias cp)* command is used to mark files as copied for the next commit. :: |
302 |
311 |
303 $ hg cp feviStick.py pidiLite.py |
312 $ hg cp letter.tex letter-prof.tex |
|
313 |
|
314 *rename(alias mv)* rename files; equivalent of copy + remove. :: |
|
315 |
|
316 $ hg rename letter.tex letter-personal.tex |
304 $ hg st |
317 $ hg st |
305 A pidiLite.py |
318 A letter-personal.tex |
306 |
319 A letter-pro.tex |
307 *rename(alias mv)* rename files; equivalent of copy + remove. *tip* command shows newest revision in the repository. :: |
320 R letter.tex |
308 |
321 $ hg ci -u "Shantanu <shantanu@fossee.in>" -m "Renamed and added letters." |
309 $ hg rename pidiLite.py feviCol.py |
322 |
310 $ hg st |
323 *tip* command shows newest revision in the repository. :: |
311 A feviCol.py |
324 |
312 $ hg ci -u "Shantanu <shantanu@fossee.in>" -m "Renamed pidiLite.py." |
|
313 $ hg tip |
325 $ hg tip |
314 changeset: 1:d948fb4137c5 |
326 changeset: 1:4a2d973a92de |
315 tag: tip |
|
316 user: Shantanu <shantanu@fossee.in> |
327 user: Shantanu <shantanu@fossee.in> |
317 date: Sat Aug 22 00:11:25 2009 +0530 |
328 date: Tue Feb 23 19:50:39 2010 +0530 |
318 summary: Renamed pidiLite.py. |
329 summary: Renamed and added letters. |
319 |
|
320 *remove* command is used to remove files from a repo. :: |
|
321 |
|
322 $ hg remove feviCol.py |
|
323 $ hg st |
|
324 R feviCol.py |
|
325 |
|
326 R status of files denotes, file is marked as to be removed by the previous command *remove*. To add the file again to repo, one can use *revert* command, which restore individual files or dirs to an earlier state. :: |
|
327 |
|
328 $ ls |
|
329 feviStick.py |
|
330 $ hg revert feviCol.py |
|
331 $ ls |
|
332 feviCol.py feviStick.py |
|
333 |
330 |
334 Sharing Changes: |
331 Sharing Changes: |
335 ---------------- |
332 ---------------- |
336 |
333 |
337 Pulling from repo: |
334 Pulling from repo: |
338 ~~~~~~~~~~~~~~~~~~ |
335 ~~~~~~~~~~~~~~~~~~ |
339 |
336 |
340 As mentioned earlier that repositories in Mercurial are self-contained. This means that the changeset just created exists only in Fevicol repository and not in previously cloned Fevicol-pull. There are a few ways that can be used to propagate this change into other repositories. :: |
337 As mentioned earlier that repositories in Mercurial are self-contained. This means that the changeset just created exists only in *letter* repository and not in previously cloned . There are a few ways that can be used to propagate this change into other repositories. *pull* command will download all changeset from main repo. :: |
341 |
338 |
342 $ hg clone Fevicol Fevicol-clone |
339 $ cd letter-clone |
343 updating working directory |
340 $ hg pull |
344 2 files updated, 0 files merged, 0 files removed, 0 files unresolved |
341 pulling from /home/baali/letter |
345 |
|
346 Or traverse into the any dir which is a working hg repo(using hg init) and pull command will download all changeset from main repo. :: |
|
347 |
|
348 $ mkdir Fevicol-pull |
|
349 $ cd Fevicol-pull |
|
350 $ hg init |
|
351 $ hg pull ../Fevicol |
|
352 pulling from ../Fevicol |
|
353 requesting all changes |
342 requesting all changes |
354 adding changesets |
343 adding changesets |
355 adding manifests |
344 adding manifests |
356 adding file changes |
345 adding file changes |
357 added 2 changesets with 2 changes to 2 files |
346 added 2 changesets with 2 changes to 2 files |
359 |
348 |
360 *changeset* means a list of changes made to a file. In words of *hg help*, pull command is: :: |
349 *changeset* means a list of changes made to a file. In words of *hg help*, pull command is: :: |
361 |
350 |
362 pull changes from the specified source |
351 pull changes from the specified source |
363 |
352 |
364 Pull changes from a remote repository to a local one. |
353 Pull changes from a remote repository to a local one. |
365 |
354 |
366 This finds all changes from the repository at the specified path |
355 This finds all changes from the repository at the specified path |
367 or URL and adds them to the local repository. By default, this |
356 or URL and adds them to the local repository. By default, this |
368 does not update the copy of the project in the working directory. |
357 does not update the copy of the project in the working directory. |
369 |
358 |
370 Some times, even before pulling changesets, one may need to see what changes would be pulled, Mercurial provides *hg incoming* to tell what changes *hg pull* would pull into repo, without actually pulling the changes. This command is really handy in case of avoiding unwanted changesets into the repo. |
359 Some times, even before pulling changesets, one may need to see what changes would be pulled, Mercurial provides *hg incoming* to tell what changes *hg pull* would pull into repo, without actually pulling the changes. This command is really handy in case of avoiding unwanted changesets into the repo. |
371 |
360 |
372 With Mercurial, *hg pull* does not(by default) touch the working directory. Instead there is *hg up (alias update, co, checkout)* command to do this. :: |
361 As output of *pull* command suggests it does not(by default) update the working directory. By update we mean, content of files and directory structure still remains the same as prior to *pull* command. *hg up (alias update)* command updates repo by adding latest imported changesets and bringing it upto date. :: |
373 |
362 |
374 $ cd Fevicol-pull |
363 $ ls -a |
375 $ ls -a |
364 . .. .hg |
376 . .. .hg |
365 $ hg up |
377 $ hg up |
366 2 files updated, 0 files merged, |
378 2 files updated, 0 files merged, 0 files removed, 0 files unresolved |
367 0 files removed, 0 files unresolved |
379 $ ls -a |
368 $ ls -a |
380 . .. feviCol.py feviStick.py .hg |
369 . .. .hg letter-personal.tex |
|
370 letter-pro.tex |
381 |
371 |
382 To update to specific version, give a version number to the *hg update* command. :: |
372 To update to specific version, give a version number to the *hg update* command. |
383 |
|
384 $ hg update 0 |
|
385 0 files updated, 0 files merged, 1 files removed, 0 files unresolved |
|
386 $ hg parent |
|
387 changeset: 0:84f5e91f4de1 |
|
388 user: Shantanu <shantanu@fossee.in> |
|
389 date: Fri Aug 21 23:37:13 2009 +0530 |
|
390 summary: First commit. |
|
391 |
|
392 If no version number is specified *hg up* will update to the tip version. Version number of hg starts from 0. Compare *hg parent* output to the one before doing update to see the difference. |
|
393 |
373 |
394 Making Changes: |
374 Making Changes: |
395 ~~~~~~~~~~~~~~~ |
375 ~~~~~~~~~~~~~~~ |
396 |
376 |
397 After getting the desired version of local repo, one can make changes as he/she needs and then make them available(share) for others. For these operations we will be working in Fevicol-clone repo which we created earlier. It's often good practice to keep a “pristine” copy of a remote repository around, which you can then make temporary clones of to create sandboxes for each task you want to work on. :: |
377 Lets start with adding content to letters. For start personal letter can be a letter to ask a boy/girl out! Using LaTeX to write letter, it would be straight forward, open the file in any text editor and add the following content to it :: |
398 |
378 |
399 $ cd Fevicol-clone/ |
379 \documentclass{letter} |
400 $ cat feviStick.py |
380 \begin{document} |
401 print 'Yeh Fevicol ka Majboot jod hai' |
381 \begin{letter}{} |
402 |
382 \opening{Hello xxxxxx,} |
403 This tagline is correct for feviCol.py but for feviStick.py it should be different. :: |
383 I really enjoyed meeting you in CS 101, |
404 |
384 but would love to know you better. |
405 $ echo "print 'Ab no more Chip Chip'" > feviStick.py |
385 How about a coffee on Thursday after class? |
406 $ cat feviStick.py |
386 \closing{-xxxxx} |
407 print 'Ab no more Chip Chip' |
387 \end{letter} |
408 $ hg st |
388 \end{document} |
409 M feviStick.py |
389 |
410 |
390 Replace "xxxxx" with proper names to suite yourself. Mercurial's hg status command will tell us what Mercurial knows about the files in the repository. 'M' sign in front of feviStick.py indicates that Mercurial has noticed change(modified). :: |
411 Mercurial's hg status command will tell us what Mercurial knows about the files in the repository. 'M' sign in front of feviStick.py indicates that Mercurial has noticed change. |
391 |
412 |
392 $ hg st |
413 It's somewhat helpful to know that feviStick.py was modified, but one might prefer to know exactly what changes were made to it. To do this, use the *hg diff* command. :: |
393 M letter-personal.tex |
|
394 |
|
395 At times more information is needed on knowing exactly what changes were made to what files. To do this, use the *hg diff* command. :: |
414 |
396 |
415 $ hg diff |
397 $ hg diff |
416 diff -r a7912d45f47c feviStick.py |
398 diff -r 4a2d973a92de letter-personal.tex |
417 --- a/feviStick.py Sun Aug 23 22:34:35 2009 +0530 |
399 --- a/letter-personal.tex Tue Feb 23 19:50:39 2010 +0530 |
418 +++ b/feviStick.py Sun Aug 23 22:47:49 2009 +0530 |
400 +++ b/letter-personal.tex Tue Jun 08 16:12:19 2010 +0530 |
419 @@ -1,1 +1,1 @@ |
401 @@ -0,0 +1,11 @@ |
420 -print 'Yeh Fevicol ka Majboot jod hai' |
402 +\documentclass{letter} |
421 +print 'Ab no more Chip Chip' |
403 +\begin{document} |
422 |
404 + |
423 We can modify files, build and test our changes, and use hg status and hg diff to review our changes, until we're satisfied with what we've done and arrive at a natural stopping point where we want to record our work in a new changeset. All the diffs prior to committing the changes would be done wrt earlier marked record.The hg commit command lets us create a new changeset. |
405 +\begin{letter}{} |
424 |
406 +\opening{Hello Jas,} |
425 Mercurial records your name and address with each change that you commit, so that you and others will later be able to tell who made each change. Mercurial tries to automatically figure out a sensible username to commit the change with. When we try to use *hg commit* there are various ways by which one can specify User name, some of those are: |
407 + |
|
408 +I really enjoyed meeting you in CS 101, but would love to know you better. How about a coffee on Thursday after class? |
|
409 + |
|
410 +\closing{-Samarth} |
|
411 +\end{letter} |
|
412 +\end{document} |
|
413 |
|
414 We can modify files, build and test our changes, and use hg status and hg diff to review our changes, until we're satisfied with what we've done and arrive at a natural stopping point where we want to record our work in a new changeset. All the diffs prior to committing the changes would be done wrt earlier marked record.Then we use *hg commit* to create a new changeset |
|
415 |
|
416 Mercurial records your name and email-address with each change that you commit, so that you and others will later be able to tell who made each change. It also tries to automatically figure out a sensible username to commit the change with. When we try to use *hg commit* there are various ways by which one can specify User name, some of those are: |
426 |
417 |
427 - Specify a -u option to the hg commit command on the command line, followed by a username. |
418 - Specify a -u option to the hg commit command on the command line, followed by a username, this is the procedure we used earlier. |
428 - set HGUSER environment variable. |
419 - set HGUSER environment variable:: |
|
420 |
|
421 $ export HGUSER="xxxxx" |
429 - Edit hgrc file present in .hg folder to set this property, add following lines to that file and Mercurial will read those parameters from that location. :: |
422 - Edit hgrc file present in .hg folder to set this property, add following lines to that file and Mercurial will read those parameters from that location. :: |
430 |
423 |
431 [ui] |
424 [ui] |
432 username = Firstname Lastname <email.address@example.net> |
425 username = Firstname Lastname <email.address@example.net> |
433 |
426 |
434 For me the hgrc file looks like this: :: |
427 For me the hgrc file for *letter* clone repo looks like this: :: |
435 |
428 |
436 [paths] |
429 [paths] |
437 default = /home/baali/Fevicol |
430 default = /home/baali/letter |
438 [ui] |
431 [ui] |
439 username = Shantanu Choudhary <shantanu@fossee.in> |
432 username = Shantanu Choudhary <shantanu@fossee.in> |
440 |
433 |
441 Once this parameter is set, *hg commit* command drops us into a text editor, to enter a message that will describe the modifications we've made in this changeset. This is called the commit message. It will be a record for readers of what we did and why, and it will be printed by hg log after we've finished committing. :: |
434 Once this parameter is set, *hg commit* command drops us into a text editor, to enter a message that will describe the modifications we've made in this changeset. This is called the commit message. It will be a record for readers of what we did and why, and it will be printed by hg log after we've finished committing. :: |
442 |
435 |
443 Changed tagline for feviStick.py. |
436 Added content to personal letter. |
444 HG: Enter commit message. Lines beginning with 'HG:' are removed. |
437 HG: Enter commit message. Lines beginning with 'HG:' are removed. |
445 HG: -- |
438 HG: -- |
446 HG: user: Shantanu Choudhary <shantanu@fossee.in> |
439 HG: user: Shantanu Choudhary <shantanu@fossee.in> |
447 HG: branch 'default' |
440 HG: branch 'default' |
448 HG: changed feviStick.py |
441 HG: changed letter-personal.tex |
449 |
442 |
450 This would be your default system editor(for me it is vim, one can set it also), where you can enter the log message in first line, once you are done with log message quit the editor using *[ESC] key ":wq"*.Once we've finished the commit, we can use the hg tip command to display the changeset we just created. :: |
443 This would be your default system editor(for me it is vim, one can set it also), where you can enter the log message in first line, once you are done with log message quit the editor using *[ESC] key ":wq"*.Once we've finished the commit, we can use the hg tip command to display the changeset we just created. :: |
451 |
444 |
452 $ hg tip |
445 $ hg tip |
453 changeset: 3:e1ab2aff4ddd |
446 changeset: 2:a5d8cb2fac01 |
454 tag: tip |
447 user: Shantanu <shantanu@fossee.in> |
455 user: Shantanu Choudhary <shantanu@fossee.in> |
448 date: Tue Feb 23 20:34:12 2010 +0530 |
456 date: Sun Aug 23 23:32:01 2009 +0530 |
449 summary: Added content to personal letter. |
457 summary: Changed tagline for feviStick.py. |
450 |
458 |
|
459 One can do above mentioned procedure using following one line command: :: |
451 One can do above mentioned procedure using following one line command: :: |
460 |
452 |
461 $ hg ci -u "Shantanu <shantanu@fossee.in>" -m "Changed tagline for feviStick.py." |
453 $ hg ci -u "Shantanu <shantanu@fossee.in>" -m "Added content to personal letter." |
462 |
454 |
463 Sharing Changes: |
455 Sharing Changes: |
464 ~~~~~~~~~~~~~~~~ |
456 ~~~~~~~~~~~~~~~~ |
465 |
457 |
466 The *hg outgoing* command tells us what changes would be pushed into another repository. :: |
458 So now we have this *letter-clone* repo where we created above changes and committed them. But the main repo(*trunk*) that is *letter* wont be hinted of these changes. It will be still in older stage, same way as we pulled changes to this cloned repo from main branch at starting. To share changes from a cloned repo to main branch hg provides with *push* command. It is same as *pull* but instead of pulling it pushes the changes to trunk. :: |
467 |
|
468 $ hg outgoing ../Fevicol |
|
469 comparing with ../Fevicol |
|
470 searching for changes |
|
471 changeset: 3:e1ab2aff4ddd |
|
472 tag: tip |
|
473 user: Shantanu Choudhary <shantanu@fossee.in> |
|
474 date: Sun Aug 23 23:32:01 2009 +0530 |
|
475 summary: Changed tagline for feviStick.py. |
|
476 |
|
477 And the *hg push* command does the actual push. :: |
|
478 |
459 |
479 $ hg push ../Fevicol |
460 $ hg push ../Fevicol |
480 pushing to ../Fevicol |
461 pushing to ../Fevicol |
481 searching for changes |
462 searching for changes |
482 adding changesets |
463 adding changesets |
483 adding manifests |
464 adding manifests |
484 adding file changes |
465 adding file changes |
485 added 1 changesets with 1 changes to 1 files |
466 added 1 changesets with 1 changes to 1 files |
486 |
467 |
487 As with hg pull, the hg push command does not update the working directory in the repository that it's pushing changes into. One has to use hg update to populate the changes in desired repo. :: |
468 Same as with hg pull, the hg push command populates the changesets nothing more. :: |
488 |
469 |
489 $ cd ../Fevicol |
470 $ cd ../letter |
490 $ hg tip |
471 $ hg tip |
491 changeset: 3:e1ab2aff4ddd |
472 changeset: 2:a5d8cb2fac01 |
492 tag: tip |
473 user: Shantanu <shantanu@fossee.in> |
493 user: Shantanu Choudhary <shantanu@fossee.in> |
474 date: Tue Feb 23 20:34:12 2010 +0530 |
494 date: Sun Aug 23 23:32:01 2009 +0530 |
475 summary: Added content to personal letter. |
495 summary: Changed tagline for feviStick.py. |
476 |
496 $ cat feviStick.py |
477 The branch where changes are being pushed still need *up* to be updated or for inclusion of all the imported changesets :: |
497 print 'Yeh Fevicol ka Majboot jod hai' |
478 |
498 |
479 $ hg up |
499 changesets are imported, but update is yet to be done. :: |
|
500 |
|
501 $ hg up tip |
|
502 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
480 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
503 $ $ cat feviStick.py |
481 $ cat letter-personal.tex |
504 print 'Ab no more Chip Chip' |
482 \documentclass{letter} |
|
483 \begin{document} |
|
484 \begin{letter}{} |
|
485 \opening{Hello xxxx,} |
|
486 I really enjoyed meeting you in CS 101, but would love to know you better. How about a coffee on Thursday after class? |
|
487 |
|
488 \closing{-xxxx} |
|
489 \end{letter} |
|
490 \end{document} |
505 |
491 |
506 Merging the Work: |
492 Merging the Work: |
507 ~~~~~~~~~~~~~~~~~ |
493 ~~~~~~~~~~~~~~~~~ |
508 |
494 |
509 This is next aspect of any version control, how to merge work done by various participants of project in a way that no one looses changes being made, and still remains updated. Here is simple case study which can help understanding why merging is required: |
495 This is next aspect of any version control, how to merge work done by various participants of project in a way that no one looses changes being made, and still remains updated. Here is simple case study which can help understanding why merging is required: |
510 |
496 |
511 Two persons, A and B are contributing on same project. Both starts from cloning the same online repo(lets say present state X), so that both have a working local repo. Now A edits one of file, commits the changes and pushes to the repo, hence changing the state of repo to Y, but B, have not updated his repo, makes a change in one of files and reaches to a different state Z. Now when A pulls repo from B, his repo will have multiple heads. This stage is clearly ambiguous, the repo of A is not consistent, it has multiple heads, and from here, whatever changes he makes can take whatsoever direction if it is not fixed, and hence A will have to merge changes so that everything becomes consistent again. |
497 Two persons, A and B are contributing on same project. Both starts from cloning the same online repo(lets say present state X), so that both have a working local repo. Now A edits one of file, commits the changes and pushes to the repo, hence changing the state of repo to Y, but B, have not updated his repo, makes a change in one of files and reaches to a different state Z. Now when A pulls repo from B, his repo will have multiple heads. This stage is clearly ambiguous, the repo of A is not consistent, it has multiple heads, and from here, whatever changes he makes can take whatsoever direction if it is not fixed, and hence A will have to merge changes so that everything becomes consistent again. |
512 |
498 |
513 Lets see how this work with working repo, we will use Fevicol and Fevicol-clone repositories created earlier. For now, the status of both repo is: :: |
499 Lets see how this work with working repo, we will use letter and letter-clone repositories created earlier. For now, the status of both repo is: :: |
514 |
500 |
515 $ cd Fevicol-clone |
501 $ cd letter-clone |
|
502 $ hg tip |
|
503 changeset: 2:a5d8cb2fac01 |
|
504 user: Shantanu <shantanu@fossee.in> |
|
505 date: Tue Feb 23 20:34:12 2010 +0530 |
|
506 summary: Added content to personal letter. |
|
507 |
|
508 We share(clones) this repo with a friend, he goes through the letter and just makes small change of adding color to clogins part of letter. :: |
|
509 |
|
510 $ hg diff |
|
511 diff -r 4a2d973a92de letter-personal.tex |
|
512 --- a/letter-personal.tex Tue Feb 23 19:50:39 2010 +0530 |
|
513 +++ b/letter-personal.tex Wed Feb 24 12:03:33 2010 +0530 |
|
514 @@ -0,0 +1,12 @@ |
|
515 \documentclass{letter} |
|
516 +\usepackage{color} |
|
517 \begin{document} |
|
518 . |
|
519 -\closing{-Samarth} |
|
520 +\closing{\textcolor{red}{-Samarth}} |
|
521 |
|
522 Here the "-" sign shows which lines are removed, and "+" indicates what lines are added. He is satisfied and commits the changes. :: |
|
523 |
|
524 $ hg ci -u "Vattam <vattam@fossee.in>" -m "Added some suggestions." |
|
525 changeset: 3:71fd776d856b |
|
526 parent: 2:a5d8cb2fac01 |
|
527 user: Vattam <vattam@fossee.in> |
|
528 date: Wed Feb 24 12:54:31 2010 +0530 |
|
529 summary: Added some suggestions. |
|
530 |
|
531 In the meanwhile, it seems, our "xxxx" is already dating someone else. So we also change the name to "yyyy" who is available, and we commit it :: |
|
532 |
|
533 $ cd letter |
|
534 $ hg ci -u "Shantanu <shantanu@fossee.in>" -m "Changed name." |
516 $ hg tip |
535 $ hg tip |
517 changeset: 3:e1ab2aff4ddd |
536 changeset: 3:02b49a53063f |
518 tag: tip |
|
519 user: Shantanu Choudhary <shantanu@fossee.in> |
|
520 date: Sun Aug 23 23:32:01 2009 +0530 |
|
521 summary: Changed tagline for feviStick.py. |
|
522 |
|
523 The tagline for feviCol.py is not complete, so we make changes in that file in this repo. :: |
|
524 |
|
525 $ echo "print 'Yeh Fevicol ka Majboot jod hai, tootega nahin'" > feviStick.py |
|
526 $ hg st |
|
527 M feviStick.py |
|
528 |
|
529 And commit the changes made :: |
|
530 |
|
531 $ hg ci -u "Shantanu <shantanu@fossee.in>" -m "Updated tag line for feviCol.py." |
|
532 $ hg st |
|
533 $ hg tip |
|
534 changeset: 4:caf986b15e05 |
|
535 tag: tip |
|
536 user: Shantanu <shantanu@fossee.in> |
537 user: Shantanu <shantanu@fossee.in> |
537 date: Tue Aug 25 16:28:24 2009 +0530 |
538 date: Wed Feb 24 13:12:26 2010 +0530 |
538 summary: Updated tag line for feviCol.py. |
539 summary: Changed name. |
539 |
|
540 Now we will make some changes on Fevicol repo. We will add new file here :: |
|
541 |
|
542 $ cd Fevicol |
|
543 $ echo "print 'Jor laga ke hayyiya'" > firstAdd.py |
|
544 $ hg st |
|
545 ? firstAdd.py |
|
546 $ hg add firstAdd.py |
|
547 $ hg st |
|
548 A firstAdd.py |
|
549 $ hg ci -u "Shantanu <shantanu@fossee.in>" -m "Added firsAdd.py." |
|
550 $ hg tip |
|
551 changeset: 4:fadbd6492cc4 |
|
552 tag: tip |
|
553 user: Shantanu <shantanu@fossee.in> |
|
554 date: Tue Aug 25 16:46:24 2009 +0530 |
|
555 summary: Added firsAdd.py. |
|
556 |
540 |
557 So now we have two repo, who have different commit history and tree, now if we try to pull changes from one to another, this is how it goes(we are still in Fevicol repo): :: |
541 So now we have two repo, who have different commit history and tree. |
558 |
542 |
559 $ hg pull ../Fevicol-clone |
543 .. image:: glog-main.png |
560 pulling from ../Fevicol-clone |
544 |
|
545 .. image:: glog-suggestion.png |
|
546 |
|
547 If we try to pull changes from one to another, this is how it goes(we are still in letter repo): :: |
|
548 |
|
549 $ hg pull ../letter-suggestion |
|
550 pulling from ../letter-suggestion |
561 searching for changes |
551 searching for changes |
562 adding changesets |
552 adding changesets |
563 adding manifests |
553 adding manifests |
564 adding file changes |
554 adding file changes |
565 added 1 changesets with 1 changes to 1 files (+1 heads) |
555 added 1 changesets with 1 changes to 1 files (+1 heads) |
566 (run 'hg heads' to see heads, 'hg merge' to merge) |
556 (run 'hg heads' to see heads, 'hg merge' to merge) |
567 |
557 |
568 There we go, since both repo were on different track, hg pull command in last line gives some heading from here. *hg heads* command show current repository heads or show branch heads. :: |
558 There we go, since both repo were on different track, hg pull command in last line gives some heading from here. *hg heads* command show current repository heads or show branch heads. :: |
569 |
559 |
570 $ hg heads |
560 $ hg heads |
571 changeset: 5:caf986b15e05 |
561 changeset: 4:71fd776d856b |
572 tag: tip |
562 tag: tip |
573 parent: 3:e1ab2aff4ddd |
563 parent: 2:a5d8cb2fac01 |
574 user: Shantanu <shantanu@fossee.in> |
564 user: Vattam <vattam@fossee.in> |
575 date: Tue Aug 25 16:28:24 2009 +0530 |
565 date: Wed Feb 24 12:54:31 2010 +0530 |
576 summary: Updated tag line for feviCol.py. |
566 summary: Added some suggestions. |
577 |
567 |
578 changeset: 4:fadbd6492cc4 |
568 changeset: 3:02b49a53063f |
579 user: Shantanu <shantanu@fossee.in> |
569 user: Shantanu <Shantanu@fossee.in> |
580 date: Tue Aug 25 16:46:24 2009 +0530 |
570 date: Wed Feb 24 13:12:26 2010 +0530 |
581 summary: Added firsAdd.py. |
571 summary: Changed name. |
582 |
572 |
583 To get better understanding of what is going on hg have a tool known as *glog* which shows revision history alongside an ASCII revision graph. :: |
573 To get better understanding of what is going on hg have a tool known as *glog* which shows revision history alongside an ASCII revision graph. :: |
584 |
574 |
585 $ hg glog |
575 $ hg glog |
586 o changeset: 5:caf986b15e05 |
576 |
587 | tag: tip |
577 .. image:: heads.png |
588 | parent: 3:e1ab2aff4ddd |
|
589 | user: Shantanu <shantanu@fossee.in> |
|
590 | date: Tue Aug 25 16:28:24 2009 +0530 |
|
591 | summary: Updated tag line for feviCol.py. |
|
592 | |
|
593 | @ changeset: 4:fadbd6492cc4 |
|
594 |/ user: Shantanu <shantanu@fossee.in> |
|
595 | date: Tue Aug 25 16:46:24 2009 +0530 |
|
596 | summary: Added firsAdd.py. |
|
597 | |
|
598 o changeset: 3:e1ab2aff4ddd |
|
599 | user: Shantanu Choudhary <shantanu@fossee.in> |
|
600 | date: Sun Aug 23 23:32:01 2009 +0530 |
|
601 | summary: Changed tagline for feviStick.py. |
|
602 | |
|
603 o changeset: 2:a7912d45f47c |
|
604 | user: Shantanu <shantanu@fossee.in> |
|
605 | date: Sun Aug 23 22:34:35 2009 +0530 |
|
606 | summary: Updated Content. |
|
607 | |
|
608 o changeset: 1:d948fb4137c5 |
|
609 | user: Shantanu <shantanu@fossee.in> |
|
610 | date: Sat Aug 22 00:11:25 2009 +0530 |
|
611 | summary: Renamed pidiLite.py. |
|
612 | |
|
613 o changeset: 0:84f5e91f4de1 |
|
614 user: Shantanu <shantanu@fossee.in> |
|
615 date: Fri Aug 21 23:37:13 2009 +0530 |
|
616 summary: First commit. |
|
617 |
578 |
618 To bring repo on single track/branch once again we will have to merge these two branches. Without merging them even hg update wont work for obvious reason of confusing track record. :: |
579 To bring repo on single track/branch once again we will have to merge these two branches. Without merging them even hg update wont work for obvious reason of confusing track record. :: |
619 |
580 |
620 $ hg up |
581 $ hg up |
621 abort: crosses branches (use 'hg merge' or 'hg update -C') |
582 abort: crosses branches (use 'hg merge' or 'hg update -C') |
622 |
583 |
623 *hg merge* command merge working directory with another revision. :: |
584 *hg merge* command merge working directory with another revision. :: |
624 |
585 |
625 $ hg merge |
586 $ hg merge |
626 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
587 1 files updated, 0 files merged, 0 files removed, 0 files unresolved |
627 (branch merge, don't forget to commit) |
588 (branch merge, don't forget to commit) |
628 $ hg tip |
|
629 changeset: 5:caf986b15e05 |
|
630 tag: tip |
|
631 parent: 3:e1ab2aff4ddd |
|
632 user: Shantanu <shantanu@fossee.in> |
|
633 date: Tue Aug 25 16:28:24 2009 +0530 |
|
634 summary: Updated tag line for feviCol.py. |
|
635 |
589 |
636 After merging two branches, until we commit the results of merge it will keep on showing two heads. :: |
590 After merging two branches, until we commit the results of merge it will keep on showing two heads. :: |
637 |
591 |
638 $ hg ci -u "Shantanu <shantanu@fossee.in>" -m "Merged branches of add and tag line." |
592 $ hg ci -u "Shantanu <shantanu@fossee.in>" -m "Merged branches." |
639 $ hg heads |
|
640 changeset: 6:edbe97209954 |
|
641 tag: tip |
|
642 parent: 4:fadbd6492cc4 |
|
643 parent: 5:caf986b15e05 |
|
644 user: Shantanu <shantanu@fossee.in> |
|
645 date: Tue Aug 25 17:06:03 2009 +0530 |
|
646 summary: Merged branches of add and tag line. |
|
647 |
|
648 Here is brief and meaningful output of glog :: |
|
649 |
|
650 $ hg glog |
593 $ hg glog |
651 @ changeset: 6:edbe97209954 |
594 |
652 |\ tag: tip |
595 .. image:: glog-2.png |
653 | | parent: 4:fadbd6492cc4 |
596 |
654 | | parent: 5:caf986b15e05 |
597 *And we are back on track.* |
655 | | user: Shantanu <shantanu@fossee.in> |
|
656 | | date: Tue Aug 25 17:06:03 2009 +0530 |
|
657 | | summary: Merged branches of add and tag line. |
|
658 | | |
|
659 | o changeset: 5:caf986b15e05 |
|
660 | | parent: 3:e1ab2aff4ddd |
|
661 | | user: Shantanu <shantanu@fossee.in> |
|
662 | | date: Tue Aug 25 16:28:24 2009 +0530 |
|
663 | | summary: Updated tag line for feviCol.py. |
|
664 | | |
|
665 o | changeset: 4:fadbd6492cc4 |
|
666 |/ user: Shantanu <shantanu@fossee.in> |
|
667 | date: Tue Aug 25 16:46:24 2009 +0530 |
|
668 | summary: Added firsAdd.py. |
|
669 |
|
670 And we are back on track. |
|
671 |
598 |
672 Workflow: |
599 Workflow: |
673 ========= |
600 ========= |
674 |
601 |
675 This is chain of steps which can be followed for working against a project that has a centralized copy, you may want to make sure you're up to date first. This means pulling its changes and then updating. |
602 This is chain of steps which can be followed for working against a project that has a centralized copy, you may want to make sure you're up to date first. This means pulling its changes and then updating. |