Fast, Flexible and Fun: Revision Control with

Martin Geisler [email protected]

JAOO Geek Night in Aarhus August 25, 2009 Outline Introduction Basic Concepts Historic Context Subversion in Detail Using Mercurial The Underlying Model Workflows Using History Cool Extensions Changing History Talking to Other Systems Third-Party Tools Wrapping Up Alternatives Unsolved Problems Conclusion

2 / 45 Outline Introduction Basic Concepts Historic Context Subversion in Detail Using Mercurial The Underlying Model Workflows Using History Cool Extensions Changing History Talking to Other Systems Third-Party Tools Wrapping Up Alternatives Unsolved Problems Conclusion

3 / 45 Common features: ñ collaboration ñ branches ñ tags Not so common features: ñ speed! ñ much more, as you will see. . .

Features in Systems Universal features: ñ let you save changes ñ browser the history

4 / 45 Not so common features: ñ speed! ñ much more, as you will see. . .

Features in Version Control Systems Universal features: ñ let you save changes ñ browser the history Common features: ñ collaboration ñ branches ñ tags

4 / 45 Features in Version Control Systems Universal features: ñ let you save changes ñ browser the history Common features: ñ collaboration ñ branches ñ tags Not so common features: ñ speed! ñ much more, as you will see. . .

4 / 45 The Repository The database that holds your history: ñ series of project-wide snapshots ñ called or revisions in Mercurial ñ changesets encapsulate a delta between two snapshots ñ each has a parent changeset

Repository

5 / 45 The Working Directory Holds your files:

Alice Bob hello. hello.c Makefile goodbye.c Makefile

ñ you edit files in the working directory ñ reflects a changeset (the parent changeset) ñ also called a working copy

6 / 45 Branches A key concept: ñ parallel lines of development ñ used to track releases ñ used to isolate disruptive changes

7 / 45 Branches A key concept: ñ parallel lines of development ñ used to track releases ñ used to isolate disruptive changes

time

7 / 45 Branches A key concept: ñ parallel lines of development ñ used to track releases ñ used to isolate disruptive changes

1.0 time

7 / 45 Branches A key concept: ñ parallel lines of development ñ used to track releases ñ used to isolate disruptive changes

1.0 time

7 / 45 Branches A key concept: ñ parallel lines of development ñ used to track releases ñ used to isolate disruptive changes

1.0.1

1.0 time

7 / 45 Branches A key concept: ñ parallel lines of development ñ used to track releases ñ used to isolate disruptive changes

1.0.1 1.0.2

1.0 time

7 / 45 Merging The opposite of branching: ñ combines two branches ñ used to back bugfixes ñ used to integrate feature branches

1.0.1 1.0.2

1.0 time

8 / 45 Merging The opposite of branching: ñ combines two branches ñ used to merge back bugfixes ñ used to integrate feature branches

1.0.1 1.0.2

1.0 time

8 / 45 Merging The opposite of branching: ñ combines two branches ñ used to merge back bugfixes ñ used to integrate feature branches

1.0.1 1.0.2

1.0 time

8 / 45 Centralized Revision Control Subversion use a single server:

Repository

/ branches/ trunk/ hello.c bob/ hello.c Makefile hello.c Makefile Alice Makefile Carla Bob

9 / 45 Distributed Revision Control Mercurial duplicates the history on many servers:

Alice

Bob Carla

10 / 45 Distributed Revision Control Mercurial duplicates the history on many servers:

Alice’s Alice Laptop

Bob Carla

10 / 45 Distributed Revision Control Mercurial duplicates the history on many servers:

Alice’s Alice Laptop

Server

Bob Carla

10 / 45 Distributed Revision Control Mercurial duplicates the history on many servers:

Alice’s Alice Laptop

Server

Bob Carla

10 / 45 (RCS) Version control from the 1980s: ñ store changes (date, message) ñ browse history

11 / 45 Revision Control System (RCS) Version control from the 1980s: ñ store changes (date, commit message) ñ browse history

hello.c:

Makefile:

11 / 45 Revision Control System (RCS) Version control from the 1980s: ñ store changes (date, commit message) ñ browse history

