versionControl/handOut.rst
changeset 135 339230606dc0
parent 96 bb52cf47e920
child 136 68508b5175db
equal deleted inserted replaced
134:73012a0eb878 135:339230606dc0
     3 ===============
     3 ===============
     4 
     4 
     5 Introduction
     5 Introduction
     6 ============
     6 ============
     7 
     7 
     8 The following statement from a blog[1](http://karlagius.com/2009/01/09/version-control-for-the-masses/") aptly points usefulness of version control systems:
     8 Version control is just a way to track your files over time and share them.
     9 
     9 This allows you to go back to older versions when something goes wrong, see
    10 "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.
    10 what changed when and why, collaborate on a single piece of work with a bunch
    11 
    11 of people. 
    12 Version control (or source control) is nothing more complex than keeping copies of work as we make changes. 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 wrong."
    12 
    13 
    13 Like this
    14 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.
    14 `blog <http://karlagius.com/2009/01/09/version-control-for-the-masses/>`_
       
    15 aptly points out, "Version control is one of those weird, geeky things that
       
    16 never really gained much ground in non-geek fields, despite the fact that
       
    17 it’s blindingly useful." In this course, we are going to see a handful of
       
    18 such things, which are widely used in the programmer world, but not so much
       
    19 in the scientific computing world, even when if they would be very useful.
       
    20 
       
    21 Version control is just a way of backing up your files, before making changes
       
    22 to it. Most people would have cooked up their own version control system,
       
    23 without realizing, there are tools built by others, which make this task much
       
    24 more organized and systematic. You surely would've saved your files, some
       
    25 time or the other as ``oldproject.py``, ``latestproject.py`` and so on, or
       
    26 date-tagging them as ``project-21-01-10.py``, ``project-20-02-10.py`` and so
       
    27 on. 
    15 
    28 
    16 Why Use Version Control
    29 Why Use Version Control
    17 =======================
    30 =======================
    18  
    31  
    19 One of idea behind Version Control Tools was to build onto very first step which can be creating a empty file, or writing a first buggy program for assignment, rather than simply loose it. So here are some more reasons why is automated version control needed:
    32 We have seen that one of the main motivation to use a version system control
    20 
    33 system is the ability to go back to a working version of the file, when
    21     - 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.
    34 something stops working. Below are a few more advantages of using an
    22     - 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.
    35 automated version control system.
    23     - It can help to recover from mistakes. If a change made at some moment of time, turns out to be an 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.
    36 
    24 
    37     - It tracks the history and evolution of a project. It allows you to
    25 Most of these reasons are equally valid for the project having one man show, or hundred people. Besides projects, even it can be used to maintain assignments related to one particular subject/course, it will help manage things in way much better way. These tools can be used for better *resources management*. All codes, documents, presentation, assignments related to one course maintained in such a inventory can help avoiding accidental lose of data(deletion) and Internet hosting for version control will make the work immune to local hard-disk crash.
    38       track what changes were made at what point of time, when and by whom. 
       
    39 
       
    40     - If you are collaborating, as a team on a project, a version control
       
    41       system will make it much easier for you to collaborate. It allows you
       
    42       to work simultaneously on the same file, without worrying about merging
       
    43       your changes. 
       
    44 
       
    45     - A good version control system will help you efficiently track down bugs
       
    46       and pin-point the changes that introduced the bug, reducing your
       
    47       debugging time. 
       
    48 
       
    49 Version control is as useful for a one man show, as it is for a big group of
       
    50 people working on a project. As a student, you can use it to maintain your
       
    51 course work, too. You could maintain a version controlled repository with all
       
    52 your code, assignments, and other documents. Keeping your stuff version
       
    53 controlled will help avoid accidental deletion of individual files etc.
       
    54 Hosting it on a remote server will protect you from a local hard disk crash. 
       
    55 
       
    56 Mercurial
       
    57 =========
    26 
    58 
    27 Some of Version Control Tools available and used widely are:
    59 Some of Version Control Tools available and used widely are:
    28 
    60 
    29      - cvs (Concurrent Version System)
    61   - ``cvs`` (Concurrent Versions System)
    30      - svn (Subversion)
    62   - ``svn`` (Subversion)
    31      - hg (Mercurial)
    63   - ``hg`` (Mercurial)
    32      - bzr (Bazaar)
    64   - ``git`` 
    33      - git 
    65 
    34 
    66 Each of these tools have some unique functionality and their own merits and
    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.
    67 de-merits. In this course, we shall learn to use Mercurial or ``hg``.
    36 
    68 Once you know how to use ``hg``, you could easily try other tools and switch
    37 Learning the Lingo
    69 to one that you feel most comfortable with.
    38 ==================
    70 
    39 
    71 Why ``hg`` ?
    40 Here are some of terms which are going to used through out the rest of session:
    72 ------------
    41 
       
    42 Basic Setup
       
    43 -----------
       
    44 
       
    45 (should we include at all terms used by vcs's other than hg?)
       
    46 
       
    47      Repository(repo):
       
    48 	The folder with all the files.
       
    49      Server:
       
    50 	The system with the main(mother) repo.
       
    51      Trunk/Main:
       
    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.
       
    53 
       
    54 Basic Actions
       
    55 -------------
       
    56      
       
    57      Add:
       
    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:
       
    62 	What version a file is on.
       
    63      Clone:
       
    64      	Creating initial copy of the repo onto a local machine.
       
    65      Commit:
       
    66      	Committing the changes done to the repo in terms of contents of the files or adding/removing of the files.
       
    67      Logs/History:
       
    68 	Logs of all the past changes done to the repo.
       
    69      Update:
       
    70         Updating the local repo with the main one, includes both, adding changing done by us or importing changes done by others.
       
    71      Revert:
       
    72         Going back to previous committed state of file.
       
    73 
       
    74 Advanced Actions:
       
    75 -----------------
       
    76 
       
    77      Branch:
       
    78 	Create a separate copy of the repo for private use (bug fixing, testing, etc).
       
    79      Diff/Change:
       
    80 	Finding the differences between two versions of a file.
       
    81      Merge (or patch):
       
    82      	Apply the changes from one branch to another, to bring it up-to-date.
       
    83      Conflict:
       
    84 	When pending changes to a file contradict each other (both changes cannot be applied).
       
    85      
       
    86 Types of Version Control:
       
    87 -------------------------
       
    88 
       
    89 (should we have this part at all?)
       
    90 Based on how source/code management is carried out in a tool there are two categories of Version Control Systems(VCS):
       
    91 
       
    92       - Centralized VCS: 
       
    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.
       
    94    
       
    95       - Distributed VCS:
       
    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.
       
    97 
       
    98 Get Going with Hg:
       
    99 ==================
       
   100 
       
   101 Why hg?
       
   102 -------
       
   103 
    73 
   104    - easy to learn and use.
    74    - easy to learn and use.
   105    - lightweight.
    75    - lightweight.
   106    - scales excellently.
    76    - scales excellently.
   107    - based on Python.
    77    - based on Python.
   108 
    78 
   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.
    79 Installation
   110 
    80 ------------
   111 Installation:
    81 
   112 -------------
    82 - For Linux based systems, hg is available in most of package management. So
   113 
    83   for say Ubuntu systems::
   114 - For Linux based systems, hg is available in most of package management. So for say Ubuntu systems::
       
   115 
    84 
   116    $ sudo apt-get install mercurial
    85    $ sudo apt-get install mercurial
   117 
    86 
   118   will be all you need to install hg. Similarly Fedora users can use yum to install hg. 
    87   will be all you need to install hg. Similarly Fedora users can use yum to
   119 
    88   install hg.
   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.
    89 
   121 
    90 - For Windows and Mac OS X systems the setup can be downloaded from
   122 Getting Started:
    91   http://mercurial.selenic.com/downloads/ and standard installation can be
       
    92   followed.
       
    93 
       
    94 Just say ``hg`` in your shell, to see some of the commands that ``hg``
       
    95 provides and say ``hg version`` to see the version of ``hg`` that has
       
    96 been installed on your system. 
       
    97 
       
    98 Let there be Repository
       
    99 =======================
       
   100 
       
   101 To start using Mercurial (or ``hg``) and get the benefits of using a version
       
   102 control system, we should first have a **repository**. A repository is a
       
   103 folder with all your files and a store of all the changes that were made to
       
   104 it. To save disk space, ``hg`` doesn't save all the files, but only saves
       
   105 only a series of changes made to the files.
       
   106 
       
   107 We have talked of an example of how we cook up our own version control
       
   108 systems. Mercurial does almost the same thing with one major difference. It
       
   109 doesn't keep track of individual files. It keeps snapshots of the whole
       
   110 directory (or repository), instead of individual files.
       
   111 
       
   112 A repository can either be started using an ``init`` command or an existing
       
   113 repository could be **cloned**.
       
   114 
       
   115 Let us look at creating our own repository, now. We can look at obtaining
       
   116 already existing repositories, at a later stage.
       
   117 
       
   118 Let's say we have a folder called ``book``, which has all the chapters of a
       
   119 book as text files. Let us convert that folder, into a ``hg`` repository.
       
   120 
       
   121 ::
       
   122 
       
   123     $ cd book/
       
   124     $ ls -a
       
   125     . .. chapter1.txt chapter2.txt chapter3.txt 
       
   126     $ 
       
   127     
       
   128 We have three chapters in the folder. We convert this folder into a mercurial
       
   129 repository using the ``hg init`` command
       
   130 
       
   131 ::
       
   132 
       
   133     $ hg init
       
   134     $ ls -a
       
   135     . .. .hg chapter1.txt chapter2.txt chapter3.txt 
       
   136     $ 
       
   137 
       
   138 The ``.hg`` directory indicates that our book directory is now a ``hg``
       
   139 repository. Mercurial keeps all the history of the changes made, and a few
       
   140 other config files, etc. in this directory. The directory, ``book`` is called
       
   141 our **working directory**. 
       
   142 
       
   143 Adding Files
       
   144 ------------
       
   145 
       
   146 We now have a fresh repository, but all our files are not being tracked or
       
   147 watched by ``mercurial``, yet. We need to explicitly ask it to watch the
       
   148 files, that we want it to.
       
   149 
       
   150 To see this use the ``hg status`` command. 
       
   151 ::
       
   152 
       
   153     $ hg status
       
   154     ? chapter1.txt
       
   155     ? chapter2.txt
       
   156     ? chapter3.txt
       
   157 
       
   158 
       
   159 We see the three files for the chapters, but they are preceded by a ``?``
       
   160 mark. What does it mean?
       
   161 
       
   162 We use the ``help`` command to see what this means. 
       
   163 ::
       
   164 
       
   165     $ hg help status 
       
   166     ...
       
   167     The codes used to show the status of files are:
       
   168 
       
   169       M = modified
       
   170       A = added
       
   171       R = removed
       
   172       C = clean
       
   173       ! = missing (deleted by non-hg command, but still tracked)
       
   174       ? = not tracked
       
   175       I = ignored
       
   176         = origin of the previous file listed as A (added)
       
   177     ...
       
   178 
       
   179 By looking at the codes, it is clear that our files are not *yet* being
       
   180 tracked by ``hg``. We now use the add command to ask ``hg`` to track these
       
   181 files.
       
   182 
       
   183 The ``status`` command gives the *status* of our working-directory at this
       
   184 point in time. Using this command after every ``hg`` command you use, is a
       
   185 good idea, at least until you are reasonably comfortable with the use of
       
   186 ``hg``.
       
   187 
       
   188 ::
       
   189 
       
   190     $ hg add
       
   191     adding chapter1.txt
       
   192     adding chapter2.txt
       
   193     adding chapter3.txt
       
   194     $ hg status
       
   195     A chapter1.txt
       
   196     A chapter2.txt
       
   197     A chapter3.txt
       
   198     $
       
   199 
       
   200 This simply adds all the files in the (working) directory, to the repository.
       
   201 As expected, the ``status`` command shows an ``A`` before he file names.
       
   202 
       
   203 Taking Snapshots
   123 ----------------
   204 ----------------
   124 
   205 
   125 After installation is complete lets get started with using. First things first, lets pay our homage to *man* pages as per rituals: ::
   206 We have added a set of new files to the repository, but we haven't told
   126    
   207 mercurial to remember these changes, i.e., to take a snapshot at this point
   127    $ man hg
   208 in time. We do this by using the ``commit`` command.
   128 
   209 
   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 ::
   210 ::
   130 
   211 
   131    $ hg help
   212     $ hg commit 
   132 
   213 
   133    Mercurial Distributed SCM
   214 We are now prompted with a new editor window. We type out our message here
   134    list of commands:
   215 describing the changes that we have made.
   135    add          add the specified files on the next commit
   216 
   136    addremove	-----------------------
   217 ::
   137    ------------------------------------
   218 
   138    heads        show current repository heads or show branch heads
   219     Initial Commit
   139    ------------------------------------
   220 
   140 
   221     HG: Enter commit message.  Lines beginning with 'HG:' are removed.
   141 For specific command, just follow the command name after the help. ::
   222     HG: Leave message empty to abort commit.
   142 
   223 
   143     $ hg help diff
   224 Mercurial has now taken a snapshot of our repository and has attached our
   144     hg diff [OPTION]... [-r REV1 [-r REV2]] [FILE]...
   225 description along with it. To see the status of the files in the repository,
   145 
   226 use the ``hg status`` command. 
   146     diff repository (or selected files)
   227 
   147     Show differences between revisions for the specified files.
   228 ::
   148     Differences between files are shown using the unified diff format.
   229 
   149     NOTE:____________
   230     $ hg st
   150 
   231     $
   151 Let there be Repository:
   232     
   152 ------------------------
   233 The command does not return anything, when there are no uncommitted changes.
   153 
   234 Also, notice that I have started getting lazy and used only a short name
   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.
   235 ``st`` for the status command. Mercurial accepts short names, as long as they
   155 
   236 can be disambiguated (just like tab completion).
   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. 
   237 
   157 
   238 Viewing the History
   158 Say we have a directory which we want to bring under version control, so we start a new repository using *hg init*: ::
   239 -------------------
   159 
   240 
   160   $ ls -a circulate/
   241 To see the history of the changes to our repository, we use ``hg log``. We
   161   .  ..  lena.png  pendulum.txt  points.txt  pos.txt  sslc1.py  sslc1.txt
   242 can view the change that we just made to our repository.
   162   $ cd circulate/
   243 
   163   $ hg init
   244 ::
   164   $ ls -a
   245 
   165   .  ..  .hg  lena.png  pendulum.txt  points.txt  pos.txt  sslc1.py  sslc1.txt
   246     $ hg log
   166 
   247     changeset:   0:cbf6e2a375b4
   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.
   248     tag:         tip
   168 
   249     user:        punchagan@shrike.aero.iitb.ac.in
   169 For getting already existing repo hg uses command *"clone"* ::
   250     date:        Fri Jan 28 14:04:07 2011 +0530
   170 
   251     summary:     Initial Commit
   171       $ hg clone http://hg.serpentine.com/tutorial/hello localCopyhello
   252 
   172 
   253 
   173       requesting all changes
   254 As we already discussed, mercurial keeps track of the changes that are made
   174       adding changesets
   255 to the files in the repository. Notice, that our ``log`` is showing a
   175       adding manifests
   256 **changeset**. A change set is nothing but a set of changes made to the
   176       adding file changes
   257 repository between two consecutive commits (the action of taking snapshots).
   177       added 5 changesets with 5 changes to 2 files
   258 Notice that ``hg`` also shows the date at which the commit was made and the
   178       updating working directory
   259 description of the changeset.
   179       2 files updated, 0 files merged, 0 files removed, 0 files unresolved
   260 
   180 
   261 User information
   181 If clone succeeded, there would be a local directory called localCopyhello, with some files: ::
       
   182 
       
   183       $ ls localCopyhello/
       
   184       hello.c  Makefile
       
   185 
       
   186 Every Mercurial repository is complete, self-contained, and independent. It contains its own private copy of a project's files and history.
       
   187 
       
   188 Creating a branch of existing local repo is very easy via hg using clone command: ::
       
   189 	
       
   190      $ hg clone localCopyhello newCopy
       
   191     updating working directory
       
   192     2 files updated, 0 files merged, 0 files removed, 0 files unresolved
       
   193 
       
   194 newCopy is exact copy of already existing repo. These local branches can prove really handy at times. It allows keep multiple copies of local branch for different purposes, say for debugging, testing, working version.
       
   195 	
       
   196 History or Logs:
       
   197 ----------------
   262 ----------------
   198 
   263 
   199 For the new repo created, first thing which can be tried is to check the logs/history. What changes were made and when and why, answers to all those questions are stored in logs safely. So for the cloned repo the history can be viewed using command *"log"* (following commands are wrt localCopyhello repo). ::
   264 But there is a slight problem with the user details that mercurial is saving.
       
   265 It saves my username with my machine name. It is a general good practice to
       
   266 use your full name with your email id. We set our username in the ``.hgrc``
       
   267 file in our Home folder. (``$HOME/.hgrc`` on Unix like systems and
       
   268 ``%HOME%\.hgrc`` on Windows systems)
       
   269 
       
   270 We open the file in our favorite editor and add the username details. 
       
   271 
       
   272 ::
       
   273 
       
   274     $ emacs ~/.hgrc  
       
   275     [ui]
       
   276     username = Puneeth Chaganti <punchagan@fossee.in>
       
   277 
       
   278 We have now set the username details for mercurial to use, in all our future
       
   279 commits. (Note: You can also set user preferences at the repository level.
       
   280 Exercise-N asks you to do that)
       
   281 
       
   282 Let us now make another commit to see if this has taken effect. Let us
       
   283 add author information to all the chapters that we have. 
       
   284 
       
   285 ::
       
   286 
       
   287     Author: Puneeth Chaganti <punchagan@fossee.in>
       
   288 
       
   289 
       
   290 Once we have added this to all the files, let us commit this change. We again
       
   291 used the ``hg commit`` command to commit the changes that we have made.
       
   292 
       
   293 ::
       
   294 
       
   295     $ hg commit
       
   296 
       
   297 We are again prompted with the editor window to enter our commit message and
       
   298 we type out our commit message. There are some good practices when typing out
       
   299 a commit message too. It is a general practice to have a summary line in the
       
   300 commit message which is no longer than 60 to 65 characters giving a summary
       
   301 of the change we have made. This is followed up with an explanation of why
       
   302 this was changed, what is the effect of this change, known bugs/issues
       
   303 remaining, if any, etc.
       
   304 
       
   305 ::
       
   306 
       
   307     Add author info to all the chapters
       
   308 
       
   309     All the chapters must have an author info. Added Puneeth Chaganti
       
   310     as the author. New authors can be added in newlines.              
       
   311 
       
   312     HG: Enter commit message.  Lines beginning with 'HG:' are removed.
       
   313     HG: Leave message empty to abort commit.
       
   314 
       
   315 ``hg log`` should now show us both the changes that we have made. Notice that
       
   316 the username settings are being used and also, the summary of the changeset
       
   317 shows only the first line in the description that we have added. Also, notice
       
   318 that ``hg`` shows the commits in the reverse chronological order, which is
       
   319 useful.
       
   320 
       
   321 Mercurial Magic
       
   322 ===============
       
   323 
       
   324 You must already be wondering, why we need all the overhead of
       
   325 ``commit`` and ``log``, etc. What is all this fuss about? "Isn't it
       
   326 just a waste of time?"
       
   327 
       
   328 Reverting Changes
       
   329 -----------------
       
   330 
       
   331 While you were wondering, let's say your friend walks in and together you
       
   332 make a lot of changes.
       
   333 
       
   334 1. You replace all the occurrences of ``&`` in ``chapter1.txt`` with
       
   335 ``and``. 
       
   336 2. You delete the ``chapter3.txt`` file. 
       
   337 
       
   338 ::
       
   339 
       
   340     $ rm chapter3.txt
       
   341     $ hg st
       
   342     M chapter1.txt
       
   343     ! chapter3.txt
       
   344     $ 
       
   345 
       
   346 
       
   347 But after a while, you realize that these changes are unwarranted. You
       
   348 want to go back to the previous state, undoing all the changes that
       
   349 you made, after your friend arrived. 
       
   350 
       
   351 The undo in your editor may allow undoing the first change (if you
       
   352 haven't closed it after making the changes) but there's no way you
       
   353 could get back your ``chapter3.txt`` file, using your editor. But
       
   354 don't worry. Mercurial to the rescue!
       
   355 
       
   356 We shall use the ``revert`` command of ``hg`` to undo all the changes
       
   357 after the last commit. As we want to undo all the changes, we use the
       
   358 ``revert`` command with the ``--all`` argument. 
       
   359 
       
   360 ::
       
   361 
       
   362     $ hg revert --all
       
   363     reverting chapter1.txt
       
   364     reverting chapter3.txt
       
   365     $ hg st
       
   366     ? chapter1.txt.orig
       
   367     $ ls
       
   368     chapter1.txt  chapter1.txt.orig  chapter2.txt  chapter3.txt
       
   369 
       
   370 As you can see the ``chapter3.txt`` file has been restored. But ``hg``
       
   371 gives you a new file ``chapter1.txt.orig``. Mercurial actually doesn't
       
   372 like to delete any of the changes that you have made. So, it makes a
       
   373 back-up of the file ``chapter1.txt`` in the present state and gives
       
   374 you back the old file. 
       
   375 
       
   376 If we now decide, that we want to ``redo`` the changes that we had
       
   377 done to the ``chapter1``, we can just overwrite the ``chapter1.txt``
       
   378 file with the backed up file. 
       
   379 ::
       
   380 
       
   381     $ mv chapter1.txt.orig chapter1.txt
       
   382     $ hg st
       
   383     M chapter1.txt
       
   384     $
       
   385 
       
   386 Viewing Changes
       
   387 ---------------
       
   388 
       
   389 Let's say we now want to ``commit`` these changes, but we are not sure
       
   390 of all the changes that we have made to the file, since it's been a
       
   391 while after we made the changes. We could use the ``diff`` command to
       
   392 see all the changes that have been made in the file. 
       
   393 
       
   394 ::
       
   395 
       
   396     $ hg diff
       
   397     diff -r 3163b8db10bb chapter1.txt
       
   398     --- a/chapter1.txt	Fri Jan 28 16:21:29 2011 +0530
       
   399     +++ b/chapter1.txt	Fri Jan 28 16:22:41 2011 +0530
       
   400     @@ -8,9 +8,9 @@
       
   401        1 Session
       
   402      Table of Contents
       
   403      =================
       
   404     -1 Introduction & Motivation 
       
   405     -2 Creating & Getting repositories 
       
   406     +1 Introduction and Motivation 
       
   407     +2 Creating and Getting repositories 
       
   408      3 Revision history 
       
   409     -4 Making & sharing changes 
       
   410     -5 Merges & Conflicts 
       
   411     +4 Making and sharing changes 
       
   412     +5 Merges and Conflicts 
       
   413 
       
   414 You see some cryptic output, but it's essentially giving you the list
       
   415 of changes made to the file. All the lines that were deleted are
       
   416 preceded by a ``-`` and all the new-lines are preceded by a ``+``. You
       
   417 can see that the ``&`` occurrences have been replaces with ``and``. 
       
   418 
       
   419 Let us now commit this change. 
       
   420 ::
       
   421 
       
   422     $ hg commit
       
   423 
       
   424     Replace all occurrences of & with and
       
   425 
       
   426     On the suggestion of Madhusudan C S. 
       
   427 
       
   428     HG: Enter commit message.  Lines beginning with 'HG:' are removed.
       
   429     HG: Leave message empty to abort commit.
       
   430     
       
   431 ::
       
   432 
       
   433     $ hg log    
       
   434 
       
   435 We can see the history of all the commits that we have made in our
       
   436 project. As you can see, the logs have started getting longer (and
       
   437 hence have been dropped from the output) and may even be getting out
       
   438 of our screens. Also, we are not very interested in all the commits in
       
   439 the project. We usually want to see the last few commits. 
       
   440 
       
   441 Revision Numbering
       
   442 ------------------
       
   443 
       
   444 Let us now see how to get logs of specific commits and a range of
       
   445 commits. Have a look at the logs that the previous ``log`` command has
       
   446 printed and look at the ``changeset`` line. It shows a number followed
       
   447 by a semi-colon and some long hexa-decimal string. The number is
       
   448 called the **revision number**. It is an identifier for the commit,
       
   449 and can be along with various commands to specify the revision number,
       
   450 if required. 
       
   451 
       
   452 Let us now check the logs of the very first commit of the project.
       
   453 ::
       
   454 
       
   455     $ hg log -r0
       
   456     changeset:   0:cbf6e2a375b4
       
   457     tag:         tip
       
   458     user:        punchagan@shrike.aero.iitb.ac.in
       
   459     date:        Fri Jan 28 14:04:07 2011 +0530
       
   460     summary:     Initial Commit
       
   461 
       
   462 Now, if we wish to get the logs of the latest commit only, how do we
       
   463 do it? We could specify the exact revision number of the commit (2) or
       
   464 just use -1 to start counting in the reverse chronological order. 
       
   465 ::
       
   466 
       
   467     $ hg log -r-1
       
   468     changeset:   2:98f7f4a1bb4d
       
   469     tag:         tip
       
   470     user:        Puneeth Chaganti <punchagan@fossee.in>
       
   471     date:        Fri Jan 28 16:24:42 2011 +0530
       
   472     summary:     Replace all occurrences of & with and
       
   473 
       
   474 You could also specify a range of commits whose logs you would like to
       
   475 see. Say, we would like to see the last two commits, 
       
   476 ::
       
   477 
       
   478     $ hg log -r-1:-2
       
   479 
       
   480 This is equivalent to using the following     
       
   481 ::
       
   482 
       
   483         $ hg log -r2:1
       
   484 
       
   485 You could also see the changes made to a particular file, in the
       
   486 specified range of the commits. Say, we wish to see the changes made
       
   487 to the ``chapter2.txt`` file in the last two commits. 
       
   488 ::
       
   489 
       
   490     $ hg log -r-1:-2 chapter2.txt
       
   491     changeset:   1:3163b8db10bb
       
   492     user:        Puneeth Chaganti <punchagan@fossee.in>
       
   493     date:        Fri Jan 28 16:21:29 2011 +0530
       
   494     summary:     Add author info to all the chapters
       
   495 
       
   496 Notice that it shows only the logs of revision 1, since no changes
       
   497 were made to the specified file in the second commit. 
       
   498 
       
   499 You can do all of this with the ``diff`` command to see the exact
       
   500 changes made to the files, instead of seeing the ``log`` message. This
       
   501 will be a part of your exercises. 
       
   502 
       
   503 Collaborating with Mercurial
       
   504 ============================
       
   505 
       
   506 When motivating the use of version control systems, we spoke a lot about
       
   507 collaboration and sharing our changes with our peers. Let us now see how we
       
   508 can share our project with our peers and collaborate with them. 
       
   509 
       
   510 Cloning Repositories
       
   511 --------------------
       
   512 
       
   513 For this purpose let us create a central repository, a copy of our
       
   514 repository, which is different from the one in which we are working. The
       
   515 ``clone`` command is used to **clone** or replicate an existing repository.
       
   516 
       
   517 ::
       
   518 
       
   519     $ hg clone book book-repo
       
   520 
       
   521 This creates a copy of our repository, ``book``, with the name ``book-repo``.
       
   522 The syntax of the ``clone`` command is -- ``hg clone SOURCE [DEST]``, where
       
   523 the optional argument DEST is being represented in brackets. Here we are
       
   524 giving book-repo as the destination. 
       
   525 
       
   526 The clone command can be used to replicate already existing repositories,
       
   527 either on your own machine or on some remote machine somewhere on the
       
   528 network. Since, ``hg`` maintains a copy of the full repository with every
       
   529 copy of the repository, the two copies that we have are exactly equivalent.
       
   530 
       
   531 ``book-repo`` is the repository we shall be using as a central repository
       
   532 and share it with our peers. 
       
   533 
       
   534 Sharing Repositories
       
   535 --------------------
       
   536 
       
   537 A mercurial repository can be shared in multiple ways. We shall use the
       
   538 ``http`` protocol to share the repository. Mercurial comes inbuilt with a
       
   539 tiny server that can be used to share your repository over the network. To
       
   540 start sharing the repository, we say 
       
   541 
       
   542 ::
       
   543 
       
   544     $ cd ../book-repo
       
   545     $ hg serve 
       
   546 
       
   547 This will start serving the repository on the network on the port 8000.
       
   548 Anybody in your network can access the repository in their browsers. Let us
       
   549 see how it looks, in our own browser. We open the url `http://localhost:8000`
       
   550 in our browser.     
       
   551 
       
   552 Let's say, our friend Madhu, now wants  to clone this repository. He will use
       
   553 our ip-address and the port on which  we are serving the repository, to clone
       
   554 the repository. Instead of using two machines, for the purposes of
       
   555 demonstration, we shall clone into our own machine, with a different name. 
       
   556 
       
   557 ::
       
   558 
       
   559     $ hg clone http://192.168.1.101:8000 book-madhu
       
   560 
       
   561 This will clone the repository to the folder, ``book-madhu``. The log of the
       
   562 repository will, obviously, be the same as our original repository. 
       
   563 
       
   564 ::
   200 
   565 
   201     $ hg log
   566     $ hg log
   202     changeset:   4:2278160e78d4
   567 
       
   568 Sharing Changes
       
   569 ---------------
       
   570 
       
   571 Let's say, Madhu now makes some changes to the repository. 
       
   572 
       
   573 1. He adds his name to the Authors list. 
       
   574 2. He moves down the Getting repositories part into a different section.  
       
   575 
       
   576 ::
       
   577 
       
   578     $ hg diff
       
   579     diff -r 98f7f4a1bb4d chapter1.txt
       
   580     --- a/chapter1.txt	Fri Jan 28 16:24:42 2011 +0530
       
   581     +++ b/chapter1.txt	Fri Jan 28 23:03:37 2011 +0530
       
   582     @@ -2,6 +2,7 @@
       
   583                             =======================
       
   584      
       
   585      Author: Puneeth Chaganti <punchagan@fossee.in>
       
   586     +        Madhusudan CS <madhusudancs@fossee.in>
       
   587      Date: 2011-01-28 13:58:47 IST
       
   588      
       
   589      
       
   590     @@ -9,8 +10,9 @@
       
   591      Table of Contents
       
   592      =================
       
   593      1 Introduction and Motivation 
       
   594     -2 Creating and Getting repositories 
       
   595     +2 Creating 
       
   596      3 Revision history 
       
   597      4 Making and sharing changes 
       
   598     -5 Merges and Conflicts 
       
   599     +5 Getting repositories 
       
   600     +6 Merges and Conflicts  
       
   601     $
       
   602 
       
   603 He then commits these changes and **pushes** them to the central repository
       
   604 that we have created. 
       
   605 
       
   606 ::
       
   607 
       
   608     $ hg commit
       
   609     $ hg push
       
   610     pushing to http://192.168.1.101:8000 
       
   611     searching for changes
       
   612     ssl required
       
   613 
       
   614 The push failed, obviously, since we have not taken care of access rights
       
   615 etc. It doesn't make much sense to allow anybody to make changes to a public
       
   616 repository, by default. We will need to make changes to the settings of the
       
   617 repository to allow this. **Note**: This is obviously not a safe way to share
       
   618 your repository, but for our purposes, this is sufficient.
       
   619 
       
   620 We add the following lines to the ``.hg/hgrc`` of the ``book-repo``
       
   621 repository. 
       
   622 ::
       
   623 
       
   624     [web]
       
   625     push_ssl=False
       
   626     allow_push=*
       
   627 
       
   628 This will allow anybody to push to the repository, now. 
       
   629 
       
   630 Madhusudan can now push and his changes will appear in the central
       
   631 repository. 
       
   632 
       
   633 ::
       
   634 
       
   635     $ hg push
       
   636     
       
   637 Let's confirm it in the web interface that we started with the ``hg serve``
       
   638 command. 
       
   639 
       
   640 Pulling Changes
       
   641 ---------------
       
   642 
       
   643 Let us now **pull** these changes into our original repository ``book`` that
       
   644 we have been working with. Before pulling the changes, we can use the command
       
   645 ``hg incoming`` to see the changes that have been made to the repository
       
   646 after our last **pull** and the changesets that will be coming into our
       
   647 repository after we do a **pull**. 
       
   648 
       
   649 ::
       
   650 
       
   651     $ hg incoming
       
   652     abort: repository default not found!
       
   653 
       
   654 What is going on here? This is because, we didn't clone our repository
       
   655 ``book`` from the central repository ``book-repo``. We can now add the
       
   656 location of the central repository to the ``hgrc`` file, of this project. 
       
   657 
       
   658 ::
       
   659 
       
   660     [paths]
       
   661     default = /home/punchagan/book-repo
       
   662 
       
   663 Now, we can check the incoming changes. 
       
   664 
       
   665 ::
       
   666 
       
   667     $ hg incoming
       
   668     searching for changes
       
   669     changeset:   3:3cd54926dbea
   203     tag:         tip
   670     tag:         tip
   204     user:        Bryan O'Sullivan <bos@serpentine.com>
   671     user:        Madhusudan CS <madhusudancs@fossee.in>
   205     date:        Sat Aug 16 22:16:53 2008 +0200
   672     date:        Fri Jan 28 23:08:25 2011 +0530
   206     summary:     Trim comments.
   673     summary:     Add my name to authors and move getting repositories section
   207 
   674     to 5
   208     changeset:   3:0272e0d5a517
   675 
   209     user:        Bryan O'Sullivan <bos@serpentine.com>
   676 
   210     date:        Sat Aug 16 22:08:02 2008 +0200
   677 To now **pull** these changes, we use the ``pull`` command. 
   211     summary:     Get make to generate the final binary from a .o file.
   678 
   212 
   679 ::
   213     changeset:   2:fef857204a0c
   680 
   214     user:        Bryan O'Sullivan <bos@serpentine.com>
   681     $ hg pull 
   215     date:        Sat Aug 16 22:05:04 2008 +0200
   682     pulling from /home/punchagan/book-repo
   216     summary:     Introduce a typo into hello.c.
       
   217 
       
   218     changeset:   1:82e55d328c8c
       
   219     user:        mpm@selenic.com
       
   220     date:        Fri Aug 26 01:21:28 2005 -0700
       
   221     summary:     Create a makefile
       
   222 
       
   223     changeset:   0:0a04b987be5a
       
   224     user:        mpm@selenic.com
       
   225     date:        Fri Aug 26 01:20:50 2005 -0700
       
   226     summary:     Create a standard "hello, world" program
       
   227 
       
   228 By default, this command prints a brief paragraph of output for each change to the project that was recorded.The fields in a record of output from hg log are as follows:
       
   229 
       
   230    - changeset: This field is a identifier for the changeset. The hex string is a unique identifier.
       
   231    - user: The identity of the person who created the changeset.
       
   232    - date: The date and time on which the changeset was created.
       
   233    - summary: The first line of the text message entered to describe the changeset.
       
   234 
       
   235 To narrow the output of hg log down to a single revision, use the -r option. ::
       
   236    
       
   237    $ hg log -r 3
       
   238    changeset:   3:0272e0d5a517
       
   239    user:        Bryan O'Sullivan <bos@serpentine.com>
       
   240    date:        Sat Aug 16 22:08:02 2008 +0200
       
   241    summary:     Get make to generate the final binary from a .o file.
       
   242 
       
   243 *range notation* can be used to get history of several revisions without having to list each one. ::
       
   244 
       
   245    $  hg log -r 2:4
       
   246    changeset:   2:fef857204a0c
       
   247    user:        Bryan O'Sullivan <bos@serpentine.com>
       
   248    date:        Sat Aug 16 22:05:04 2008 +0200
       
   249    summary:     Introduce a typo into hello.c.
       
   250 
       
   251    changeset:   3:0272e0d5a517
       
   252    user:        Bryan O'Sullivan <bos@serpentine.com>
       
   253    date:        Sat Aug 16 22:08:02 2008 +0200
       
   254    summary:     Get make to generate the final binary from a .o file.
       
   255 
       
   256    changeset:   4:2278160e78d4
       
   257    tag:         tip
       
   258    user:        Bryan O'Sullivan <bos@serpentine.com>
       
   259    date:        Sat Aug 16 22:16:53 2008 +0200
       
   260    summary:     Trim comments.
       
   261 
       
   262 -v option with "log" gives some extra details related to a changeset.
       
   263 
       
   264 Making Changes:
       
   265 ---------------
       
   266 
       
   267 Lets follow a simple exercise of *managing letters* using hg. We create a new directory and start revision tracking on it.::
       
   268 
       
   269   $  mkdir letter
       
   270   $  cd letter
       
   271   $  touch letter.tex
       
   272   $  hg init
       
   273 
       
   274 Now lets try to create a local clone of this repository::
       
   275 
       
   276   $  hg clone letter letter-clone
       
   277   updating working directory
       
   278   0 files updated, 0 files merged, 
       
   279   0 files removed, 0 files unresolved 
       
   280 
       
   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::
       
   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."
       
   297    $ hg log
       
   298    changeset:   0:210664b4ed58
       
   299    tag:         tip
       
   300    user:        Shantanu <shantanu@fossee.in>
       
   301    date:        Tue Feb 23 19:41:45 2010 +0530
       
   302    summary:     First commit.
       
   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 
       
   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. ::
       
   311 
       
   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
       
   317    $ hg st
       
   318    A letter-personal.tex
       
   319    A letter-pro.tex
       
   320    R letter.tex
       
   321    $ hg ci -u "Shantanu <shantanu@fossee.in>" -m "Renamed and added letters."
       
   322            
       
   323 *tip* command shows newest revision in the repository. ::
       
   324 
       
   325    $ hg tip
       
   326    changeset:   1:4a2d973a92de
       
   327    user:        Shantanu <shantanu@fossee.in>
       
   328    date:        Tue Feb 23 19:50:39 2010 +0530
       
   329    summary:     Renamed and added letters.
       
   330 
       
   331 Sharing Changes:
       
   332 ----------------
       
   333 
       
   334 Pulling from repo:
       
   335 ~~~~~~~~~~~~~~~~~~
       
   336 
       
   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. ::
       
   338 
       
   339    $ cd letter-clone
       
   340    $ hg pull 
       
   341    pulling from /home/baali/letter
       
   342    requesting all changes
       
   343    adding changesets
       
   344    adding manifests
       
   345    adding file changes
       
   346    added 2 changesets with 2 changes to 2 files
       
   347    (run 'hg update' to get a working copy)
       
   348 
       
   349 *changeset* means a list of changes made to a file. In words of *hg help*, pull command is: ::
       
   350 
       
   351    pull changes from the specified source
       
   352 
       
   353    Pull changes from a remote repository to a local one.
       
   354 
       
   355    This finds all changes from the repository at the specified path
       
   356    or URL and adds them to the local repository. By default, this
       
   357    does not update the copy of the project in the working directory.
       
   358 
       
   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.
       
   360 
       
   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. ::
       
   362 
       
   363    $ ls -a
       
   364    .  ..  .hg
       
   365    $ hg up
       
   366    2 files updated, 0 files merged, 
       
   367    0 files removed, 0 files unresolved
       
   368    $ ls -a
       
   369    .  ..  .hg  letter-personal.tex  
       
   370    letter-pro.tex
       
   371     
       
   372 To update to specific version, give a version number to the *hg update* command.
       
   373 
       
   374 Making Changes:
       
   375 ~~~~~~~~~~~~~~~
       
   376 
       
   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 ::
       
   378 
       
   379   \documentclass{letter}
       
   380   \begin{document}
       
   381   \begin{letter}{}
       
   382   \opening{Hello xxxxxx,}
       
   383   I really enjoyed meeting you in CS 101, 
       
   384   but would love to know you better. 
       
   385   How about a coffee on Thursday after class?
       
   386   \closing{-xxxxx}
       
   387   \end{letter}
       
   388   \end{document}
       
   389 
       
   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). ::
       
   391 
       
   392   $ hg st
       
   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. ::
       
   396 
       
   397     $ hg diff
       
   398     diff -r 4a2d973a92de letter-personal.tex
       
   399     --- a/letter-personal.tex	Tue Feb 23 19:50:39 2010 +0530
       
   400     +++ b/letter-personal.tex	Tue Jun 08 16:12:19 2010 +0530
       
   401     @@ -0,0 +1,11 @@
       
   402     +\documentclass{letter}
       
   403     +\begin{document}
       
   404     + 
       
   405     +\begin{letter}{}
       
   406     +\opening{Hello Jas,}
       
   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:
       
   417 	  
       
   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.
       
   419 	  - set HGUSER environment variable::
       
   420 
       
   421 	    $ export HGUSER="xxxxx"	  
       
   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. ::
       
   423 	  
       
   424 		[ui]
       
   425 		username = Firstname Lastname <email.address@example.net>
       
   426 
       
   427 	    For me the hgrc file for *letter* clone repo looks like this: ::
       
   428 
       
   429 	        [paths]
       
   430 		default = /home/baali/letter
       
   431 		[ui]	
       
   432 		username = Shantanu Choudhary <shantanu@fossee.in>
       
   433 
       
   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. ::
       
   435 
       
   436     Added content to personal letter.
       
   437     HG: Enter commit message.  Lines beginning with 'HG:' are removed.
       
   438     HG: --
       
   439     HG: user: Shantanu Choudhary <shantanu@fossee.in>
       
   440     HG: branch 'default'
       
   441     HG: changed letter-personal.tex
       
   442 
       
   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. ::
       
   444 
       
   445     $ hg tip
       
   446     changeset:   2:a5d8cb2fac01
       
   447     user:        Shantanu <shantanu@fossee.in>
       
   448     date:        Tue Feb 23 20:34:12 2010 +0530
       
   449     summary:     Added content to personal letter.
       
   450     
       
   451 One can do above mentioned procedure using following one line command: ::
       
   452 
       
   453     $ hg ci -u "Shantanu <shantanu@fossee.in>" -m "Added content to personal letter."
       
   454 
       
   455 Sharing Changes:
       
   456 ~~~~~~~~~~~~~~~~
       
   457 
       
   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. ::
       
   459 
       
   460     $ hg push ../Fevicol
       
   461     pushing to ../Fevicol
       
   462     searching for changes
   683     searching for changes
   463     adding changesets
   684     adding changesets
   464     adding manifests
   685     adding manifests
   465     adding file changes
   686     adding file changes
   466     added 1 changesets with 1 changes to 1 files
   687     added 1 changesets with 1 changes to 1 files
   467 
   688     (run 'hg update' to get a working copy)
   468 Same as with hg pull, the hg push command populates the changesets nothing more. ::
   689 
   469 
   690 
   470    $ cd ../letter
   691 *Note* that ``hg`` is giving us a message, asking us to run a ``hg update``
   471    $ hg tip
   692  to get a working copy. Let us try to understand what this is. 
   472    changeset:   2:a5d8cb2fac01
   693 
   473    user:        Shantanu <shantanu@fossee.in>
   694 As already explained, ``.hg`` folder has all the information about the
   474    date:        Tue Feb 23 20:34:12 2010 +0530
   695 changesets of the repository. When we do a ``pull`` the changesets from the
   475    summary:     Added content to personal letter.
   696 remote repository are pulled to our repository, but our working directory is
   476 
   697 not affected by these changes. To see this, we could use the ``hg parent``
   477 The branch where changes are being pushed still need *up* to be updated or for inclusion of all the imported changesets ::
   698 command. 
   478 
   699 
   479    $ hg up
   700 ::
   480    1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   701 
   481    $ cat letter-personal.tex
   702     $ hg parent
   482    \documentclass{letter}
   703     changeset:   2:98f7f4a1bb4d
   483    \begin{document} 
   704     user:        Puneeth Chaganti <punchagan@fossee.in>
   484    \begin{letter}{}
   705     date:        Fri Jan 28 16:24:42 2011 +0530
   485    \opening{Hello xxxx,}  
   706     summary:     Replace all occurrences of & with and
   486    I really enjoyed meeting you in CS 101, but would love to know you better. How about a coffee on Thursday after class?
   707     $ 
   487  
   708 
   488    \closing{-xxxx}
   709 As we can see, the parent is still our last commit, and the changes made by
   489    \end{letter}
   710 Madhusudan are still not in our working directory. To get these changes we do
   490    \end{document}
   711 the update as suggested by ``hg``. 
   491 
   712 
   492 Merging the Work:
   713 ::
   493 ~~~~~~~~~~~~~~~~~
   714 
   494 
   715     $ hg up
   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: 
   716     1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   496 
   717     $ hg parent
   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.
   718     changeset:   3:3cd54926dbea
   498 
   719     tag:         tip
   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: ::
   720     user:        Madhusudan CS <madhusudancs@fossee.in>
   500 
   721     date:        Fri Jan 28 23:08:25 2011 +0530
   501    $ cd letter-clone
   722     summary:     Add my name to authors and move getting repositories section
   502    $ hg tip
   723     to 5 
   503    changeset:   2:a5d8cb2fac01
   724     $
   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."
       
   535     $ hg tip
       
   536     changeset:   3:02b49a53063f
       
   537     user:        Shantanu <shantanu@fossee.in>
       
   538     date:        Wed Feb 24 13:12:26 2010 +0530
       
   539     summary:     Changed name.
       
   540     
   725     
   541 So now we have two repo, who have different commit history and tree. 
   726 As expected the **update** command updates the parent to the latest changes
   542 
   727 that we just pulled from the remote repository. 
   543 .. image:: glog-main.png 
   728 
   544 
   729 The update command can also be used to go back into an older revision, by
   545 .. image:: glog-suggestion.png
   730 specifying the revision to which we want to go to. 
   546 
   731 
   547 If we try to pull changes from one to another, this is how it goes(we are still in letter repo): ::
   732 ::
   548 
   733 
   549     $ hg pull ../letter-suggestion
   734     $ hg up -r1
   550     pulling from ../letter-suggestion
   735     1 files updated, 0 files merged, 0 files removed, 0 files unresolved
       
   736     $ hg parent
       
   737     changeset:   1:3163b8db10bb
       
   738     user:        Puneeth Chaganti <punchagan@fossee.in>
       
   739     date:        Fri Jan 28 16:21:29 2011 +0530
       
   740     summary:     Add author info to all the chapters
       
   741     $ hg cat chapter1.txt
       
   742     # Displays the contents of the chapter1.txt file as in revision 1. 
       
   743 
       
   744 To return to the latest revision we just use the ``up`` or ``update`` command
       
   745 without specifying any revision number. 
       
   746 
       
   747 ::
       
   748 
       
   749     $ hg up
       
   750     1 files updated, 0 files merged, 0 files removed, 0 files unresolved
       
   751     $ hg parent
       
   752     changeset:   3:3cd54926dbea
       
   753     tag:         tip
       
   754     user:        Madhusudan CS <madhusudancs@fossee.in>
       
   755     date:        Fri Jan 28 23:08:25 2011 +0530
       
   756     summary:     Add my name to authors and move getting repositories section
       
   757     to 5 
       
   758     $ 
       
   759 
       
   760 Simultaneous Changes
       
   761 --------------------
       
   762 
       
   763 Ok, we have been talking about collaboration, but this is a nice situation,
       
   764 where I was not changing anything while Madhusudan was changing the file,
       
   765 incidentally.  
       
   766 
       
   767 Now, let's say, both of us are editing the file at the same time, but
       
   768 different parts of it.  Say, I change the title of the section 2. 
       
   769 ::
       
   770 
       
   771     $ hg diff
       
   772     diff -r 3cd54926dbea chapter1.txt
       
   773     --- a/chapter1.txt	Fri Jan 28 23:08:25 2011 +0530
       
   774     +++ b/chapter1.txt	Fri Jan 28 23:45:19 2011 +0530
       
   775     @@ -10,7 +10,7 @@
       
   776      Table of Contents
       
   777      =================
       
   778      1 Introduction and Motivation 
       
   779     -2 Creating 
       
   780     +2 Creating repositories
       
   781      3 Revision history 
       
   782      4 Making and sharing changes 
       
   783      5 Getting repositories 
       
   784     $ hg commit 
       
   785     $ hg push
       
   786     pushing to /home/punchagan/book-repo
       
   787     searching for changes
       
   788     adding changesets
       
   789     adding manifests
       
   790     adding file changes
       
   791     added 1 changesets with 1 changes to 1 files
       
   792     $ 
       
   793     
       
   794 Also, let us assume Madhusudan adds an additional section called References. 
       
   795 ::
       
   796 
       
   797     $ hg diff
       
   798     diff -r 3cd54926dbea chapter1.txt
       
   799     --- a/chapter1.txt	Fri Jan 28 23:08:25 2011 +0530
       
   800     +++ b/chapter1.txt	Fri Jan 28 23:47:05 2011 +0530
       
   801     @@ -15,4 +15,4 @@
       
   802      4 Making and sharing changes 
       
   803      5 Getting repositories 
       
   804      6 Merges and Conflicts 
       
   805     -
       
   806     +7 References
       
   807     $ hg commit
       
   808     $ hg log
       
   809 
       
   810 Let us now compare the logs of the two repositories. You can see that both
       
   811 the repositories have their topmost revision numbered as 4, but they are both
       
   812 different. The identification number given to each revision is a local
       
   813 identification. The hexadecimal string following that number is the actual
       
   814 unique identification of that changeset, which will be unique across
       
   815 repositories.
       
   816 
       
   817 What happens now, when Madhusudan tries to push his changes to the central
       
   818 repository? 
       
   819 
       
   820 ::
       
   821 
       
   822     $ hg push
       
   823     pushing to http://192.168.1.101:8000 
       
   824     searching for changes
       
   825     abort: push creates new remote heads!
       
   826     (did you forget to merge? use push -f to force)
       
   827 
       
   828 
       
   829 The push failed! This is because, both of us have made changes, and they need
       
   830 to be merged somehow. **Don't**, just for this one instance, take the advice
       
   831 given by ``mercurial``. Using the ``-f`` would be disastrous. We will leave
       
   832 out a discussion of that, for this course. 
       
   833 
       
   834 Madhusudan now needs to pull the new changes that have been pushed to the
       
   835 repository after his last pull and **merge** them with his changes. 
       
   836 
       
   837 ::
       
   838 
       
   839     $ hg pull 
       
   840     pulling from http://192.168.1.101:8000 
   551     searching for changes
   841     searching for changes
   552     adding changesets
   842     adding changesets
   553     adding manifests
   843     adding manifests
   554     adding file changes
   844     adding file changes
   555     added 1 changesets with 1 changes to 1 files (+1 heads)
   845     added 1 changesets with 1 changes to 1 files (+1 heads)
   556     (run 'hg heads' to see heads, 'hg merge' to merge)    
   846     (run 'hg heads' to see heads, 'hg merge' to merge)
   557 
   847     $ hg merge
   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. ::
   848     merging chapter1.txt
   559 
   849     0 files updated, 1 files merged, 0 files removed, 0 files unresolved
   560     $ hg heads 
   850     (branch merge, don't forget to commit)
   561     changeset:   4:71fd776d856b
   851 
       
   852 We have now pull the changes from the central repository and merged them with
       
   853 the changes in our repository. But, ``hg`` is warning us not to forget to
       
   854 commit. Let's see what is the status of the repository at this point in time. 
       
   855 
       
   856 ::
       
   857 
       
   858     $ hg st
       
   859     M chapter1.txt
       
   860     $ hg diff
       
   861     diff -r bd57162c31f6 chapter1.txt
       
   862     --- a/chapter1.txt	Fri Jan 28 23:51:52 2011 +0530
       
   863     +++ b/chapter1.txt	Sat Jan 29 00:00:39 2011 +0530
       
   864     @@ -10,7 +10,7 @@
       
   865      Table of Contents
       
   866      =================
       
   867      1 Introduction and Motivation 
       
   868     -2 Creating 
       
   869     +2 Creating repositories
       
   870      3 Revision history 
       
   871      4 Making and sharing changes 
       
   872      5 Getting repositories 
       
   873 
       
   874 As you can see, the changes pushed by us, changing the name of the section 2,
       
   875 have now been made in the repository of Madhusudan. We will now need to
       
   876 commit these changes. 
       
   877 
       
   878 ::
       
   879 
       
   880     $ hg commit
       
   881     
       
   882 We shall be using a commit message that makes it clear that we are merging.
       
   883 We can now push this changes to the central repository. We could also check
       
   884 the changes that will be pushed, before pushing them, using the ``hg
       
   885 outgoing`` command. 
       
   886 ::
       
   887 
       
   888     $ hg outgoing
   562     tag:         tip
   889     tag:         tip
   563     parent:      2:a5d8cb2fac01
   890     parent:      5:bd57162c31f6
   564     user:        Vattam <vattam@fossee.in>
   891     parent:      4:5c88c36f60de
   565     date:        Wed Feb 24 12:54:31 2010 +0530
   892     user:        Madhusudan CS <madhusudancs@fossee.in>
   566     summary:     Added some suggestions.
   893     date:        Sat Jan 29 00:02:53 2011 +0530
   567     
   894     summary:     Merge heads.
   568     changeset:   3:02b49a53063f
   895 
   569     user:        Shantanu <Shantanu@fossee.in>
   896     changeset:   5:bd57162c31f6
   570     date:        Wed Feb 24 13:12:26 2010 +0530
   897     parent:      3:3cd54926dbea
   571     summary:     Changed name.
   898     user:        Madhusudan CS <madhusudancs@fossee.in>
   572     
   899     date:        Fri Jan 28 23:51:52 2011 +0530
   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. ::
   900     summary:     Add additional References section
   574      
   901     $ hg push
   575     $ hg glog
   902     pushing to http://192.168.1.101:8000 
   576 
   903     searching for changes
   577 .. image:: heads.png
   904     adding changesets
   578 
   905     adding manifests
   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. ::
   906     adding file changes
   580 
   907     added 2 changesets with 2 changes to 1 files
   581     $ hg up
   908 
   582     abort: crosses branches (use 'hg merge' or 'hg update -C')
   909 The changes have now been successfully pushed! Let us look at the web
   583 
   910 interface of the repo, to see that the changes have actually taken place. Let
   584 *hg merge* command merge working directory with another revision. ::
   911 us also have a look at the graph to, try and understand what has happened. 
   585 
   912 
       
   913 As we can see, a branch was created, when both of us started editing the file
       
   914 simultaneously, and was then merged by Madhusudan CS. 
       
   915 
       
   916 Simultaneous Conflicting Changes
       
   917 --------------------------------
       
   918 
       
   919 We were lucky this time, in that we were editing separate parts of the file.
       
   920 What will happen if we edited the same portion of the file, at the same time?
       
   921 How would merges work? This will be the last thing that we are going to see
       
   922 in this part of the course. 
       
   923 
       
   924 Let's say both of us edit the title of the section 6. 
       
   925 
       
   926 Let's say, I make the following changes, commit them and push them. 
       
   927 
       
   928 ::
       
   929 
       
   930     $ hg diff
       
   931     diff -r ce3469a9446f chapter1.txt
       
   932     --- a/chapter1.txt	Sat Jan 29 00:02:53 2011 +0530
       
   933     +++ b/chapter1.txt	Sat Jan 29 10:30:21 2011 +0530
       
   934     @@ -14,5 +14,5 @@
       
   935      3 Revision history 
       
   936      4 Making and sharing changes 
       
   937      5 Getting repositories 
       
   938     -6 Merges and Conflicts 
       
   939     +6 Merging and resolving conflicts 
       
   940      7 References
       
   941     $ hg commit
       
   942     $ hg push
       
   943     ...
       
   944     added 1 changesets with 1 changes to 1 files
       
   945 
       
   946 Meanwhile, let's say Madhusudan was changing the same section title, as
       
   947 follows.      
       
   948 
       
   949 ::
       
   950 
       
   951     $ hg diff
       
   952     diff -r ce3469a9446f chapter1.txt
       
   953     --- a/chapter1.txt	Sat Jan 29 00:02:53 2011 +0530
       
   954     +++ b/chapter1.txt	Sat Jan 29 10:35:29 2011 +0530
       
   955     @@ -14,5 +14,5 @@
       
   956      3 Revision history 
       
   957      4 Making and sharing changes 
       
   958      5 Getting repositories 
       
   959     -6 Merges and Conflicts 
       
   960     +6 Simple Merges and Merges with Conflicts 
       
   961      7 References
       
   962     $ hg commit
       
   963     $ hg push
       
   964     pushing to http://192.168.1.101:8000 
       
   965     searching for changes
       
   966     abort: push creates new remote heads!
       
   967     (did you forget to merge? use push -f to force)
       
   968     $ hg pull 
       
   969     ...
       
   970     added 1 changesets with 1 changes to 1 files (+1 heads)
       
   971     (run 'hg heads' to see heads, 'hg merge' to merge)
   586     $ hg merge
   972     $ hg merge
   587     1 files updated, 0 files merged, 0 files removed, 0 files unresolved
   973     0 files updated, 1 files merged, 0 files removed, 0 files unresolved
   588     (branch merge, don't forget to commit)   
   974     (branch merge, don't forget to commit)
   589 
   975 
   590 After merging two branches, until we commit the results of merge it will keep on showing two heads. ::
   976 
   591 
   977 What happens now actually depends on how Mercurial is configured and the
   592     $ hg ci -u "Shantanu <shantanu@fossee.in>" -m "Merged branches."
   978 programs available in your machine. You will either get a diff view with 3
   593     $ hg glog 
   979 panes or ``merge`` will insert markers in your file at the points where the
   594 
   980 conflicts occur.
   595 .. image:: glog-2.png
   981 
   596 
   982 If you get a 3 pane view, the first pane is the actual file, where you make
   597 *And we are back on track.*
   983 changes, to resolve the conflicts. The second pane shows the changes that you
   598 
   984 made, to the file. The last pane shows the changes that you pulled from the
   599 Workflow:
   985 original repo. Once you are satisfied with the changes, save and quit. 
   600 =========
   986 
   601 
   987 If you have a very minimal system, you might end up getting a file with
   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. 
   988 change markers, the original file being backed up. Open the file and resolve
   603 
   989 the conflicts, deleting the markers. Once you are done, you need to tell
   604 For example: ::
   990 mercurial that you have resolved the conflicts manually. 
   605     
   991 
   606     $ hg pull
   992 ::
   607     $ hg update
   993 
   608 
   994     $ hg resolve -m chapter1.txt
   609 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: ::
   995 
   610 
   996 Whatever be the process you have used for the merge, you will now need to
   611     $ hg pull -u
   997 commit your changes, just like the simple merge that we performed. 
   612 
   998 
   613 Now let's say you make some changes. You edit a file and you want to commit your change. You can do this with: ::
   999 ::
   614 
  1000 
   615     $ hg commit
  1001     $ hg commit -m "Merge heads."
   616 
       
   617 An editor will pop-up asking you to write a message describing your change. 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, ::
       
   618 
       
   619     $ hg push
  1002     $ hg push
   620 
  1003 
   621 Cheatsheet
  1004 *Note*, we have used a different way to commit. We have used the ``-m``
       
  1005 argument with the commit message.
       
  1006 
       
  1007 We could look at the graph of the changes, in our web interface, being served
       
  1008 by the ``hg serve`` command. From the graph it is clear, how the merging has
       
  1009 occurred. 
       
  1010 
       
  1011 That brings us to the end of this tutorial on Mercurial. What we have covered
       
  1012 is nothing close to all the features of Mercurial. We've only scratched the
       
  1013 surface, but let's hope that this will get you started and you will be able
       
  1014 to organize your work and projects, better. 
       
  1015 
       
  1016 Additional Reading
       
  1017 ==================
       
  1018 
       
  1019 I strongly suggest you to go through the following topics, if and when you
       
  1020 start using Mercurial on a day-to-day basis. 
       
  1021 
       
  1022 1. ``.hgignore`` 
       
  1023 #. ``hg rollback`` 
       
  1024 #. ``hg bisect`` 
       
  1025 #. ``hg backout`` 
       
  1026 
       
  1027 
       
  1028 References
   622 ==========
  1029 ==========
   623 
  1030 
   624 .. image:: mod.png
  1031     - `A Visual Guide to Version Control <http://betterexplained.com/articles/a-visual-guide-to-version-control/>`_
   625 
  1032     - `Version Control for the Masses <http://karlagius.com/2009/01/09/version-control-for-the-masses/>`_
   626 Suggested Reading:
  1033     - `(Illustrated) Intro to Distributed Version Control <http://betterexplained.com/articles/intro-to-distributed-version-control-illustrated/>`_
   627 ==================
  1034     - `Understanding Mercurial <http://mercurial.selenic.com/wiki/UnderstandingMercurial>`_
   628 
  1035     - `A Tutorial on Using Mercurial <http://mercurial.selenic.com/wiki/Tutorial>`_
   629 	* http://karlagius.com/2009/01/09/version-control-for-the-masses/
  1036     - `Hg Init: a Mercurial tutorial <http://hginit.com/>`_
   630 	* http://betterexplained.com/articles/a-visual-guide-to-version-control/
  1037     - `Beginners Guides <http://mercurial.selenic.com/wiki/BeginnersGuides>`_
   631 	* http://en.wikipedia.org/wiki/Revision_control
  1038     - `Software Carpentry <http://software-carpentry.org/4_0/vc/>`_
   632 	* http://hgbook.red-bean.com/
  1039 
   633 	* http://betterexplained.com/articles/intro-to-distributed-version-control-illustrated/
  1040 
   634 	* http://wiki.alliedmods.net/Mercurial_Tutorial
  1041 Appendix A - Definitions
       
  1042 ========================
       
  1043 
       
  1044 Definitions of a few commonly used terms. 
       
  1045 
       
  1046 Add
       
  1047     Begin tracking a file (or a set of files) with Version Control. 
       
  1048 
       
  1049 Branch
       
  1050     A diverged line of development. 
       
  1051 
       
  1052 Changeset
       
  1053     An atomic collection of changes to the files in a repository. 
       
  1054 
       
  1055 Clone 
       
  1056     Creating a copy of an existing repository; New repo is self-contained. 
       
  1057 
       
  1058 Commit
       
  1059     Taking a snapshot of the changes made in the repository (after the
       
  1060     previous snapshot) 
       
  1061 
       
  1062 Conflict 
       
  1063     Occurs when two changesets have overlapping sections that have been
       
  1064     modified.
       
  1065 
       
  1066 Head
       
  1067     A changeset with no child changesets. 
       
  1068 
       
  1069 History
       
  1070     Cumulative of all the changesets of a repository. 
       
  1071 
       
  1072 Merge 
       
  1073     Combining two separate changesets into one merge changeset. 
       
  1074 
       
  1075 Repository (repo) 
       
  1076     - Loosely speaking, the folder with all the files and a store
       
  1077       of the change history.
       
  1078     - Strictly speaking, only the ``.hg`` directory that contains the change
       
  1079       history. 
       
  1080 
       
  1081 Revert
       
  1082     Going back to previous committed state of working directory or a file.
       
  1083 
       
  1084 Revision
       
  1085     A particular changeset. 
       
  1086 
       
  1087 Server
       
  1088     A machine which serves the repository. 
       
  1089 
       
  1090 Tip 
       
  1091     Most recently changed head in a repository. 
       
  1092 
       
  1093 Update
       
  1094     Updating the working directory to a particular revision or to the tip
       
  1095     revision. 
       
  1096 
       
  1097 Working Directory
       
  1098     The directory where all of the files and directories of the project are
       
  1099     present. 
       
  1100 
       
  1101 .. 
       
  1102    Local Variables:
       
  1103    mode: rst
       
  1104    indent-tabs-mode: nil
       
  1105    sentence-end-double-space: nil
       
  1106    fill-column: 77
       
  1107    End:
       
  1108