versionControl/handOut.rst
changeset 37 4cddf3a13843
parent 26 977009f5a22a
child 38 ce7634ee7986
equal deleted inserted replaced
36:4c4c8a9795b2 37:4cddf3a13843
    10 
    10 
    11 "Version control is one of those weird, geeky things that never really gained much ground in non-geek fields, despite the fact that it’s blindingly useful.
    11 "Version control is one of those weird, geeky things that never really gained much ground in non-geek fields, despite the fact that it’s blindingly useful.
    12 
    12 
    13 Version control (or source control) is nothing more arcane than keeping copies of ones work as one make changes to it. On the surface, it’s all straight-forward; make a copy of every file before making any changes to it. That way, if something seriously messes up, one can always fall back to something that worked before, or at least compare the broken copy with one that used to work so one can figure out where it went off kilter. Accidentally deleted half of thesis and closed the word processor? No problem – out comes the backup."
    13 Version control (or source control) is nothing more arcane than keeping copies of ones work as one make changes to it. On the surface, it’s all straight-forward; make a copy of every file before making any changes to it. That way, if something seriously messes up, one can always fall back to something that worked before, or at least compare the broken copy with one that used to work so one can figure out where it went off kilter. Accidentally deleted half of thesis and closed the word processor? No problem – out comes the backup."
    14 
    14 
    15 Now, in the real world, it’s not so easy. One probably cooks up their own version control system without realizing it had such a geeky name. For instances files with names oldxxxxxx.odt and latestxxxxxx.odt. Every time to make some change in a file, one save it with different name then the original one. Luckily there are like, loads of version control systems out there to do this heavy lifting.
    15 Now, in the real world, it’s not so easy. One probably cooks up their own version control system without realizing it had such a geeky name. For instances files with names oldxxxxxx.py and latestxxxxxx.py. Every time to make some change in a file, one save it with different name then the original one. Luckily there are like, loads of version control systems out there to do this heavy lifting.
    16 
    16 
    17 Why Use Version Control
    17 Why Use Version Control
    18 =======================
    18 =======================
    19 
    19  
    20 "Its the start which most people fail to attempt". 
    20 One of idea behind Version Control Tools was to build onto very first step which can be creating a empty file, or writting a first buggy program for assignment, rather then simply loose it. So here are some reasons why is automated version control needed:
    21 One of idea behind Version Control Tools was to save that "one" step, to build onto it, rather then simply loose it. So here are some reasons why is automated version control needed:
       
    22 
    21 
    23     - It will track the history and evolution of a project, so one don't have to do it manually. It allows to track what changes where made, when were they made, by whom and why.
    22     - It will track the history and evolution of a project, so one don't have to do it manually. It allows to track what changes where made, when were they made, by whom and why.
    24     - For a team of people working on same project, revision control software makes it easier to collaborate. For example, when people more or less simultaneously make potentially incompatible changes, the software will help them to identify and resolve those conflicts.
    23     - For a team of people working on same project, revision control software makes it easier to collaborate. For example, when people more or less simultaneously make potentially incompatible changes, the software will help them to identify and resolve those conflicts.
    25     - It can help to recover from mistakes. If a change made at some moment of time, turns out to be in error in future, one can revert to an earlier version of one or more files. In fact, a really good revision control tool will even help in efficiently figure out exactly when a problem was introduced.
    24     - It can help to recover from mistakes. If a change made at some moment of time, turns out to be in error in future, one can revert to an earlier version of one or more files. In fact, a really good revision control tool will even help in efficiently figure out exactly when a problem was introduced.
    26 
    25 
   111 	- It is easy to learn and use.
   110 	- It is easy to learn and use.
   112 	- It is lightweight.
   111 	- It is lightweight.
   113 	- It scales excellently.
   112 	- It scales excellently.
   114 	- It is based on Python.
   113 	- It is based on Python.
   115 
   114 
       
   115 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.
       
   116 
   116 Getting Started:
   117 Getting Started:
   117 ----------------
   118 ----------------
   118 
   119 
   119 Following command tells the version of hg installed on machine: ::
   120 Following command tells the version of hg installed on machine: ::
   120    
   121    
   273     Get make to generate the final binary from a .o file.
   274     Get make to generate the final binary from a .o file.
   274 
   275 
   275 Making Changes:
   276 Making Changes:
   276 ---------------
   277 ---------------
   277 
   278 
   278 There is feviStick.py file in repo created above with name feviCol. ::
   279 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::
   279 
   280 
   280     $ cd Fevicol
   281     $ cd Fevicol
   281     $ hg log
   282     $ hg log
   282     $ hg status
   283     $ hg status
   283     ? feviStick.py
   284     ? feviStick.py
   284 
   285 
   285 *status(st)* command prints the revision history of the specified files or the entire project. "?" 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. ::
   286 "?" 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. ::
   286 
   287 
   287     $ hg add feviStick.py
   288     $ hg add feviStick.py
   288     $ hg st
   289     $ hg st
   289     A feviStick.py
   290     A feviStick.py
   290 
   291 
   296    tag:         tip
   297    tag:         tip
   297    user:        Shantanu <shantanu@fossee.in>
   298    user:        Shantanu <shantanu@fossee.in>
   298    date:        Fri Aug 21 23:37:13 2009 +0530
   299    date:        Fri Aug 21 23:37:13 2009 +0530
   299    summary:     First commit.
   300    summary:     First commit.
   300 
   301 
   301 Similar to add there are other commands available for file management in repo. ::
   302 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 
   303 
   303    $ hg cp feviStick.py pidiLite.py
   304    $ hg cp feviStick.py pidiLite.py
   304    $ hg st
   305    $ hg st
   305    A pidiLite.py
   306    A pidiLite.py
   306 
   307 
   307 *copy (alias cp)* command is used to mark files as copied for the next commit. ::
   308 *rename(alias mv)* rename files; equivalent of copy + remove. *tip* command shows newest revision in the repository. ::
   308 
   309 
   309    $ hg rename pidiLite.py feviCol.py
   310    $ hg rename pidiLite.py feviCol.py
   310    $ hg st
   311    $ hg st
   311    A feviCol.py
   312    A feviCol.py
   312    $ hg ci -u "Shantanu <shantanu@fossee.in>" -m "Renamed pidiLite.py."
   313    $ hg ci -u "Shantanu <shantanu@fossee.in>" -m "Renamed pidiLite.py."
   315    tag:         tip
   316    tag:         tip
   316    user:        Shantanu <shantanu@fossee.in>
   317    user:        Shantanu <shantanu@fossee.in>
   317    date:        Sat Aug 22 00:11:25 2009 +0530
   318    date:        Sat Aug 22 00:11:25 2009 +0530
   318    summary:     Renamed pidiLite.py.
   319    summary:     Renamed pidiLite.py.
   319 
   320 
   320 *rename(alias mv)* rename files; equivalent of copy + remove. *tip* command shows newest revision in the repository.. ::
   321 *remove* command is used to remove files from a repo. ::
   321 
   322 
   322    $ hg remove feviCol.py
   323    $ hg remove feviCol.py
   323    $ hg st
   324    $ hg st
   324    R feviCol.py
   325    R feviCol.py
   325 
   326 
   335 ----------------
   336 ----------------
   336 
   337 
   337 Pulling from repo:
   338 Pulling from repo:
   338 ~~~~~~~~~~~~~~~~~~
   339 ~~~~~~~~~~~~~~~~~~
   339 
   340 
   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. ::
   341 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. ::
   341 
   342 
   342    $ hg clone Fevicol Fevicol-clone
   343    $ hg clone Fevicol Fevicol-clone
   343    updating working directory
   344    updating working directory
   344    2 files updated, 0 files merged, 0 files removed, 0 files unresolved
   345    2 files updated, 0 files merged, 0 files removed, 0 files unresolved
   345 
   346 
   395 ~~~~~~~~~~~~~~~
   396 ~~~~~~~~~~~~~~~
   396 
   397 
   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. ::
   398 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. ::
   398 
   399 
   399     $ cd Fevicol-clone/
   400     $ cd Fevicol-clone/
   400     $ cat cat feviStick.py 
   401     $ cat feviStick.py 
   401     print 'Yeh Fevicol ka Majboot jod hai'
   402     print 'Yeh Fevicol ka Majboot jod hai'
   402 
   403 
   403 This tagline is correct for feviCol.py but for feviStick.py it should be different. ::
   404 This tagline is correct for feviCol.py but for feviStick.py it should be different. ::
   404 
   405 
   405     $ echo "print 'Ab no more Chip Chip'" > feviStick.py
   406     $ echo "print 'Ab no more Chip Chip'" > feviStick.py
   406     $ cat cat feviStick.py
   407     $ cat feviStick.py
   407     print 'Ab no more Chip Chip'
   408     print 'Ab no more Chip Chip'
   408     $ hg st
   409     $ hg st
   409     M feviStick.py
   410     M feviStick.py
   410 
   411 
   411 Mercurial's hg status command will tell us what Mercurial knows about the files in the repository. 'M' sign infront of feviStick.py indicates that Mercurial has noticed change.
   412 Mercurial's hg status command will tell us what Mercurial knows about the files in the repository. 'M' sign infront of feviStick.py indicates that Mercurial has noticed change.
   424 
   425 
   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:
   426 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:
   426 	  
   427 	  
   427 	  - Specify a -u option to the hg commit command on the command line, followed by a username.
   428 	  - Specify a -u option to the hg commit command on the command line, followed by a username.
   428 	  - set HGUSER environment variable.
   429 	  - set HGUSER environment variable.
   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.
   430 	  - 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 	  
   431 	  
   431 		[ui]
   432 		[ui]
   432 		username = Firstname Lastname <email.address@example.net>
   433 		username = Firstname Lastname <email.address@example.net>
   433 
   434 
   434 For me the hgrc file looks like this: ::
   435 For me the hgrc file looks like this: ::
   445     HG: --
   446     HG: --
   446     HG: user: Shantanu Choudhary <shantanu@fossee.in>
   447     HG: user: Shantanu Choudhary <shantanu@fossee.in>
   447     HG: branch 'default'
   448     HG: branch 'default'
   448     HG: changed feviStick.py 
   449     HG: changed feviStick.py 
   449 
   450 
   450 This would be vi sort of editor, 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 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 
   452 
   452     $ hg tip
   453     $ hg tip
   453     changeset:   3:e1ab2aff4ddd
   454     changeset:   3:e1ab2aff4ddd
   454     tag:         tip
   455     tag:         tip
   455     user:        Shantanu Choudhary <shantanu@fossee.in>
   456     user:        Shantanu Choudhary <shantanu@fossee.in>
   472     tag:         tip
   473     tag:         tip
   473     user:        Shantanu Choudhary <shantanu@fossee.in>
   474     user:        Shantanu Choudhary <shantanu@fossee.in>
   474     date:        Sun Aug 23 23:32:01 2009 +0530
   475     date:        Sun Aug 23 23:32:01 2009 +0530
   475     summary:     Changed tagline for feviStick.py.
   476     summary:     Changed tagline for feviStick.py.
   476 
   477 
   477 And the hg push command does the actual push. ::
   478 And the *hg push* command does the actual push. ::
   478 
   479 
   479     $ hg push ../Fevicol
   480     $ hg push ../Fevicol
   480     pushing to ../Fevicol
   481     pushing to ../Fevicol
   481     searching for changes
   482     searching for changes
   482     adding changesets
   483     adding changesets
   501    $ hg up tip
   502    $ hg up tip
   502    1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   503    1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   503    $ $ cat feviStick.py 
   504    $ $ cat feviStick.py 
   504    print 'Ab no more Chip Chip'
   505    print 'Ab no more Chip Chip'
   505 
   506 
   506 Dos and Don'ts with Mercurial:
   507 Merging the Work:
   507 ==============================
   508 ~~~~~~~~~~~~~~~~~
   508 
   509 
   509 
   510 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: 
       
   511 
       
   512 Two persons, changu and mangu are contributing on same project. Both starts from cloning the same online repo(lets say present state A), so that both have a working local repo. Now changu edits one of file, commits the changes and pushes to the repo, hence changing the state of repo to B, but mangu, have not updated his repo, makes a change in one of files and reaches to a different state C. Now when changu pulls repo from mangu, his repo will have multiple heads. This stage is clearly ambiguous the repo of changu 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 changu will have to merge changes so that everything becomes consistent again.
       
   513 
       
   514 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: ::
       
   515 
       
   516     $ cd Fevicol-clone
       
   517     $ hg tip
       
   518     changeset:   3:e1ab2aff4ddd
       
   519     tag:         tip
       
   520     user:        Shantanu Choudhary <shantanu@fossee.in>
       
   521     date:        Sun Aug 23 23:32:01 2009 +0530
       
   522     summary:     Changed tagline for feviStick.py.
       
   523 
       
   524 The tagline for feviCol.py is not complete, so we make changes in that file in this repo. ::
       
   525 
       
   526     $ echo "print 'Yeh Fevicol ka Majboot jod hai, tootega nahin'" > feviStick.py
       
   527     $ hg st
       
   528     M feviStick.py
       
   529 
       
   530 And commit the changes made ::
       
   531 
       
   532     $ hg ci -u "Shantanu <shantanu@fossee.in>" -m "Updated tag line for feviCol.py."
       
   533     $ hg st
       
   534     $ hg tip
       
   535     changeset:   4:caf986b15e05
       
   536     tag:         tip
       
   537     user:        Shantanu <shantanu@fossee.in>
       
   538     date:        Tue Aug 25 16:28:24 2009 +0530
       
   539     summary:     Updated tag line for feviCol.py.
       
   540 
       
   541 Now we will make some changes on Fevicol repo. We will add new file here ::
       
   542 
       
   543     $ cd Fevicol
       
   544     $ echo "print 'Jor laga ke hayyiya'" > firstAdd.py
       
   545     $ hg st
       
   546     ? firstAdd.py
       
   547     $ hg add firstAdd.py
       
   548     $ hg st
       
   549     A firstAdd.py
       
   550     $ hg ci -u "Shantanu <shantanu@fossee.in>" -m "Added firsAdd.py."
       
   551     $ hg tip
       
   552     changeset:   4:fadbd6492cc4
       
   553     tag:         tip
       
   554     user:        Shantanu <shantanu@fossee.in>
       
   555     date:        Tue Aug 25 16:46:24 2009 +0530
       
   556     summary:     Added firsAdd.py.
       
   557     
       
   558 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): ::
       
   559 
       
   560     $ hg pull ../Fevicol-clone 
       
   561     pulling from ../Fevicol-clone
       
   562     searching for changes
       
   563     adding changesets
       
   564     adding manifests
       
   565     adding file changes
       
   566     added 1 changesets with 1 changes to 1 files (+1 heads)
       
   567     (run 'hg heads' to see heads, 'hg merge' to merge)
       
   568 
       
   569 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. ::
       
   570 
       
   571     $ hg heads
       
   572     changeset:   5:caf986b15e05
       
   573     tag:         tip
       
   574     parent:      3:e1ab2aff4ddd
       
   575     user:        Shantanu <shantanu@fossee.in>
       
   576     date:        Tue Aug 25 16:28:24 2009 +0530
       
   577     summary:     Updated tag line for feviCol.py.
       
   578 
       
   579     changeset:   4:fadbd6492cc4
       
   580     user:        Shantanu <shantanu@fossee.in>
       
   581     date:        Tue Aug 25 16:46:24 2009 +0530
       
   582     summary:     Added firsAdd.py.
       
   583     
       
   584 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. ::
       
   585      
       
   586     $ hg glog
       
   587     o  changeset:   5:caf986b15e05
       
   588     |  tag:         tip
       
   589     |  parent:      3:e1ab2aff4ddd
       
   590     |  user:        Shantanu <shantanu@fossee.in>
       
   591     |  date:        Tue Aug 25 16:28:24 2009 +0530
       
   592     |  summary:     Updated tag line for feviCol.py.
       
   593     |
       
   594     | @  changeset:   4:fadbd6492cc4
       
   595     |/   user:        Shantanu <shantanu@fossee.in>
       
   596     |    date:        Tue Aug 25 16:46:24 2009 +0530
       
   597     |    summary:     Added firsAdd.py.
       
   598     |
       
   599     o  changeset:   3:e1ab2aff4ddd
       
   600     |  user:        Shantanu Choudhary <shantanu@fossee.in>
       
   601     |  date:        Sun Aug 23 23:32:01 2009 +0530
       
   602     |  summary:     Changed tagline for feviStick.py.
       
   603     |
       
   604     o  changeset:   2:a7912d45f47c
       
   605     |  user:        Shantanu <shantanu@fossee.in>
       
   606     |  date:        Sun Aug 23 22:34:35 2009 +0530
       
   607     |  summary:     Updated Content.
       
   608     |
       
   609     o  changeset:   1:d948fb4137c5
       
   610     |  user:        Shantanu <shantanu@fossee.in>
       
   611     |  date:        Sat Aug 22 00:11:25 2009 +0530
       
   612     |  summary:     Renamed pidiLite.py.
       
   613     |
       
   614     o  changeset:   0:84f5e91f4de1
       
   615        user:        Shantanu <shantanu@fossee.in>
       
   616        date:        Fri Aug 21 23:37:13 2009 +0530
       
   617        summary:     First commit.
       
   618 
       
   619 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. ::
       
   620 
       
   621     $ hg up
       
   622     abort: crosses branches (use 'hg merge' or 'hg update -C')
       
   623 
       
   624 *hg merge* command merge working directory with another revision. ::
       
   625 
       
   626     $ hg merge
       
   627     1 files updated, 0 files merged, 0 files removed, 0 files unresolved
       
   628     (branch merge, don't forget to commit) 
       
   629     $ hg tip 
       
   630     changeset:   5:caf986b15e05
       
   631     tag:         tip
       
   632     parent:      3:e1ab2aff4ddd
       
   633     user:        Shantanu <shantanu@fossee.in>
       
   634     date:        Tue Aug 25 16:28:24 2009 +0530
       
   635     summary:     Updated tag line for feviCol.py.
       
   636 
       
   637 After merging two branches, until we commit the results of merge it will keep on showing two heads. ::
       
   638 
       
   639     $ hg ci -u "Shantanu <shantanu@fossee.in>" -m "Merged branches of add and tag line."
       
   640     $ hg heads 
       
   641     changeset:   6:edbe97209954
       
   642     tag:         tip
       
   643     parent:      4:fadbd6492cc4
       
   644     parent:      5:caf986b15e05
       
   645     user:        Shantanu <shantanu@fossee.in>
       
   646     date:        Tue Aug 25 17:06:03 2009 +0530
       
   647     summary:     Merged branches of add and tag line.
       
   648 
       
   649 Here is brief and meaningful output of glog ::
       
   650 
       
   651     $ hg glog 
       
   652     @    changeset:   6:edbe97209954
       
   653     |\   tag:         tip
       
   654     | |  parent:      4:fadbd6492cc4
       
   655     | |  parent:      5:caf986b15e05
       
   656     | |  user:        Shantanu <shantanu@fossee.in>
       
   657     | |  date:        Tue Aug 25 17:06:03 2009 +0530
       
   658     | |  summary:     Merged branches of add and tag line.
       
   659     | |
       
   660     | o  changeset:   5:caf986b15e05
       
   661     | |  parent:      3:e1ab2aff4ddd
       
   662     | |  user:        Shantanu <shantanu@fossee.in>
       
   663     | |  date:        Tue Aug 25 16:28:24 2009 +0530
       
   664     | |  summary:     Updated tag line for feviCol.py.
       
   665     | |
       
   666     o |  changeset:   4:fadbd6492cc4
       
   667     |/   user:        Shantanu <shantanu@fossee.in>
       
   668     |    date:        Tue Aug 25 16:46:24 2009 +0530
       
   669     |    summary:     Added firsAdd.py.
       
   670 
       
   671 And we are back on track.
       
   672 
       
   673 Workflow:
       
   674 =========
       
   675 
       
   676 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. 
       
   677 
       
   678 For example: ::
       
   679     
       
   680     $ hg pull
       
   681     $ hg update
       
   682 
       
   683 This will grab the remote changes from the location you first cloned from. Then it will apply the changes. You can do this in one go with: ::
       
   684 
       
   685     $ hg pull -u
       
   686 
       
   687 Now let's say you make some changes. You edit a file and you want to commit your change. You can do this with: ::
       
   688 
       
   689     $ hg commit
       
   690 
       
   691 An editor will pop-up asking you to write a message describing your change. This is required. When you're done for the day, and you have required changesets sitting in your repository. Before pushing to upstream make sure to pull and update and merge branches if required, once everything looks okay and you have single track, push the changes, ::
       
   692 
       
   693     $ hg push
   510 
   694 
   511 Suggested Reading:
   695 Suggested Reading:
   512 ==================
   696 ==================
   513 
   697 
   514 	* http://karlagius.com/2009/01/09/version-control-for-the-masses/
   698 	* http://karlagius.com/2009/01/09/version-control-for-the-masses/