hello.c:

Makefile:

11 / 45 Revision Control System (RCS) Version control from the 1980s: ñ store changes (date, commit message) ñ browse history

hello.c:

Makefile:

11 / 45 Revision Control System (RCS) Version control from the 1980s: ñ store changes (date, commit message) ñ browse history

hello.c:

Makefile:

11 / 45 Revision Control System (RCS) Version control from the 1980s: ñ store changes (date, commit message) ñ browse history

hello.c:

Makefile:

11 / 45 Revision Control System (RCS) Version control from the 1980s: ñ store changes (date, commit message) ñ browse history

hello.c:

Makefile:

11 / 45 CVS Server Alice Bob

hello.c hello.c: hello.c Makefile Makefile: Makefile

Concurrent Versions System (CVS) Version control in the 1990s: ñ collaboration over the network ñ several working copies ñ one central repository

12 / 45 Concurrent Versions System (CVS) Version control in the 1990s: ñ collaboration over the network ñ several working copies ñ one central repository

CVS Server Alice Bob

hello.c hello.c: hello.c Makefile Makefile: Makefile

12 / 45 Concurrent Versions System (CVS) Version control in the 1990s: ñ collaboration over the network ñ several working copies ñ one central repository

CVS Server Alice Bob

hello.c commit hello.c: hello.c Makefile Makefile: Makefile

12 / 45 Concurrent Versions System (CVS) Version control in the 1990s: ñ collaboration over the network ñ several working copies ñ one central repository

CVS Server Alice Bob

hello.c hello.c: update hello.c Makefile Makefile: Makefile

12 / 45 So, everything is good? CVS has many limitations: ñ no atomic commits ñ no rename information ñ branches? I hope you have a CVS guru at hand. . .

13 / 45 Subversion (SVN) Version control from this millennia — “CVS done right”: ñ atomic commits ñ tracks renames ñ supports some operations without network access ñ clean and simple design compared to CVS

14 / 45 Merging in Subversion SVN is a centralized system:

Repository

hello.c hello.c Makefile Makefile Alice Eve

hello.c hello.c Makefile hello.c Makefile Makefile Bob Dan Carla

ñ merging takes place in client ñ merging takes place on server(!)

15 / 45 What if you want to abandon a merge? ñ you can revert files with conflicts to their old state ñ but other files may have been updated ñ beware of mixed revisions. . .

SVN Merge in Client When you do svn update, you merge: ñ this can of course result in conflicts ñ you must resolve the merge before you go on ñ might be difficult to handle everything at once

16 / 45 SVN Merge in Client When you do svn update, you merge: ñ this can of course result in conflicts ñ you must resolve the merge before you go on ñ might be difficult to handle everything at once What if you want to abandon a merge? ñ you can revert files with conflicts to their old state ñ but other files may have been updated ñ beware of mixed revisions. . .

16 / 45 They both have mixed revisions in their working copies:

hello.c (r2) hello.c (r1) Makefile (r1) Makefile (r3) Alice Bob

Difficult for Carla to reproduce either working copy.

Mixed Revisions?! SVN lets you work with an inconsistent working copy: ñ Alice and Bob have revision 1 ñ Alice changes hello.c → revision 2 ñ Bob changes Makefile → revision 3

17 / 45 Mixed Revisions?! SVN lets you work with an inconsistent working copy: ñ Alice and Bob have revision 1 ñ Alice changes hello.c → revision 2 ñ Bob changes Makefile → revision 3 They both have mixed revisions in their working copies:

hello.c (r2) hello.c (r1) Makefile (r1) Makefile (r3) Alice Bob

Difficult for Carla to reproduce either working copy.

17 / 45 Server-Side Merges Mixed revisions are a result of allowing server-side merges ñ can we forbid server-side merges? ñ not really — it would ruin branches in SVN

18 / 45 Branches in SVN Subversion knows nothing about branches! ñ but SVN has a cheap copy mechanism ñ used for tags and branches

19 / 45 Branches in SVN Subversion knows nothing about branches! ñ but SVN has a cheap copy mechanism ñ used for tags and branches r10 trunk/ hello.c Makefile branches/ tags/

