Mercurial intro

98
Mercurial For devs...

Transcript of Mercurial intro

Page 1: Mercurial intro

MercurialFor devs...

Page 2: Mercurial intro

What will we talk about?

● The .hgrc● A Stack of Patches● Basic Commands● Branching, pushing, pulling● Howtos

Page 3: Mercurial intro

Assumptions

● You have some programming knowledge● You know the basics of some version control

system○ git○ svn○ cvs○ mercurial○ ...

Page 4: Mercurial intro

.hgrc!

Who has no.hgrc?

Page 5: Mercurial intro

.hgrc!

Page 6: Mercurial intro

Why .hgrc?

● Username● Extensions● Aliases● Other settings● Example:

○ http://confluence.incubaid.com/display/ENG/Incubaid+Starter+Kit

Page 7: Mercurial intro

What is .hgrc

● Configuration for your Mercurial● INI file format

○ # Comments○ [sections]○ key = value

Page 8: Mercurial intro

Minimal .hgrc: Username

[ui]username = John Doe <[email protected]>

Page 9: Mercurial intro

.hgrc: Extensions

● Mercurial without extensions is barely useable

● Small core, but easy to extend● Extensions add some sugar● Python scripts

○ Write your own!

Page 10: Mercurial intro

.hgrc: Extensions

[extensions]pager = # pipe through less automaticallycolor = # Color outputgraphlog = # ASCII art graphical logsfetch = # Pull-and-merge, use with caremq = # Strip, flexible commit queueshighlight = # syntax highlighting in hgweb

Page 11: Mercurial intro

.hgrc: aliases

[alias]blame = annotate -uout-diff = out -pvMin-diff = in -pvM# Show the diff of a given changeset IDshow = log -p -v -r

Page 12: Mercurial intro

How to think about Mercurial

It's a stack of patcheswith downward links between them

Page 13: Mercurial intro

A Stack of Patches@ 4:ch4ch4: Change number 3Parent: ch3ch3tag: tip

3:ch3ch3: Merge in Alice's workParent: ch2ch2Parent: al1al1

2:ch2ch2: Change number 2Parent: ch1ch1

1:al1al1: Alice's changesparent: ch1ch1

0:ch1ch1: Change number 1Parent: ch0ch0

Patch S

ave Time

Working directory commit

Root commitIdentifies a repository

Stack indexClone-dependent!

Node IDUnique!

Top of the stack

is-child-of

Page 14: Mercurial intro

What is a commit?

● Diff● Metadata

○ timestamp○ user○ branch?○ parent(s): 1 or 2○ ...

● If you change any of these fields:○ commit ID will change○ you create a different commit!

SHA1 Unique Commit ID

Page 15: Mercurial intro

Cause of all those merges

1:ch2ch2: Change number 2Parent: ch1ch1

0:ch1ch1: Change number 1

Local repository status:

Page 16: Mercurial intro

Cause of all those merges

Pull from Alice's repository:

1:ch2ch2: Change number 2Parent: ch1ch1

2:al1al1: Alice's changesparent: ch1ch1

0:ch1ch1: Change number 1

No re-ordering can happen without altering the tags and therefore the unique hashes of the commits!

Page 17: Mercurial intro

Cause of all those merges2 'heads'!

1:ch2ch2: Change number 2Parent: ch1ch1

2:al1al1: Alice's changesparent: ch1ch1

0:ch1ch1: Change number 1

We want one 'head'!

Page 18: Mercurial intro

Cause of all those merges

1:ch2ch2: Change number 2Parent: ch1ch1

2:al1al1: Alice's changesparent: ch1ch1

0:ch1ch1: Change number 1

