Difference between revisions of "Mercurial/Getting Started"

From Apache OpenOffice Wiki
Jump to: navigation, search
m (updating the local copy with new changes from the master: sp)
 
(38 intermediate revisions by 7 users not shown)
Line 1: Line 1:
[[Category:Mercurial]][[Category:SCM]]
+
{{Mercurial}}
 
__TOC__
 
__TOC__
  
Line 11: Line 11:
 
== Your checkout is a full repository ==
 
== Your checkout is a full repository ==
 
In a simplified view, every checkout is a full repository. You have history and version info for other branches in your local tree. So naturally such a checkout is rather big compared to a single-revision checkout done by cvs and svn. So you won't checkout a full repo every time (unless you have bandwidth to waste and too much time on your hands :-)
 
In a simplified view, every checkout is a full repository. You have history and version info for other branches in your local tree. So naturally such a checkout is rather big compared to a single-revision checkout done by cvs and svn. So you won't checkout a full repo every time (unless you have bandwidth to waste and too much time on your hands :-)
Instead you will regularily update your local copy with the changes that were added to the repository and then "clone" (that's the term used for a "checkout") your local repository instead.
+
Instead you will regularly update your local copy with the changes that were added to the repository and then "clone" (that's the term used for a "checkout") your local repository instead.
  
 
== Your commits go to your local repository first ==
 
== Your commits go to your local repository first ==
Line 19: Line 19:
 
== There are no version numbers anymore ==
 
== There are no version numbers anymore ==
 
Because multiple persons can do local commits, have different "local master copies" (somebody else could have pushed a change to the master before that alters the file you change yourself), it is impossible to refer to a specific version of a file by a version number. What is version 23 of a file? The one in your local copy, that doesn't exist on the master yet? Or version 23 of a file of another user that did commit the same file locally?
 
Because multiple persons can do local commits, have different "local master copies" (somebody else could have pushed a change to the master before that alters the file you change yourself), it is impossible to refer to a specific version of a file by a version number. What is version 23 of a file? The one in your local copy, that doesn't exist on the master yet? Or version 23 of a file of another user that did commit the same file locally?
So instead of version numbers, specific versions are refered to using "changeset" identifiers. Think of it as checksums.
+
So instead of version numbers, specific versions are referred to using "changeset" identifiers. Think of it as checksums.
 +
 
 +
{{Tip| Mercurial offers the possibilities to use easier to type numeric revisions instead of changeset identifiers during work with a local repository. But remember: these numbers have no meaning outside this specific local repository. Don't use them when communicating with others.}}
 +
 
 +
== Further reading ==
 +
Remembering the three points above are enough to get you going. If you want to know more you'll find all things Mercurial at the [[hg:|Mercurial Wiki]]. An excellent tutorial can be found in "tour" chapters of the [http://hgbook.red-bean.com/read/ Mercurial book], which is also available online. Another excellent illustrated tutorial aimed at a broad audience (written by [http://joelonsoftware.com/ Joel Spolski], no less) can be found [http://hginit.com/ here].
 +
 
 +
The Mercurial command line help is quite well written and concise. Make good use of it. Example:
 +
<pre>
 +
$ hg merge --help
 +
</pre>
 +
 
 +
To get an overview over all commands and some concepts type:
 +
<pre>
 +
$ hg help
 +
</pre>
  
 
= So how to use it then (aka: What commands do I have to type?) =
 
= So how to use it then (aka: What commands do I have to type?) =
This section is meant to summarize (sometimes duplicate) the [http://www.selenic.com/mercurial/wiki/ Documentation in the Mercurial wiki] - If you already know those pages, you won't find something new here..
 
  
== creating a local copy ==
+
You want to play around with the OpenOffice.org sources without bothering with all the things a OOo domain developer needs to keep in mind? You aren't interested in this CWS thing at all? Good, this section is for you.
Creating a local copy means to clone from the master - the URL for the [[Mercurial Pilot]] is http://hg.services.openoffice.org/hg/DEV300
+
 
  $ hg clone http://hg.services.openoffice.org/hg/DEV300 [target-directory]
+
== Creating a local copy ==
 +
Creating a local copy means to clone from the master - the URL for the the main OOo development code line is http://hg.services.openoffice.org/DEV300
 +
  $ hg clone http://hg.services.openoffice.org/DEV300 local_DEV300
 
If you know that you'll only use this as basis for different local clones and don't want it to create the actual source-files, then you can use
 
If you know that you'll only use this as basis for different local clones and don't want it to create the actual source-files, then you can use
  $ hg clone -U http://hg.services.openoffice.org/hg/DEV300 OOo-tip_repo-only
+
  $ hg clone -U http://hg.services.openoffice.org/DEV300 local_DEV300
This will create a repository-only version, i.e. you'll get an (apparently) empty OOo-tip-repo-only directory that holds the history/changeset data only, but not the actual files. Saves some diskspace and lessens the risk of modifying the master you intended to keep pristine.
+
This will create a treeless version, i.e. you'll get an (apparently) empty OOo-tip-repo-only directory that holds the history/changeset data only, but not the actual files. Saves some diskspace and lessens the risk of modifying the master you intended to keep pristine.
  
== updating the local copy with new changes from the master ==
+
{{Tip| The OOo mercurial repository is quite huge, so doing cloning from the OOo server will take substantial time. A significant faster way is to download a nightly (GMT) created so called ''[[hg:Bundle|bundle]]'' of DEV300 which is available at http://hg.services.openoffice.org/bundle/DEV300.hg. This bundle contains the full history in one highly compressed file (currently about 800MB in size). Create a treeless local DEV300 copy with
As mentioned above, doing a full clone every time would be a waste, so how to stay up-to-date then?
+
$ mkdir local_DEV300
(Well, for working on a cws you don't need this, only when you want "HEAD" (called "tip" in Mercurial) or when you want a local copy of a master that is not available locally)
+
$ cd local_DEV300
 +
$ hg init
 +
$ hg unbundle <path_to_bundle>/DEV300.hg
 +
and proceed with updating it with the latest changes as described below.}}
 +
 
 +
== Pulling new changes from the master and updating the local copy ==
 +
As mentioned above, doing a full clone from the OOo server every time would be a waste, so how to stay up-to-date then?
  
 
Updating means "pulling the new changes" from the master:
 
Updating means "pulling the new changes" from the master:
  $ cd DEV300 # change to the directory of your main clone
+
  $ cd local_DEV300 # change to the directory of your main clone
  $ hg pull http://hg.services.openoffice.org/hg/DEV300
+
  $ hg pull http://hg.services.openoffice.org/DEV300
'''Caveat''': While this grabs all the changes that were done on the master since the last checkout, it will *not* automatically update the source-code files on your disk. It basically only gets the history and changesets.
+
{{Warn| While this grabs all the changes that were done on the master since the last checkout, it will '''not''' automatically update the source-code files on your disk. It basically only gets the history and changesets.}}
This is of course no biggie if you use a repo-only master anyway - but if you want local source-files to reflect the newest changes, you need to do an update of your tree:
+
Not updating the source tree is just what we want for a treeless copy. But if you want local source-files to reflect the newest changes, you need to do an update of your tree:
 
  $ hg update
 
  $ hg update
 
Since pulling the newest changes and updating to those changes is rather common, you can use the -u switch to the pull command to do both in one go:
 
Since pulling the newest changes and updating to those changes is rather common, you can use the -u switch to the pull command to do both in one go:
 
  # alternative to separate pull and update
 
  # alternative to separate pull and update
  $ hg pull -u http://hg.services.openoffice.org/hg/DEV300
+
  $ hg pull -u http://hg.services.openoffice.org/DEV300
'''Note''': the URL is optional in all of the above commands - if omitted, it will just use the URL that was used to clone the repo
+
{{Template:Note| The URL is optional in all of the above commands - if omitted, it will just use the URL that was used to clone the repo.}}
  
== cloning from the local repo to create a working copy ==
+
== Cloning from the local repo to create a working copy ==
 
It is easier to keep a pristine copy of the sources as a base for new work, than to clean up an already modified repo, especially when you're not familiar with the tools yet :-) - so to create a working playground for your real work, clone from your local main-clone:
 
It is easier to keep a pristine copy of the sources as a base for new work, than to clean up an already modified repo, especially when you're not familiar with the tools yet :-) - so to create a working playground for your real work, clone from your local main-clone:
  $ hg clone -U DEV300 target-dir # where DEV300 is your main-checkout
+
  $ hg clone local_DEV300 working_DEV300 # where local_DEV300 is your main-checkout
  $ hg --cwd target-dir update DEV300_m46 # same as "cd target-dir && hg update -r DEV300_m46"
+
 
This is much faster than to use "hg clone -r DEV300_m46 DEV300 target-dir" and preserves future revisions in the target-clone.
+
If you need an earlier milestone examine the tags and update your working copy to the desired milestone (you might want to use clone -U in the command above then).
It is much faster because the clone without revision uses hardlinks, creates a full-featured copy of the main-checkout very fast (plain copy). The subsequent update command (hg --cwd target-dir update DEV300_m46) creates the files that match the DEV300_m46 tag.
+
$ cd working_DEV300
The clone with revision creates a DEV300_m46 straight ahead, but uses a different method called "pull protocol". It needs to analyze the full history and changesets to isolate those that are included in DEV300_m46 and throws away everything that was added after DEV300_m46 and is much slower (and needs more diskspace)
+
  $ hg tags                # in case you don't already know the name of the tag
 +
$ hg update -r DEV300_m60 # if you want milestone DEV300:m60
 +
 
 +
{{Warn| The above method is much faster than the apparently easier method of using clone with a revision.
 +
<strong>Don't use</strong>
 +
$ hg clone -r DEV300_m60 local_DEV300 working_DEV300
 +
as mercurial would have to examine the whole history to throw out everything that wasn't part of DEV300_m60, and it cannot make use of hardlinks, thus it will require a significant amount of diskspace as well.
 +
Depending on how fast your system is, the difference can be something like 30 minutes for the "clone -r" method and just 3 minutes for the "first clone, then update" one. You have been warned.}}
 +
 
 +
== Explore the working tree and history ==
 +
 
 +
The basic Mercurial commands are very similar to their equivalents in SVN and CVS.
 +
 
 +
$ hg status sw            # shows the status of all files in directory sw
 +
$ hg status                # shows the status of the whole tree!
 +
 
 +
{{Warn| Most Mercurial commands, when specified without file/directory argument, will operate on the whole tree. This will come as a surprise to SVN and CVS users. You'll notice it when your status command scans the whole tree instead of a single directory, or you accidentally commit files in a far away directory.}}
 +
 
 +
  $ hg log cws.pl          # shows all changesets affecting file cws.pl
 +
  $ hg log -v | more        # shows all changes in the repository in verbose format
 +
  $ hg log -v -r 262026    # shows verbose log of the changset with the numeric id 262026 (only locally valid!)
 +
 
 +
  $ hg diff cws.pl          # shows local (= not yet committed) modifications of cws.pl
 +
  $ hg diff --git          # shows all not yet committed modifications in tree, format is git-diff
 +
  $ hg diff -c 2e9d06d9922d # show all changes made by changeset 2e9d06d9922d
 +
  $ hg diff -r 4e62cb377115 -r d6f5cf344cec cws.pl # show diff of cws.pl between the two rev.
 +
 
 +
== Committing your changes ==
 +
 
 +
Commit your changes to your local repository is straighforward:
 +
 +
$ hg commit -m"foo42: #i4711# implement foobar gadget" # Commit all your locally modified files
 +
$ hg commit cws.pl        # Commit cws.pl, an editor will pop up for the commit log
 +
 
 +
== Merging ==
 +
 
 +
Occasionally you will need to merge changes. Say you are working on repository cloned a while ago and now you want to update to the latest DEV300 milestone:
 +
 
 +
$ hg pull http://hg.services.openoffice.org/DEV300
 +
 
 +
Mercurial will tell you that you need to merge the freshly pull changes with your local changes
 +
 
 +
$ hg merge
 +
 
 +
In many cases automerging the files will suffice, but occasionally you'll get conflicts. Fix the conflicts and mark the conflicted file as resolved.
 +
 
 +
$ hg resolve -m solenv/bin/cws.pl  # mark the conflict in cws.pl as resolved
 +
 
 +
Check if there are more unresolved conflicts with
 +
 
 +
$ hg resolve -l
 +
 
 +
When all conflicted files are resolved commit the result with
 +
 
 +
$ hg commit -m"foo42: merge with DEV300 m63"
 +
 
 +
== Exchanging your work with others ==
 +
 
 +
There are a number of ways on how to exchange your work with others. OpenOffice.org domain developers use a process called "child workspaces (CWS)" as the main way to organize collaboration. How to work with Mercurial based Child Workspaces is described [[Mercurial/Cws|here]].
 +
 
 +
If you are not (yet) a OOo domain developer you can export your changes as patch and attach it to an issue or send it to the developers mailing list
 +
 
 +
$ hg export tip > tip.patch
  
== show me the differences ==
+
When you made larger changes you could use the [[hg:PatchbombExtension|patchbomb extension]] for proper formatting before sending to the mailing list.
== committing stuff ==
+
=== pushing changes ===
+
== what about merging ==
+

Latest revision as of 08:20, 16 July 2018

Mercurial.png

Mercurial

Quick Navigation

About this template


This page aims to help cvs/svn users to get started with mercurial, without the need to dig in cyberspace for basic stuff. If you have a tip or general remark to share, feel free to edit the page - It's a wiki after all :-) Especially if you see something wrong here, just correct it without asking for permission on the ML

The very basics: Mercurial is a DVCS

Mercurial (hg) is a distributed version control system. This is a major difference compared to tools like CVS or subversion and that difference imposes a changed workflow compared to centralized version control systems.

Your checkout is a full repository

In a simplified view, every checkout is a full repository. You have history and version info for other branches in your local tree. So naturally such a checkout is rather big compared to a single-revision checkout done by cvs and svn. So you won't checkout a full repo every time (unless you have bandwidth to waste and too much time on your hands :-) Instead you will regularly update your local copy with the changes that were added to the repository and then "clone" (that's the term used for a "checkout") your local repository instead.

Your commits go to your local repository first

Another difference is that any change you commit will be done in your local copy only at first. You can accumulate many different commits locally and need to "push" changes to the master to finally have them in the main repo/available for everyone.

There are no version numbers anymore

Because multiple persons can do local commits, have different "local master copies" (somebody else could have pushed a change to the master before that alters the file you change yourself), it is impossible to refer to a specific version of a file by a version number. What is version 23 of a file? The one in your local copy, that doesn't exist on the master yet? Or version 23 of a file of another user that did commit the same file locally? So instead of version numbers, specific versions are referred to using "changeset" identifiers. Think of it as checksums.

Tip.png Mercurial offers the possibilities to use easier to type numeric revisions instead of changeset identifiers during work with a local repository. But remember: these numbers have no meaning outside this specific local repository. Don't use them when communicating with others.


Further reading

Remembering the three points above are enough to get you going. If you want to know more you'll find all things Mercurial at the Mercurial Wiki. An excellent tutorial can be found in "tour" chapters of the Mercurial book, which is also available online. Another excellent illustrated tutorial aimed at a broad audience (written by Joel Spolski, no less) can be found here.

The Mercurial command line help is quite well written and concise. Make good use of it. Example:

 $ hg merge --help

To get an overview over all commands and some concepts type:

 $ hg help

So how to use it then (aka: What commands do I have to type?)

You want to play around with the OpenOffice.org sources without bothering with all the things a OOo domain developer needs to keep in mind? You aren't interested in this CWS thing at all? Good, this section is for you.

Creating a local copy

Creating a local copy means to clone from the master - the URL for the the main OOo development code line is http://hg.services.openoffice.org/DEV300

$ hg clone http://hg.services.openoffice.org/DEV300 local_DEV300

If you know that you'll only use this as basis for different local clones and don't want it to create the actual source-files, then you can use

$ hg clone -U http://hg.services.openoffice.org/DEV300 local_DEV300

This will create a treeless version, i.e. you'll get an (apparently) empty OOo-tip-repo-only directory that holds the history/changeset data only, but not the actual files. Saves some diskspace and lessens the risk of modifying the master you intended to keep pristine.

Tip.png The OOo mercurial repository is quite huge, so doing cloning from the OOo server will take substantial time. A significant faster way is to download a nightly (GMT) created so called bundle of DEV300 which is available at http://hg.services.openoffice.org/bundle/DEV300.hg. This bundle contains the full history in one highly compressed file (currently about 800MB in size). Create a treeless local DEV300 copy with
$ mkdir local_DEV300
$ cd local_DEV300
$ hg init
$ hg unbundle <path_to_bundle>/DEV300.hg

and proceed with updating it with the latest changes as described below.


Pulling new changes from the master and updating the local copy

As mentioned above, doing a full clone from the OOo server every time would be a waste, so how to stay up-to-date then?

Updating means "pulling the new changes" from the master:

$ cd local_DEV300 # change to the directory of your main clone
$ hg pull http://hg.services.openoffice.org/DEV300
Documentation caution.png While this grabs all the changes that were done on the master since the last checkout, it will not automatically update the source-code files on your disk. It basically only gets the history and changesets.

Not updating the source tree is just what we want for a treeless copy. But if you want local source-files to reflect the newest changes, you need to do an update of your tree:

$ hg update

Since pulling the newest changes and updating to those changes is rather common, you can use the -u switch to the pull command to do both in one go:

# alternative to separate pull and update
$ hg pull -u http://hg.services.openoffice.org/DEV300
Documentation note.png The URL is optional in all of the above commands - if omitted, it will just use the URL that was used to clone the repo.

Cloning from the local repo to create a working copy

It is easier to keep a pristine copy of the sources as a base for new work, than to clean up an already modified repo, especially when you're not familiar with the tools yet :-) - so to create a working playground for your real work, clone from your local main-clone:

$ hg clone local_DEV300 working_DEV300 # where local_DEV300 is your main-checkout

If you need an earlier milestone examine the tags and update your working copy to the desired milestone (you might want to use clone -U in the command above then).

$ cd working_DEV300
$ hg tags                 # in case you don't already know the name of the tag
$ hg update -r DEV300_m60 # if you want milestone DEV300:m60
Documentation caution.png The above method is much faster than the apparently easier method of using clone with a revision.

Don't use

$ hg clone -r DEV300_m60 local_DEV300 working_DEV300

as mercurial would have to examine the whole history to throw out everything that wasn't part of DEV300_m60, and it cannot make use of hardlinks, thus it will require a significant amount of diskspace as well. Depending on how fast your system is, the difference can be something like 30 minutes for the "clone -r" method and just 3 minutes for the "first clone, then update" one. You have been warned.

Explore the working tree and history

The basic Mercurial commands are very similar to their equivalents in SVN and CVS.

$ hg status sw             # shows the status of all files in directory sw
$ hg status                # shows the status of the whole tree!
Documentation caution.png Most Mercurial commands, when specified without file/directory argument, will operate on the whole tree. This will come as a surprise to SVN and CVS users. You'll notice it when your status command scans the whole tree instead of a single directory, or you accidentally commit files in a far away directory.
 $ hg log cws.pl           # shows all changesets affecting file cws.pl
 $ hg log -v | more        # shows all changes in the repository in verbose format
 $ hg log -v -r 262026     # shows verbose log of the changset with the numeric id 262026 (only locally valid!)
 $ hg diff cws.pl          # shows local (= not yet committed) modifications of cws.pl
 $ hg diff --git           # shows all not yet committed modifications in tree, format is git-diff
 $ hg diff -c 2e9d06d9922d # show all changes made by changeset 2e9d06d9922d
 $ hg diff -r 4e62cb377115 -r d6f5cf344cec cws.pl # show diff of cws.pl between the two rev.

Committing your changes

Commit your changes to your local repository is straighforward:

$ hg commit -m"foo42: #i4711# implement foobar gadget" # Commit all your locally modified files
$ hg commit cws.pl         # Commit cws.pl, an editor will pop up for the commit log

Merging

Occasionally you will need to merge changes. Say you are working on repository cloned a while ago and now you want to update to the latest DEV300 milestone:

$ hg pull http://hg.services.openoffice.org/DEV300

Mercurial will tell you that you need to merge the freshly pull changes with your local changes

$ hg merge

In many cases automerging the files will suffice, but occasionally you'll get conflicts. Fix the conflicts and mark the conflicted file as resolved.

$ hg resolve -m solenv/bin/cws.pl   # mark the conflict in cws.pl as resolved

Check if there are more unresolved conflicts with

$ hg resolve -l

When all conflicted files are resolved commit the result with

$ hg commit -m"foo42: merge with DEV300 m63"

Exchanging your work with others

There are a number of ways on how to exchange your work with others. OpenOffice.org domain developers use a process called "child workspaces (CWS)" as the main way to organize collaboration. How to work with Mercurial based Child Workspaces is described here.

If you are not (yet) a OOo domain developer you can export your changes as patch and attach it to an issue or send it to the developers mailing list

$ hg export tip > tip.patch

When you made larger changes you could use the patchbomb extension for proper formatting before sending to the mailing list.

Personal tools