19 / 45 Branches in SVN Subversion knows nothing about branches! ñ but SVN has a cheap copy mechanism ñ used for tags and branches r10 r11 trunk/ trunk/ hello.c hello.c Makefile Makefile branches/ branches/ tags/ goodbye/ hello.c Makefile tags/

19 / 45 Branches in SVN Subversion knows nothing about branches! ñ but SVN has a cheap copy mechanism ñ used for tags and branches r10 r11 r12 trunk/ trunk/ trunk/ hello.c hello.c hello.c Makefile Makefile Makefile branches/ branches/ branches/ tags/ goodbye/ goodbye/ hello.c hello.c Makefile goodbye.c tags/ Makefile tags/

19 / 45 The bottom line is that Subversion’s merge-tracking feature has an extremely complex internal implementation, and the svn:mergeinfo property is the only window the user has into the machinery. Because the feature is relatively new, a numbers of edge cases and possible unexpected behaviors may pop up. —Version Control with Subversion

(Mercurial has robust built-in support for merging branches.)

Merging Branches in SVN Branches are only interesting if you can merge them: ñ before SVN 1.5: no built-in support for merging(!) ñ SVN 1.5 and later: tracks info needed for merging

20 / 45 Merging Branches in SVN Branches are only interesting if you can merge them: ñ before SVN 1.5: no built-in support for merging(!) ñ SVN 1.5 and later: tracks info needed for merging

The bottom line is that Subversion’s merge-tracking feature has an extremely complex internal implementation, and the svn:mergeinfo property is the only window the user has into the machinery. Because the feature is relatively new, a numbers of edge cases and possible unexpected behaviors may pop up. —Version Control with Subversion

(Mercurial has robust built-in support for merging branches.)

20 / 45 Outline Introduction Basic Concepts Historic Context Subversion in Detail Using Mercurial The Underlying Model Workflows Using History Cool Extensions Changing History Talking to Other Systems Third-Party Tools Wrapping Up Alternatives Unsolved Problems Conclusion

21 / 45 Live Demo!

22 / 45 The Underlying Model A Mercurial changeset conceptually consist of: ñ 0–2 parent changeset IDs: ñ root changeset has no parents ñ normal commits have one parent ñ merge changesets have two parents ñ date, username, commit message ñ difference from first parent ñ changeset ID is computed as SHA-1 hash of the above

23 / 45 Immutable History SHA-1 hashes as changeset IDs have some consequences: ñ a changeset ID is a hash of the entire history ñ changing history changes subsequent changesets ñ history is immutable, you can only make new history:

A B C D E

24 / 45 Immutable History SHA-1 hashes as changeset IDs have some consequences: ñ a changeset ID is a hash of the entire history ñ changing history changes subsequent changesets ñ history is immutable, you can only make new history:

A B C D E

C0 D0 E0

24 / 45 Immutable History SHA-1 hashes as changeset IDs have some consequences: ñ a changeset ID is a hash of the entire history ñ changing history changes subsequent changesets ñ history is immutable, you can only make new history:

A B C D E

C0 D0 E0

24 / 45 Central Workflow Everybody has write access to a central repository:

Repository

Alice Eve

Bob Dan Carla

25 / 45 Pull Workflow People have read-only access (e.g., hg serve): Alice Bob 0 0

Carla 0

26 / 45 Pull Workflow People have read-only access (e.g., hg serve): Alice Bob 0 1 0

Carla 0

26 / 45 Pull Workflow People have read-only access (e.g., hg serve): Alice Bob 0 1 2 0

Carla 0

26 / 45 Pull Workflow People have read-only access (e.g., hg serve): Alice Bob 0 1 2 0 1

Carla 0

26 / 45 Pull Workflow People have read-only access (e.g., hg serve): Alice Bob 0 1 2 0 1 pull 1

Carla 0

26 / 45 Pull Workflow People have read-only access (e.g., hg serve): Alice Bob 0 1 2 3 0 1

1

Carla 0

26 / 45 Pull Workflow People have read-only access (e.g., hg serve): Alice Bob 0 1 2 3 0 1

