Mercurial: Difference between revisions
(41 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
{{lowercase title}} | {{lowercase title}} | ||
== Cheat Sheet == | |||
You are currently on version 38 but want to revert to version 33: | |||
<pre> | |||
hg log # to see logs of all versions | |||
hg update -r 33 # to revert to version 33 | |||
hg update -r 38 # to revert back to version 38 | |||
hg cat -r 22 old_file.txt # output version 22 of a specific file | |||
</pre> | |||
== Client == | == Client == | ||
Line 15: | Line 24: | ||
</pre> | </pre> | ||
=== Ignoring files === | |||
Manually create a file called <code>.hgignore</code> at the top level of your repository and add patterns that mercurial should ignore: | |||
<pre> | |||
# use glob syntax. | |||
syntax: glob | |||
log/* # ignore these directories in rails | |||
tmp/* | |||
*~ # ignore emacs backup files | |||
*.bak # ignore other backup files | |||
</pre> | |||
=== Commit, Revert, Log === | === Commit, Revert, Backout, Tag, Log === | ||
<pre> | <pre> | ||
hg commit # has you enter a text description in a text editor, then creates a snapshot of the directory | hg commit # has you enter a text description in a text editor, then creates a snapshot of the directory | ||
hg commit -m "my comment" # commit with this comment | hg commit -m "my comment" # commit with this comment | ||
hg revert --all # reverts everything back to the last commit | hg revert --all # reverts everything back to the last commit | ||
hg rollback # rolls back to the commit before last | |||
hg backout -r 2 # undo just changeset number 2 | |||
hg tag Version-1.0 # add a tag to the current changeset | |||
hg log # shows a list of all commits | hg log # shows a list of all commits | ||
hg log -v -r 2 # show all notes (and changed files) of changeset number 2 | |||
</pre> | </pre> | ||
Line 35: | Line 58: | ||
> | > | ||
> hg diff a.txt # show differences between last snapshot and current version | > hg diff a.txt # show differences between last snapshot and current version | ||
> hg add # add all new files to repository | |||
> hg remove favicon.ico # really remove this file | > hg remove favicon.ico # really remove this file | ||
> hg status | > hg status | ||
M a.txt | M a.txt | ||
Line 52: | Line 75: | ||
hg update # revert to the latest version of the repository | hg update # revert to the latest version of the repository | ||
</pre> | </pre> | ||
=== Working with a server === | |||
<pre> | |||
hg clone http://my_server:8000/ my_copy_of_the_code # name the directory as you like | |||
... commit some changes ... | |||
hg push # upload latest committed version to the server | |||
... commit more changes ... | |||
hg outgoing # show differences between my current version and the server's | |||
</pre> | |||
Push will fail if conflicting changes have been uploaded to the server in the meantime. If this happens, you need to merge the updates into your version: | |||
<pre> | |||
hg incoming # show differences between my current version and the server's | |||
hg pull # pull down more recent changes from the server | |||
hg merge # merge my version with the latest changes from the server | |||
hg commit -m "merge" # commit the merge | |||
hg push # upload | |||
</pre> | |||
Pull does not automatically update the files in your directory to the latest version, it just downloads the latest changes. | |||
Use parent to see what version number you're currently working with: | |||
<pre> | |||
hg parent # show the changeset that’s in the working directory | |||
hg heads # show any changesets that are at the head of the repository | |||
</pre> | |||
=== Dealing with conflicts === | |||
https://www.mercurial-scm.org/wiki/TutorialConflict | |||
When you pull down a file that conflicts with an existing file, the new file will be embedded with merge symbols (like a diff), and the old file will be saved as <code>my_file.txt.orig</code>. Use an editor to fix the existing file as you see fit, then run: | |||
<pre> | |||
hg resolve --mark my_file.txt | |||
</pre> | |||
You also probably want to get rid of <code>my_file.txt.orig</code>. Then commit and push the harmonized head back to the server. | |||
=== Workflow === | |||
# If you haven’t done so in a while, get the latest version that everyone else is working off of: | |||
#* hg pull | |||
#* hg up | |||
# Make some changes | |||
# Commit them (locally) | |||
# Repeat steps 2-3 until you’ve got some nice code that you’re willing to inflict on everyone else | |||
# When you’re ready to share: | |||
#* hg pull to get everyone else’s changes (if there are any) | |||
#* hg merge to merge them into yours | |||
#* test! to make sure the merge didn’t screw anything up | |||
#* hg commit (the merge) | |||
#* hg push | |||
=== Experimenting === | |||
<pre> | |||
hg clone my_code my_code_experiment # make a hard-linked duplicate directory | |||
hg push # push experimental changes back into original directory | |||
</pre> | |||
=== Stable and dev repositories === | |||
Clone <code>my_code-stable</code> to <code>my_code-dev</code>. Fix bugs in the stable repository, and add features in the dev repository. Regularly pull down bug fixes from stable to dev and merge them to stay current. When the new features are ready, push them back to stable. | |||
=== Troubleshooting: first commit === | |||
When you first create your repository, add everything to it, and then try to commit, you get this error: | |||
<pre> | |||
> hg commit -m "first commit" | |||
error: abort: no username supplied (see "hg help config") | |||
</pre> | |||
You must create a <code>.hgrc</code> file in your home directory and add something like this to it: | |||
<pre> | |||
[ui] | |||
username = Your Name <your@mail> | |||
</pre> | |||
=== Troubleshooting: push and pull === | |||
<pre> | |||
$ hg pull | |||
abort: repository default not found! | |||
$ hg push | |||
pushing to default-push | |||
abort: repository default-push not found! | |||
</pre> | |||
You have to specify the server/repository manually: | |||
<pre> | |||
hg pull ssh://hg@my_server/my_code | |||
hg push ssh://hg@my_server/my_code | |||
</pre> | |||
To avoid this in the future, edit <code>.hg/hgrc</code> like this: | |||
<pre> | |||
[paths] | |||
default = ssh://hg@my_server/my_code | |||
</pre> | |||
== Server == | |||
=== Quick and dirty web server === | |||
<pre> | |||
mkdir my_code | |||
cd my_code | |||
hg init | |||
hg serve # now accessible from http://my_server:8000/ | |||
</pre> | |||
=== SSH-based Server === | |||
http://dev.lshift.net/paul/mercurial-server/docbook.html | |||
==== Creating accounts ==== | |||
Assume that <code>dev@mybox</code> is the developer's account on his local machine, and <code>luser@myserver</code> is an account on the server where mercurial is running. | |||
* create [[ssh | public key]] for <code>dev@mybox</code>: | |||
<pre> | |||
dev@mybox:~$ ssh-keygen -t ecdsa -b 521 # add a passphrase | |||
# OR # | |||
dev@mybox:~$ ssh-keygen -t ed25519 -a 31 # add a passphrase | |||
</pre> | |||
* send a copy of the public key to <code>luser@myserver</code> | |||
* as <code>root@myserver</code>, copy the public key to a file named <code>/etc/mercurial-server/keys/users/dev/mybox</code> and run this command: | |||
<pre> | |||
root@myserver:# sudo -u hg /usr/share/mercurial-server/refresh-auth | |||
</pre> | |||
NOTE: this creates a regular user who can only check code in and out. To set up a <code>root</code> user with the authority to create and delete repositories, change <code>users</code> to <code>root</code> in the public key path above. | |||
==== Uploading a repository to the server ==== | |||
To upload the <code>myproj</code> folder as a repository | |||
<pre> | |||
cd myproj | |||
hg init; hg add; hg commit | |||
hg clone . ssh://hg@myserver/my/project | |||
hg pull ssh://hg@myserver/my/project | |||
</pre> | |||
==== Backing up <code>mercurial-server</code> ==== | |||
* Repositories are stored in <code>/var/lib/mercurial-server/repos</code>. | |||
* Keys are stored in <code>/etc/mercurial-server/keys</code>. |
Latest revision as of 16:57, 29 January 2016
Cheat Sheet
You are currently on version 38 but want to revert to version 33:
hg log # to see logs of all versions hg update -r 33 # to revert to version 33 hg update -r 38 # to revert back to version 38 hg cat -r 22 old_file.txt # output version 22 of a specific file
Client
The command for Mercurial is hg
.
Create a repository
Suppose you want to set up version control for the my_code
directory.
cd my_code hg init # creates .hg directory hg add # adds everything from the current directory hg commit # has you enter a text description, then creates a first snapshot of the directory
Ignoring files
Manually create a file called .hgignore
at the top level of your repository and add patterns that mercurial should ignore:
# use glob syntax. syntax: glob log/* # ignore these directories in rails tmp/* *~ # ignore emacs backup files *.bak # ignore other backup files
Commit, Revert, Backout, Tag, Log
hg commit # has you enter a text description in a text editor, then creates a snapshot of the directory hg commit -m "my comment" # commit with this comment hg revert --all # reverts everything back to the last commit hg rollback # rolls back to the commit before last hg backout -r 2 # undo just changeset number 2 hg tag Version-1.0 # add a tag to the current changeset hg log # shows a list of all commits hg log -v -r 2 # show all notes (and changed files) of changeset number 2
Status, Diff, Remove, Add
> cp a.txt b.txt > emacs a.txt > rm favicon.ico > hg status M a.txt # Modified ? b.txt # "?" means mercurial doesn't know anything about this file yet ! favicon.ico # "!" means missing > > hg diff a.txt # show differences between last snapshot and current version > hg add # add all new files to repository > hg remove favicon.ico # really remove this file > hg status M a.txt A b.txt # Added R favicon.ico # Removed
You need to clear up all the ?s and !s in order to commit.
Cat, Diff, Update
hg cat a.txt # print current version of a.txt hg cat -r 0 a.txt # print version 0 of a.txt hg diff -r 0:1 a.txt # show differences between versions 0 and 1 of a.txt hg update -r 0 # revert to version 0 of the repository hg update # revert to the latest version of the repository
Working with a server
hg clone http://my_server:8000/ my_copy_of_the_code # name the directory as you like ... commit some changes ... hg push # upload latest committed version to the server ... commit more changes ... hg outgoing # show differences between my current version and the server's
Push will fail if conflicting changes have been uploaded to the server in the meantime. If this happens, you need to merge the updates into your version:
hg incoming # show differences between my current version and the server's hg pull # pull down more recent changes from the server hg merge # merge my version with the latest changes from the server hg commit -m "merge" # commit the merge hg push # upload
Pull does not automatically update the files in your directory to the latest version, it just downloads the latest changes. Use parent to see what version number you're currently working with:
hg parent # show the changeset that’s in the working directory hg heads # show any changesets that are at the head of the repository
Dealing with conflicts
https://www.mercurial-scm.org/wiki/TutorialConflict
When you pull down a file that conflicts with an existing file, the new file will be embedded with merge symbols (like a diff), and the old file will be saved as my_file.txt.orig
. Use an editor to fix the existing file as you see fit, then run:
hg resolve --mark my_file.txt
You also probably want to get rid of my_file.txt.orig
. Then commit and push the harmonized head back to the server.
Workflow
- If you haven’t done so in a while, get the latest version that everyone else is working off of:
- hg pull
- hg up
- Make some changes
- Commit them (locally)
- Repeat steps 2-3 until you’ve got some nice code that you’re willing to inflict on everyone else
- When you’re ready to share:
- hg pull to get everyone else’s changes (if there are any)
- hg merge to merge them into yours
- test! to make sure the merge didn’t screw anything up
- hg commit (the merge)
- hg push
Experimenting
hg clone my_code my_code_experiment # make a hard-linked duplicate directory hg push # push experimental changes back into original directory
Stable and dev repositories
Clone my_code-stable
to my_code-dev
. Fix bugs in the stable repository, and add features in the dev repository. Regularly pull down bug fixes from stable to dev and merge them to stay current. When the new features are ready, push them back to stable.
Troubleshooting: first commit
When you first create your repository, add everything to it, and then try to commit, you get this error:
> hg commit -m "first commit" error: abort: no username supplied (see "hg help config")
You must create a .hgrc
file in your home directory and add something like this to it:
[ui] username = Your Name <your@mail>
Troubleshooting: push and pull
$ hg pull abort: repository default not found! $ hg push pushing to default-push abort: repository default-push not found!
You have to specify the server/repository manually:
hg pull ssh://hg@my_server/my_code hg push ssh://hg@my_server/my_code
To avoid this in the future, edit .hg/hgrc
like this:
[paths] default = ssh://hg@my_server/my_code
Server
Quick and dirty web server
mkdir my_code cd my_code hg init hg serve # now accessible from http://my_server:8000/
SSH-based Server
http://dev.lshift.net/paul/mercurial-server/docbook.html
Creating accounts
Assume that dev@mybox
is the developer's account on his local machine, and luser@myserver
is an account on the server where mercurial is running.
- create public key for
dev@mybox
:
dev@mybox:~$ ssh-keygen -t ecdsa -b 521 # add a passphrase # OR # dev@mybox:~$ ssh-keygen -t ed25519 -a 31 # add a passphrase
- send a copy of the public key to
luser@myserver
- as
root@myserver
, copy the public key to a file named/etc/mercurial-server/keys/users/dev/mybox
and run this command:
root@myserver:# sudo -u hg /usr/share/mercurial-server/refresh-auth
NOTE: this creates a regular user who can only check code in and out. To set up a root
user with the authority to create and delete repositories, change users
to root
in the public key path above.
Uploading a repository to the server
To upload the myproj
folder as a repository
cd myproj hg init; hg add; hg commit hg clone . ssh://hg@myserver/my/project hg pull ssh://hg@myserver/my/project
Backing up mercurial-server
- Repositories are stored in
/var/lib/mercurial-server/repos
. - Keys are stored in
/etc/mercurial-server/keys
.