Mercurial HG

General
[paths] default = path\to\default\push or [paths] default = https://user@bitbucket.org/user/project
 * http://programmers.stackexchange.com/questions/35074/im-a-subversion-geek-why-i-should-consider-or-not-consider-mercurial-or-git-or
 * http://mercurial.selenic.com/wiki/FAQ
 * http://hgbook.red-bean.com/read/a-tour-of-mercurial-the-basics.html
 * http://wiki.secondlife.com/wiki/Creating_a_version_control_repository
 * http://stackoverflow.com/questions/4321065/how-do-i-make-tortoise-hg-remember-a-repository

Questions
hg revert --no-backup a.html
 * I checkout the latest code. I make some local changes. I want to get rid of my local changes for "a.html"

Bit Bucket
hg push ssh://hg@bitbucket.org/Login/projectX Upload that new key (/.ssh/newacct.pub) to your BitBucket account, then, edit the .hg/hgrc file of the project to tell it to use the new key. While you're at it, you might as well tell it to use compression as above by adding the -C switch as well. [ui] ssh = ssh -i ~/.ssh/newacct -C
 * http://confluence.atlassian.com/display/BITBUCKET/Using+SSH+to+Access+your+Bitbucket+Repository

Reference

 * http://www.selenic.com/mercurial/hg.1.html
 * http://mercurial.selenic.com/wiki/Subrepository?action=show&redirect=subrepos

Basic Notions

 * a remote repository is a remote store of changesets (commits)
 * a local repository is a local store of changesets (commits)
 * you don't edit a repo directory, you use hg commands to do that
 * your actual files
 * you edit these directly
 * files in the working directory get checked into your local repository and then can be pushed out to a remote repository
 * another term for a commit
 * generally has a number and hex value associated with it
 * a changeset is a reference to a commit
 * a specific commit
 * all commands can be reduced to the shortest name that uniquely identifies them
 * com = commit
 * up = update
 * etc

Working Locally

 * a sort of man page about the CMD
 * creates an empty repository
 * describes which files to ignore adding, committing and/or retrieving the status of
 * adds files to the repository
 * once a file is in the repository, changes to that file will be implicitly committed
 * note that hg differs from git in this respect - git requires you explicitly add committable files on each commit whereas, if it exists in the repository and it has changed, hg will default to committing it
 * removes a file from future commits (does not remove the file from previous commits)
 * lists any files that have changed or are candidates for committal
 * commits all files that have been, at some time, added to the repository (ie: they are being tracked) and have changed since their last commit
 * commits just files a.txt and b.txt (if they are being tracked and have changed since their last commit)
 * lists all recent commits
 * includes a changeset number as well as unique hex identifier
 * grabs log information for the parent (current changeset)
 * limit display to the the last 4 commits
 * lists any changes to controlled files since their last commit
 * displays any changes to file.txt since the last commit
 * displays changes to file.txt between the 3rd and 4th changset
 * displays the contents of file.txt
 * displays the contents of file.txt from changeset 2
 * essentially checks out changeset 0
 * can go foward and backwards
 * shorthand for update
 * no args implies "take me the tip" or the last changeset
 * tells you which changeset you are working off of

Working with Others

 * start this from within any valid hg repository
 * note, this isn't the most safe way to work as it is not encrypted
 * the default port is 8000 so anyone may access this endpoint ala http://hostname:8000/
 * clone creates and copies a new repository into your local working space /project directory
 * clone can work from several different types of locations
 * lists where you will push to
 * this will, by default, try to upload your local commits to the remote repository you initially cloned
 * remember, you've already, locally, committed changes to your local repository
 * if you are using an http connection, you must push_ssl=False (see config below)
 * will push to explicit location (may not be the repository initially cloned)
 * will push to /var/repo/project
 * pulls down and copies new commits from the remote repository to your local repository
 * updates your local repository, not your working copies
 * safely tells you what will be pushed were you to
 * diffs your local repo with the remote repo
 * safely tells you what will be pulled into your local repository were you to
 * takes contents of current changeset and merges them with your local copy
 * if there are not conflicts, you may check the file in (commit the file)
 * if there are conflicts, open the file - it should have little marks everywhere it conflicted.
 * manually remove the little marks and manually resolve what to do
 * most likely, the file from the current changeset and your local file had changes to the same lines and the  didn't know which one to keep
 * lists all endpoint or tip repositories - repos that were the last commit in their branch