1

Carla 0 1

26 / 45 Pull Workflow People have read-only access (e.g., hg serve): Alice Bob 0 1 2 3 0 1

1

Carla 0 1 2

26 / 45 Pull Workflow People have read-only access (e.g., hg serve): Alice Bob 0 1 2 3 0 1

1

pull Carla 0 1 2

1

26 / 45 Pull Workflow People have read-only access (e.g., hg serve): Alice Bob 0 1 2 3 0 1

1

Carla 0 1 2 3

1

26 / 45 Pull Workflow People have read-only access (e.g., hg serve): Alice Bob 0 1 2 3 0 1

1

pull

Carla 0 1 2 3

1

1 2 3

26 / 45 Pull Workflow People have read-only access (e.g., hg serve): Alice Bob 0 1 2 3 0 1

1

Carla 0 1 2 3 4

1

1 2 3

26 / 45 Exploring History Everything is local and fast: ñ hg log can search in commit messages and usernames ñ hg grep searches in file content ñ hg bisect makes a binary search on the revision graph

27 / 45 Revision Graph Bisection You’ve found a bug! When was it first introduced? Use hg bisect to mark good and bad revisions:

bad

28 / 45 Revision Graph Bisection You’ve found a bug! When was it first introduced? Use hg bisect to mark good and bad revisions:

test bad

28 / 45 Revision Graph Bisection You’ve found a bug! When was it first introduced? Use hg bisect to mark good and bad revisions:

good bad

28 / 45 Revision Graph Bisection You’ve found a bug! When was it first introduced? Use hg bisect to mark good and bad revisions:

good test bad

28 / 45 Revision Graph Bisection You’ve found a bug! When was it first introduced? Use hg bisect to mark good and bad revisions:

good good bad

28 / 45 Revision Graph Bisection You’ve found a bug! When was it first introduced? Use hg bisect to mark good and bad revisions:

good good bad

test

28 / 45 Revision Graph Bisection You’ve found a bug! When was it first introduced? Use hg bisect to mark good and bad revisions:

good good bad

bad

28 / 45 Revision Graph Bisection You’ve found a bug! When was it first introduced? Use hg bisect to mark good and bad revisions:

good good bad

test bad

28 / 45 Revision Graph Bisection You’ve found a bug! When was it first introduced? Use hg bisect to mark good and bad revisions:

good good bad

bug! bad

28 / 45 Outline Introduction Basic Concepts Historic Context Subversion in Detail Using Mercurial The Underlying Model Workflows Using History Cool Extensions Changing History Talking to Other Systems Third-Party Tools Wrapping Up Alternatives Unsolved Problems Conclusion

29 / 45 Mercurial is Extensible You can add new functionality to Mercurial: ñ ships with 30 extensions ñ wiki lists 57 extensions ñ extensions can change basically everything ñ helps to keep the core small and focused

30 / 45 ñ Merge: A B C D E M

X Y Z

ñ Rebase: A B C D E

X Y Z D0 E0

ñ Beware: public changes should never be rebased.

Moving Changesets Around Tired of all those merges? Use the rebase extension! ñ Revision graph: A B C

31 / 45 ñ Merge: A B C D E M

X Y Z

ñ Rebase: A B C D E

X Y Z D0 E0

ñ Beware: public changes should never be rebased.

Moving Changesets Around Tired of all those merges? Use the rebase extension! ñ Revision graph: A B C D E

31 / 45 ñ Merge: A B C D E M

X Y Z

ñ Rebase: A B C D E

X Y Z D0 E0

ñ Beware: public changes should never be rebased.

Moving Changesets Around Tired of all those merges? Use the rebase extension! ñ Revision graph: A B C D E

X Y Z

31 / 45 ñ Rebase: A B C D E

X Y Z D0 E0

ñ Beware: public changes should never be rebased.

Moving Changesets Around Tired of all those merges? Use the rebase extension! ñ Revision graph: A B C D E

X Y Z

ñ Merge: A B C D E M

X Y Z

31 / 45 ñ Beware: public changes should never be rebased.