-> We need to merge. :-(

3:ch3ch3: Merge in Alice's workParent: ch2ch2Parent: al1al1

Page 19: Mercurial intro

Quiz 1

● What is .hgrc good for?

Page 20: Mercurial intro

Quiz 1

● What is .hgrc good for?○ Username○ Extensions○ Aliases○ Much, much more

Page 21: Mercurial intro

Quiz 1

● What is .hgrc good for?○ Username○ Extensions○ Aliases○ Much, much more

● How should you imagine a Mercurial repository?

Page 22: Mercurial intro

Quiz 1

● What is .hgrc good for?○ Username○ Extensions○ Aliases○ Much, much more

● How should you imagine a Mercurial repository?○ As a stack of patches.

Page 23: Mercurial intro

Basic Commands

● help● clone● init● add/remove/addremove● cp/rename/mv● status● diff● commit

Page 24: Mercurial intro

Help!

● hg help: General help○ List of commands○ List of extensions○ Additional help topics (advanced stuff)

● hg help <command>○ hg <command> --help

Page 25: Mercurial intro

Cloning a repository

● hg clone <remote> <foldername>● Creates a .hg folder in <foldername>● Downloads all the patches/commits from

<remote>● Checks out the files of the last commit on the

default branch on your disk, in <foldername>

Page 26: Mercurial intro

Init: Creating a new repository

● hg init <foldername>● Creates a .hg folder in <foldername>

○ No commits yet○ No changes yet

Page 27: Mercurial intro

Add/Remove/Addremove

● hg add <path>○ 'enables' <path> for committing

● hg rm <path>○ 'disables' <path> for committing

● hg addremove <path>○ "Add all new files and remove all missing files from

the repository."○ Use with care (.hgignore!)

● Paths either absolute or relative to $PWD!○ <> 'hg status' output

Page 28: Mercurial intro

cp/rename/mv/move

● Avoid having to add/rm● hg cp● hg rename

○ Aliases: mv, move

Page 29: Mercurial intro

Status

● Show which files are:○ Added (A)○ Removed (R)○ Modified (M)○ Missing (!) - use hg rm○ Not tracked (?) - use hg add

● Paths relative to repository root (annoying)○ Try hg status .○ Mercurial 1.7 or higher:

■ Alias: stat = !hg status $($HG root) $HG_ARGS

Page 30: Mercurial intro

.hgignore

● Tell Mercurial to ignore files in your repository○ mycode.pyc○ README.txt~○ mycode.py.orig○ mycode.py.rej○ ...

● 2 ways of matching○ Regex (default)

■ .pyc$ or re:.pyc$○ glob (~bash)

■ glob:**.pyc● Located in `hg root`

Page 31: Mercurial intro

.hgignore: Example

syntax: globdoc/*.auxdoc/_build/htmldist/*arakoon.native**.pycsyntax:regexp^_build~$

Page 32: Mercurial intro

locate: test a pattern

● "locate files matching specific patterns"● hg locate "glob:**.py"

○ The quotes are needed to avoid your shell expanding the '*'

● Only prints files under Mercurial control○ Like find, but limited to 'tracked' files.

Page 33: Mercurial intro

Diff: what did I change?

● hg diff● Changed files:

○ Show diff with previously committed version● Added files:

○ Show content● Removed files:

○ Show content● Specify <path>

○ Diff only that file/those files○ Can use re: and glob:

● USE COLOR !!!

Page 34: Mercurial intro

Color extension

● .hgrc● [extensions]

color =● Colors can be customized● Adds color to almost all commands that have output

○ status○ diff○ log○ ...

Page 35: Mercurial intro

Commit: Create a new commit

● hg commit○ Username

■ from .hgrc (preferably!)■ -u "Joske Vermeulen <[email protected]>"

○ Commit message■ in editor (default)■ -m "My commit"

○ Files■ Default: everything shown as A/R/M in status■ Use -I and -X for more control (re, glob)

● Creates a new commit● Use nice commit messages

Page 36: Mercurial intro

Log: check the history

● hg log● Order: stack of patches!● Spammy? There's an extension for that!

[extensions]pager =

[pager] pager = less -R attend = annotate, cat, df, diff, >>glog, help, in-diff, incoming, >>log, out-diff, outgoing, qdiff,>>show, tip, grep

Page 37: Mercurial intro

Graph log

● Useful when branching, merging, ...● ASCII art graphs!● Need to enable the extension

○ [extensions]graphlog =

● hg glog● @ marks the working directory commit

Page 38: Mercurial intro

Example glog output:| o changeset: 3246:1f56e1265e40

| |\ parent: 3245:96b848f10790

| | | parent: 3243:72b775711468

| | | user: Mohammed Azmy <[email protected]>

| | | date: Thu Sep 13 10:36:17 2012 +0200

| | | summary: Automatic merge

| | |

| | @ changeset: 3245:96b848f10790

| | | parent: 3236:c544f3aa38cc

| | | user: Mohammed Azmy <[email protected]>

| | | date: Thu Sep 13 10:35:49 2012 +0200

| | | summary: return empty string if key is none

| | |

o | | changeset: 3244:ed5095ad82a8

|/ / user: Jens Geiregat <[email protected]>

Page 39: Mercurial intro

Quiz 2: basic hg commands

● Start tracking an untracked file?

Page 40: Mercurial intro

Quiz 2: basic hg commands

● Start tracking an untracked file?○ hg add <path>

Page 41: Mercurial intro

Quiz 2: basic hg commands

● Start tracking an untracked file?○ hg add <path>

● Print the root of the repository you're in?

Page 42: Mercurial intro

Quiz 2: basic hg commands

● Start tracking an untracked file?○ hg add <path>

● Print the root of the repository you're in?○ hg root

Page 43: Mercurial intro

Quiz 2: basic hg commands

● Start tracking an untracked file?○ hg add <path>

● Print the root of the repository you're in?○ hg root

● Commit only one file when multiple are changed?

Page 44: Mercurial intro

Quiz 2: basic hg commands

● Start tracking an untracked file?○ hg add <path>

● Print the root of the repository you're in?○ hg root

● Commit only one file when multiple are changed?○ hg commit -I <path>

Page 45: Mercurial intro

Quiz 2: basic hg commands

● Start tracking an untracked file?○ hg add <path>

● Print the root of the repository you're in?○ hg root

● Commit only one file when multiple are changed?○ hg commit -I <path>

● Command to show an ASCII art log graph?

Page 46: Mercurial intro

Quiz 2: basic hg commands

● Start tracking an untracked file?○ hg add <path>

● Print the root of the repository you're in?○ hg root

● Commit only one file when multiple are changed?○ hg commit -I <path>

● Command to show an ASCII art log graph?○ hg glog

Page 47: Mercurial intro

Quiz 2: basic hg commands

● Start tracking an untracked file?○ hg add <path>

● Print the root of the repository you're in?○ hg root

● Commit only one file when multiple are changed?○ hg commit -I <path>

● Command to show an ASCII art log graph?○ hg glog

● Mark for the working directory commit?

Page 48: Mercurial intro

Quiz 2: basic hg commands

● Start tracking an untracked file?○ hg add <path>

● Print the root of the repository you're in?○ hg root

● Commit only one file when multiple are changed?○ hg commit -I <path>

● Command to show an ASCII art log graph?○ hg glog

● Mark for the working directory commit?○ @

Page 49: Mercurial intro

Branching, pushing, pulling

● branch● update● identify● push● pull● incoming, outgoing

Page 50: Mercurial intro

Branching...

● Not very flexible in Mercurial○ Unique branch names○ No branch renames○ Branch name must be chosen before first commit on

that branch○ ...

● Just adds a "branch=name" to the metadata of a commit.

● Default branch has no "branch=default"● Interesting comparison: http://stevelosh.com/blog/2009/08/a-guide-to-branching-in-mercurial/

Page 51: Mercurial intro

4:ch3ch3: Change number 3Parent: ch2ch2

Patch S

ave Time

Back to the stack of patches...

5:ch4ch4: Change number 4Parent: ch3ch3

6:cb1cb1: Branching!Parent: ch3ch3branch: mybranch

7:ch5ch5: Change number 5Parent: ch4ch4

8:cb2cb2: Also on the branchParent: cb1cb1branch: mybranchtag: tip

hg update 4 && hg branch mybranch

hg update default

hg update mybranch

Page 52: Mercurial intro

Branch-related commands

● hg branch○ What branch am I on?

● hg branches○ What branches are there?

● hg branch <name>○ Create a branch with <name>

Page 53: Mercurial intro

Update

● Changes the working directory commit (@)○ hg update <branchname>

■ Go to the last commit on branch <branchname>○ hg update <rev>

■ Go to revision <rev>● Discard local changes (danger, no backup!)

○ hg update --clean ...○ Forces the update

Page 54: Mercurial intro

Identify

● Prints the working directory commit (@)● hg identify

c640c961a243 tip

Page 55: Mercurial intro

Push

● Send changesets not yet at <remote> to <remote>

● hg push○ Push to 'default'

● hg push ssh://[email protected]/incubaid/pylabs-core-5.1

○ Explicit target● hg push default

○ Push to 'default' path explicitly.○ Define 'default' (and others) in .hg/hgrc

● Protocol: SSH or HTTP (or local)

Page 56: Mercurial intro

Push: 'shortcuts'

.hg/hgrc:[paths]default = ssh://[email protected]/incubaid/pylabs-core-5.1private = ssh://[email protected]/geiregaj/pylabs-core-5.1-jens

Page 57: Mercurial intro

hg paths

● Prints the named paths for the repository:○ $ hg paths

default = ssh://[email protected]/incubaid/pylabs-core-5.1private = ssh://[email protected]/geiregaj/pylabs-core-5.1-jens

Page 58: Mercurial intro

Push -b

● hg push -b default ssh://...● Push one branch

○ Keeps the <remote> clean○ Push your branch to a private repository, after merge

push to the common repository

Page 59: Mercurial intro

hg duw

● [alias]duw = push -r .

● Pushes your working directory commit (@)

Page 60: Mercurial intro

Pull

● hg pull● hg pull default● hg pull ssh://[email protected]/incubaid/pylabs-core-5.1

● Downloads the changesets that are on <remote> but not on <local>

● Shortcut: hg pull -u○ == hg pull && hg update

● Tip will be the newest of the pulled commits

Page 61: Mercurial intro

Incoming, outgoing

● Show commits that would be pulled or pushed

● Useful as a quick check without the danger of pulling things you don't want yet.

Page 62: Mercurial intro

Quiz 3

● Why do you need to commit to create a branch?

Page 63: Mercurial intro

Quiz 3

● Why do you need to commit to create a branch?○ Because branches only really exist in the commits,

as a tag. No commit means no tag. No tag means no branch.

Page 64: Mercurial intro

Quiz 3

● Why do you need to commit to create a branch?○ Because branches only really exist in the commits,

as metadata. No commit means no metadata. No metadata means no branch.

● How to print all branch names?

Page 65: Mercurial intro

Quiz 3

● Why do you need to commit to create a branch?○ Because branches only really exist in the commits,

as metadata. No commit means no metadata. No metadata means no branch.

● How to print all branch names?○ hg branches

Page 66: Mercurial intro

Quiz 3

● Why do you need to commit to create a branch?○ Because branches only really exist in the commits,

as metadata. No commit means no metadata. No metadata means no branch.

● How to print all branch names?○ hg branches

● How to find out what your working directory commit is?

Page 67: Mercurial intro

Quiz 3

● Why do you need to commit to create a branch?○ Because branches only really exist in the commits,

as metadata. No commit means no metadata. No metadata means no branch.

● How to print all branch names?○ hg branches

● How to find out what your working directory commit is?○ hg identify○ hg glog and search for the '@'

Page 68: Mercurial intro

Howto's

● Merge● Discard changes● Collaborate● Feature branches● Commit message template● (Bitbucket) SSH keys● Remove a commit● Undo a commit

Page 69: Mercurial intro

How to Merge

● This is where things typically go wrong.○ Merge direction...○ > 2 heads○ Conflicts (oh noes!)

Page 70: Mercurial intro

Merge Direction: Goal

● A small diff!○ Keeps your tools from choking on HUGE diffs

● From hg merge --help○ The current working directory is updated with all

changes made in the requested revision since the last common predecessor revision.

Page 71: Mercurial intro

Merge Direction

1. Create your local commit2. Pull in the latest changes from <remote>3. Check the situation with

a. hg glogb. hg heads

4. Decide on the merge direction5. hg update <base> (if needed)6. hg merge7. Check the merge (tests?)8. Commit

Page 72: Mercurial intro

Merge Direction

4:ch3ch3: Change number 3Parent: ch2ch2

5:ch4ch4: Change number 4Parent: ch3ch3

@ 6:abcabc: My changeParent: ch2ch2

7:ch5ch5: Change number 5Parent: ch4ch4

8:ch6ch6: Change number 6Parent: ch5ch5

9:ch7ch7: Change number 7Parent: ch6ch6

Pulled

Page 73: Mercurial intro

Merge Direction

4:ch3ch3: Change number 3Parent: ch2ch2

5:ch4ch4: Change number 4Parent: ch3ch3

@ 6:abcabc: My changeParent: ch2ch2

7:ch5ch5: Change number 5Parent: ch4ch4

8:ch6ch6: Change number 6Parent: ch5ch5

@ 9:ch7ch7: Change number 7Parent: ch6ch6

Pulled

hg update ch7ch7

1000 changes

10 changes

Page 74: Mercurial intro

Merge Direction

4:ch3ch3: Change number 3Parent: ch2ch2

5:ch4ch4: Change number 4Parent: ch3ch3

6:abcabc: My changeParent: ch2ch2

7:ch5ch5: Change number 5Parent: ch4ch4

8:ch6ch6: Change number 6Parent: ch5ch5

9:ch7ch7: Change number 7Parent: ch6ch6

Pulled

@ 9:ch8ch8c: MergeParent: ch7ch7Parent: abcabc

hg mergehg commit \ -m "Merge"

Page 75: Mercurial intro

Merge: > 2 heads

● Mercurial can only merge 2 heads / commit● To merge > 2 heads, merge multiple times

○ Choose head with most changes (biggest diff)○ hg update <bighead>○ hg merge <smallerhead>○ hg commit○ -> repeat

Page 76: Mercurial intro

Merge: conflicts

● kdiff3○ 3-way merge tool○ Powerful○ Simple to use○ Install it and configure it in your .hgrc

■ or use my example config...

Page 77: Mercurial intro

Merge: conflicts

● Kdiff3!

Result: Edit by clicking A/B/C or by manually editing the text

Common ancestor LocalRemote

Choose line

Next unmerged conflict

Page 78: Mercurial intro

Merge: conflicts

● Kdiff3 workflow:○ Fix all unmerged conflicts

■ use triple arrows to find them■ A/B/C or manual edit

○ When all unmerged conflicts are resolved■ Click 'save'■ Exit kdiff3

Page 79: Mercurial intro

Howto: discard changes

● You changed or removed a file● But want to restore it to how it looked in the

last commit○ hg revert <path>

● Shortcut: revert everything:○ hg revert --all

● The content before the revert is saved with suffix .orig

● Revert to a specific revision○ hg revert -r abcabc <path>

Page 80: Mercurial intro

Howto: Collaborate

● Avoid working on the same files at the same time○ Same for moving files that other people are working

on● Push your code often

○ What if you lose your laptop?○ If you don't want to push to the main repository,

create a private clone on Bitbucket● Merge with care● But...

○ what if Bitbucket goes down?!

Page 81: Mercurial intro

Howto: Collaborate

Page 82: Mercurial intro

Howto: Collaborate

● hg serve to the rescue!● Runs an HTTP server

○ Browse your repository■ Useful for quick reviews!

○ Pull code from it■ hg pull http://my.ip.com:8000/

● hg serve is built-in

Page 83: Mercurial intro

Howto: Collaborate

● Default push/pull 'protocol': SSH● Allows pushing (hg serve does not, by

default)● hg push ssh://user@host/home/user/repo/path/

○ Use SSH keys

Page 84: Mercurial intro

Howto: Feature Branches

● Upside:○ Develop your feature without messing up the

'default' branch of the repository● Downside

○ amount of branches might become very large...■ Close your feature branches■ Use clones, bookmarks, ...

Page 85: Mercurial intro

Howto: Feature Branches

D0

D1

D2 B1

B2

B3

B4

Default

Feature branch

D3

D4

B5D5

D6

Use --close-branch

Feature merged into defaultNo choice about merge direction here.

Merge latest defaulthg merge default

Page 86: Mercurial intro

Howto: commit message template

● .hgrc:○ [ui]

username = Jens Geiregat <...>editor = /usr/bin/vim -c "r ~/.hgtemplate"

○ vim 'command' r[ead] <path>● .hgtemplate:

○ """

Reference:

Signed-off-by:"""

Page 87: Mercurial intro

Howto: (Bitbucket) SSH keys

● Easier pushing and pulling from Bitbucket● Easy to set up

○ http://bit.ly/S4l1ly● Invest 2 minutes, gain years of easier

Bitbucket interaction.● Also useful for non-Bitbucket servers

○ Use ssh-copy-id to publish your public key to a remote machine

Page 88: Mercurial intro

Howto: Remove a commit

● Removes a commit and every commit depending on it○ DANGER!○ Creates a backup in .hg/strip-backup as a bundle○ Can only be used when the strip happens on ALL

clones that contain the stripped commit(s).● Part of the mq extension:

○ [extensions]mq =

● Bitbucket can strip too○ Part of the admin interface

Page 89: Mercurial intro

Howto: undo a commit

● Commit the inverted patch of a previous commit

● hg backout <rev>

Page 90: Mercurial intro

Quiz 4

● What is the command to discard changes?

Page 91: Mercurial intro

Quiz 4

● What is the command to discard changes?○ hg revert

Page 92: Mercurial intro

Quiz 4

● What is the command to discard changes?○ hg revert

● What 'protocols' can be used for push/pull?

Page 93: Mercurial intro

Quiz 4

● What is the command to discard changes?○ hg revert

● What 'protocols' can be used for push/pull?○ SSH and HTTP

Page 94: Mercurial intro

Quiz 4

● What is the command to discard changes?○ hg revert

● What 'protocols' can be used for push/pull?○ SSH and HTTP

● Which head should you merge to?

Page 95: Mercurial intro

Quiz 4

● What is the command to discard changes?○ hg revert

● What 'protocols' can be used for push/pull?○ SSH and HTTP

● Which head should you merge to?○ The one with the most changes

Page 96: Mercurial intro

End of the basics.

● But there's much, much more.○ 'Advanced' commands (cat, archive, locate, grep)○ revsets○ mq○ (let me know what you would like to know)○ Anyone interested?

● Links:○ http://confluence.incubaid.

com/display/ENG/Incubaid+Starter+Kit○ http://confluence.incubaid.

com/display/ENG/Mercurial+Cheat+Sheet+-+Hg+Cheat+Sheet

○ http://hginit.com/○ http://hgbook.red-bean.com/

Page 97: Mercurial intro

Thank you!

● Questions?

Page 98: Mercurial intro

Advanced

● hg cat● hg archive● hg bisect● hg copy ?● hg grep● hg locate

● hg recover● hg resolve ?● hg revert● hg rollback● ext: record