Manipulation
hg revert file.txt
 * reverts files to current changeset
 * ie: this removes any changes you may have made locally
 * your local, working copy of the file gets altered - back to a fresh copy of the current changeset
 * hg actually renames the working file to
 * (what happens if that named file already exists?)
 * will remove the LAST commit (will not go back farther than 1 commit)
 * takes changes from r3, reverts and merges the reversion? into your local working directory
 * will need to be committed (does not affect changeset 3 - instead, commits as a child of the current parent

Tagging
Changeset numbers are local HEX identifiers are unique (cross your fingers)
 * because you may commit a file to parent 4 and someone else may commit a file to changeset 4
 * you both, locally, think you have changeset 5
 * then you merge and your changeset 5 includes the other persons while the other person's changeset 5 includes your
 * changeset 4 - for both of you - is different
 * but the are oh so hard to remember
 * note: adding a tag results in a changeset (needs to be committed)
 * you can update to a changeset, hex id or tag (or branch)
 * lists tags in the current branch
 * is a floating tag - sort of like a branch
 * removes the tag association (leaves the commit)
 * if v1.1 does not exist, applies v1.1 to changeset 2
 * if v1.1 already exists, fails
 * moves the tag from wherever it exists to changeset 2
 * keeps a tag local - is not committed - no one else has to see

Branching
Creating a branch tells Mercurial which branch name to use next time you commit


 * displays the current branch_name
 * lists all branches in the repository
 * creates a new branch branch_name
 * checks out the changeset from branch_name
 * careful - OVERWRITES your local working directory
 * displays where the tip is - tip is an implicit branch
 * will display each branch's head

Merging
$ hg commit -m 'Attempt to commit a failed merge' abort: unresolved merge conflicts (see hg resolve) $ hg resolve -l U myfile.txt "We can manually mark a file as resolved using the --mark option"
 * http://hgbook.red-bean.com/read/a-tour-of-mercurial-merging-work.html
 * http://hgbook.red-bean.com/read/mercurial-in-daily-use.html

Advanced Notions
Now that you know the above, the following might make sense to you:


 * imagine that you've made 100s of commits - but you want to do something on a file from the 34th commit
 * will copy files from the 34th commit into your local working directory
 * and any changes you make to those files, will be with respect to the 34th commit
 * you are therefore working against the 34th changeset
 * as you will see below, you can  which will copy files from the second changeset into your working directory
 * (what happens to local changes that aren't part of said changeset?)
 * if you make change to your local copy, than you might  which would essentially replace your current, working copy with the file from -r 2
 * that is why I say current changeset - the file that will show up will be whatever changeset you are working off of - likely gotten to by a
 * just because you've pulled down the latest files doesn't mean you are working with them
 * remember the entities, you have a copy of the repository and a working directory
 * most (not all) of the commands listed herein work on the repository
 * retrieves and copies the remote repository to your local repository - it does not necessarily touch your working directory
 * you much  to update your local working directory to the latest changeset
 * AGAIN: just because you've pulled changes down from a remote repository doesn't mean you are working off that tip of that repository
 * can put you anywhere

Quick

 * match  with
 * match  with

Use Cases

 * TODO :)

Project
[ui] username = Your Name  ssh = ssh -i ~/.ssh/id_rsa.bitbucket.username -C

[paths] default = /c/var/dev/hg/project-name bitbucket = ssh://hg@bitbucket.org/UserName/project-name

Global
[ui] username = Your Name  ssh = ssh -C
 * includes a few helpful config hints
 * just one of several places that configuration can occur (project | user | global)
 * 1) ignore = ~/.hgignore

[extensions] hgext.graphlog =

[diff] git = true ignoreblanklines = true

[extensions] color = hgext.extdiff = hgext.fetch = rebase =

[color] status.modified = none status.added = yellow bold status.removed = red bold black_background status.deleted = cyan bold underline status.unknown = magenta bold underline status.ignored = black bold diff.diffline = black_background diff.file_a = black_background diff.file_b = yellow black_background diff.hunk = black_background diff.inserted = yellow
 * 1) http://mercurial.selenic.com/wiki/ColorExtension

[extdiff] cmd.opendiff = opendiff-sync

[web] push_ssl=False allow_push=* syntax:glob .* build/* target/*
 * 1) required on server hosting the repository
 * tells hg to ignore files that match the defined syntax

Tools

 * kdiff3

Compared to Git

 * Git requires you to add files for each commit.
 * A file will not be committed unless it is explicitly added to the commit group.
 * Git allows you to selectively push branches intto the remote repository

Tutorials

 * http://hginit.com/
 * interesting that Joel never touches branching. I think Joel is familiar with SVN and creating directories is the way you branch in SVN - but there is a much better, native way to branch from within mercurial (or this is probably just the Git in me speaking out).

Documentation

 * http://hgbook.red-bean.com/
 * http://mercurial.selenic.com/wiki/QuickStart

Vendors

 * http://www.bitbucket.org/