Moving Changesets Around Tired of all those merges? Use the rebase extension! ñ Revision graph: A B C D E

X Y Z

ñ Merge: A B C D E M

X Y Z

ñ Rebase: A B C D E

X Y Z D0 E0

31 / 45 Moving Changesets Around Tired of all those merges? Use the rebase extension! ñ Revision graph: A B C D E

X Y Z

ñ Merge: A B C D E M

X Y Z

ñ Rebase: A B C D E

X Y Z D0 E0

ñ Beware: public changes should never be rebased.

31 / 45 Maintaining Series The mq extension makes it easy to maintain a patch series:

. . Works nicely for local modification for upstream sources.

32 / 45 Maintaining Patch Series The mq extension makes it easy to maintain a patch series:

code

. . Works nicely for local modification for upstream sources.

32 / 45 Maintaining Patch Series The mq extension makes it easy to maintain a patch series:

test

code

. . Works nicely for local modification for upstream sources.

32 / 45 Maintaining Patch Series The mq extension makes it easy to maintain a patch series:

doc

test

code

. . Works nicely for local modification for upstream sources.

32 / 45 Maintaining Patch Series The mq extension makes it easy to maintain a patch series:

doc

qpush test qpop

code

. . Works nicely for local modification for upstream sources.

32 / 45 ñ fold changesets: A B C Ž A BC

ñ drop changesets: A B C Ž A C0

ñ edit changesets: A B C Ž A X B0 C0

Editing History Inspired by rebase -i, histedit lets you ñ reorder changesets: A B C Ž A C0 B0

33 / 45 ñ drop changesets: A B C Ž A C0

ñ edit changesets: A B C Ž A X B0 C0

Editing History Inspired by git rebase -i, histedit lets you ñ reorder changesets: A B C Ž A C0 B0

ñ fold changesets: A B C Ž A BC

33 / 45 ñ edit changesets: A B C Ž A X B0 C0

Editing History Inspired by git rebase -i, histedit lets you ñ reorder changesets: A B C Ž A C0 B0

ñ fold changesets: A B C Ž A BC

ñ drop changesets: A B C Ž A C0

33 / 45 Editing History Inspired by git rebase -i, histedit lets you ñ reorder changesets: A B C Ž A C0 B0

ñ fold changesets: A B C Ž A BC

ñ drop changesets: A B C Ž A C0

ñ edit changesets: A B C Ž A X B0 C0

33 / 45 Interestingly, convert can import from Mercurial: ñ --filemap lets you exclude and rename files ñ --branchmap lets you rename branches

Migrating History The convert extension can import history: ñ CVS, SVN, Git, Bazaar, , . . . ñ incremental conversion ñ many options for fiddling with branches, authors, . . .

34 / 45 Migrating History The convert extension can import history: ñ CVS, SVN, Git, Bazaar, Darcs, . . . ñ incremental conversion ñ many options for fiddling with branches, authors, . . . Interestingly, convert can import from Mercurial: ñ --filemap lets you exclude and rename files ñ --branchmap lets you rename branches

34 / 45 Interfacing with Subversion The hgsubversion extension let’s you: ñ use hg clone on a SVN URLs ñ use hg pull to convert new SVN revisions ñ use hg push to commit changesets to SVN server The extension is being used, but please note: ñ it is not yet feature complete ñ requires standard trunk/, branches/ and tags/ layout

35 / 45 Interfacing with Git Need to work on a Git repository? Try hg-git! ñ Mercurial extension: you get the nice hg command line ñ round-tripping: changeset hashes are preserved

Git

Hg Hg Git

36 / 45 Third-Party Tools Tools with Mercurial support: ñ Shell integration: TortoiseHg (Windows, Mac, ) ñ IDEs: Eclipse, NetBeans, IntelliJ, Visual Studio, Emacs. . . ñ Project Support: , , Maven, Hudson, . . . ñ Ant tasks

37 / 45 TortoiseHg Screenshots

38 / 45 TortoiseHg Screenshots

38 / 45 TortoiseHg Screenshots

38 / 45 Outline Introduction Basic Concepts Historic Context Subversion in Detail Using Mercurial The Underlying Model Workflows Using History Cool Extensions Changing History Talking to Other Systems Third-Party Tools Wrapping Up Alternatives Unsolved Problems Conclusion

39 / 45 Git The version control system by : ñ distributed, fast, scalable ñ used by Linux Kernel, Perl, and many others ñ written in C, shell scripts(!) and a little Perl ñ models history the same way as Mercurial

40 / 45 Git Differences Git is different in a number of ways: ñ quite verbose compared to Mercurial ñ core Mercurial never rewrites history, Git has it built-in ñ changes are added to an “index” before commit:

% git add . % git commit -m ’Initial import.’ [master (root-commit) ba41f97] Initial import. 2 files changed, 7 insertions(+), 0 deletions(-) create mode 100644 Makefile create mode 100644 hello.c % echo ’/* The End */’ >> hello.c % git add hello.c % git commit -m ’Added comment.’ [master 2489734] Added comment. 1 files changed, 1 insertions(+), 0 deletions(-)

41 / 45 Why isn’t everybody using Darcs? ñ determining if a change commutes with another is slow ñ merges could take hours or days with older versions

Darcs Repository consist of unordered changesets:

+first +second

first first -first -bottom -second +top +bot +bottom second

42 / 45 Why isn’t everybody using Darcs? ñ determining if a change commutes with another is slow ñ merges could take hours or days with older versions

Darcs Repository consist of unordered changesets:

+first +second first second

first first -first -bottom -second +top +bot +bottom second

42 / 45 Why isn’t everybody using Darcs? ñ determining if a change commutes with another is slow ñ merges could take hours or days with older versions

Darcs Repository consist of unordered changesets:

+first +second first bottom

first first -first -bottom -second +top +bot +bottom second

42 / 45 Why isn’t everybody using Darcs? ñ determining if a change commutes with another is slow ñ merges could take hours or days with older versions

Darcs Repository consist of unordered changesets:

+first +second first bot

first first -first -bottom -second +top +bot +bottom second

42 / 45 Why isn’t everybody using Darcs? ñ determining if a change commutes with another is slow ñ merges could take hours or days with older versions

Darcs Repository consist of unordered changesets:

+first +second top second

first first -first -bottom -second +top +bot +bottom second

42 / 45 Why isn’t everybody using Darcs? ñ determining if a change commutes with another is slow ñ merges could take hours or days with older versions

Darcs Repository consist of unordered changesets:

+first +second top bottom

first first -first -bottom -second +top +bot +bottom second

42 / 45 Why isn’t everybody using Darcs? ñ determining if a change commutes with another is slow ñ merges could take hours or days with older versions

Darcs Repository consist of unordered changesets:

+first +second top bot

first first -first -bottom -second +top +bot +bottom second

42 / 45 Darcs Repository consist of unordered changesets:

+first +second

first first -first -bottom -second +top +bot +bottom second

Why isn’t everybody using Darcs? ñ determining if a change commutes with another is slow ñ merges could take hours or days with older versions

42 / 45 Unsolved Problems DVCSs generally have problems with ñ large binary files ñ retrieving only a sub-tree (narrow clones) ñ retrieving only recent history (shallow clones) Some more Mercurial specific problems are: ñ it is fairly easy to create conflicts in .hgtags files ñ filename encodings across different filesystems

43 / 45 Mercurial in a Nutshell Mercurial changes the way you develop: ñ simple yet strong model for both branching and merging ñ power tool instead of necessary evil ñ light-weight and snappy

44 / 45 More Information

ñ Mercurial homepage: http://mercurial.selenic.com/ ñ Mercurial: The Definitive Guide: http://hgbook.red-bean.com/ ñ Some free Mercurial hosting sites: http://www.bitbucket.org/ http://code.google.com/ http://sourceforge.net/

45 / 45 More Information

ñ Mercurial homepage: http://mercurial.selenic.com/ ñ Mercurial: The Definitive Guide: http://hgbook.red-bean.com/ ñ Some free Mercurial hosting sites: http://www.bitbucket.org/ http://code.google.com/ http://sourceforge.net/

Thank you!

45 / 45