bgneal@1: .. role:: strike bgneal@1: :class: strike bgneal@1: bgneal@0: Introduction to Distributed Version Control with Mercurial bgneal@0: ========================================================== bgneal@0: bgneal@0: ---- bgneal@0: bgneal@1: (Sublimal Message) bgneal@1: ================== bgneal@1: bgneal@4: .. image:: images/stop.jpg bgneal@1: bgneal@1: ---- bgneal@1: bgneal@0: # whoami bgneal@0: ======== bgneal@0: bgneal@0: Brian Neal bgneal@0: bgneal@0: Started at Rockwell Collins in July 1999 bgneal@0: bgneal@5: You might remember me from the following programs: bgneal@0: bgneal@0: - UMS (July 1999 - Spring 2000) bgneal@0: - Surgical Strike - (Spring - Fall 2000) bgneal@0: - JTRS 2B - (Fall 2000 - Summer 2001) bgneal@0: - SCAMP SEP - (Summer 2001 - October 2004) bgneal@0: - TTNT (January 2005 - Present) bgneal@0: bgneal@0: ---- bgneal@0: bgneal@0: Brief History of Version Control Tools bgneal@0: ====================================== bgneal@0: bgneal@0: First Generation bgneal@0: ---------------- bgneal@0: bgneal@1: - No networking! bgneal@1: - Concurrency method: locks bgneal@0: - Examples: bgneal@0: bgneal@0: - SCCS - 1972 bgneal@0: - RCS - 1982 bgneal@0: bgneal@0: ---- bgneal@0: bgneal@0: Brief History of Version Control Tools bgneal@0: ====================================== bgneal@0: bgneal@0: Second Generation bgneal@0: ----------------- bgneal@0: bgneal@0: - Client/Server networking; CVCS (Centralized Version Control) bgneal@1: - Concurrency method: merge before commit bgneal@0: - Examples: bgneal@0: bgneal@0: - CVS - 1990 bgneal@0: - IBM Rational ClearCase - 1992 bgneal@0: - Visual SourceSafe - 1994 bgneal@0: - Perforce - 1995 bgneal@0: - SVN - 2000 bgneal@0: bgneal@0: ---- bgneal@0: bgneal@0: Brief History of Version Control Tools bgneal@0: ====================================== bgneal@0: bgneal@0: Third Generation bgneal@0: ---------------- bgneal@0: bgneal@0: - Distributed networking; DVCS (Distributed Version Control) bgneal@1: - Concurrency method: commit then merge bgneal@1: - Examples: bgneal@0: bgneal@0: - Bitkeeper - 2000 bgneal@0: - Darcs - 2003 bgneal@0: - Monotone - 2003 bgneal@0: - Git - 2005 bgneal@0: - **Mercurial** - 2005 bgneal@0: - Fossil - 2006 bgneal@0: - Bazaar - 2007 bgneal@1: - Veracity - 2011 bgneal@1: bgneal@1: ---- bgneal@1: bgneal@1: What is a CVCS Again? bgneal@1: ===================== bgneal@1: bgneal@1: .. image:: images/cvcs.png bgneal@1: bgneal@1: ---- bgneal@1: bgneal@2: So what's a DVCS look like? bgneal@2: =========================== bgneal@2: bgneal@2: .. image:: images/dvcs.png bgneal@2: bgneal@2: All repositories are peers. By convention only, one repository is designated the master. bgneal@6: It is possible for all peers to exchange changes (via *push* and *pull* operations). bgneal@2: bgneal@2: ---- bgneal@2: bgneal@2: What does a DVCS buy you? bgneal@2: ========================= bgneal@2: bgneal@2: - Private workspaces bgneal@2: - Offline mode bgneal@2: - Speed bgneal@2: - Scalability bgneal@2: - Split Geography bgneal@2: - Flexible workflows bgneal@2: - Distributed backups bgneal@2: - **Easier merging** bgneal@2: - **Commit before merge** bgneal@2: bgneal@2: ---- bgneal@2: bgneal@2: Private Workspaces bgneal@2: ================== bgneal@2: bgneal@2: - You can safely experiment in your local repository bgneal@2: - Commit as often as you like without affecting the team bgneal@10: bgneal@10: - Encourages "micro-commits" bgneal@10: - With SVN, people often hold back until an entire feature is complete bgneal@10: bgneal@2: - Encourages experimentation bgneal@2: bgneal@2: - Make cheap repository clones to try things out bgneal@2: - Not visible to coworkers bgneal@2: bgneal@2: ---- bgneal@2: bgneal@2: Offline Mode bgneal@2: ============ bgneal@2: bgneal@2: - Work when you have spotty or no network access bgneal@2: - Full access to the repo when offline bgneal@2: - Can work on multiple tasks offline bgneal@2: bgneal@2: - Work on bug report #1 bgneal@2: - Commit bgneal@2: - Work on bug report #2 bgneal@2: - With a CVCS, you'd have both fixes in the same pending commit bgneal@2: bgneal@2: ---- bgneal@2: bgneal@2: Speed bgneal@2: ===== bgneal@2: bgneal@2: - Local operations are **fast** bgneal@8: bgneal@8: - No, really, **you will** notice a big difference bgneal@8: - Switching between branches will blow your mind bgneal@8: bgneal@2: - Initial pull down of an entire repository *might* be slower than a CVCS bgneal@2: bgneal@2: - Then again, you might be surprised bgneal@2: - Mercurial, for example, stores an entire repository in less space than bgneal@2: a SVN working copy in many cases bgneal@8: bgneal@2: bgneal@2: ---- bgneal@2: bgneal@2: Scalability bgneal@2: =========== bgneal@2: bgneal@2: - Some CVCS systems require heavy weight hardware to support the server bgneal@2: bgneal@2: - E.g. ClearCase with a thousand users bgneal@2: - With a DVCS, only pushes & pulls contact a central server bgneal@2: - Most of the work is done locally bgneal@2: bgneal@2: ---- bgneal@2: bgneal@2: Split Geography bgneal@2: =============== bgneal@2: bgneal@6: - Imagine a team split between Cedar Rapids & Richardson... bgneal@10: - With a CVCS, you have to pick where to put the server bgneal@2: - The remote location is stuck with network latency & associated problems bgneal@2: - With a DVCS, each site can have a central repository bgneal@2: bgneal@2: - The two central repos can be synched when convenient or even scripted bgneal@2: bgneal@9: .. image:: images/split_geography.png bgneal@9: bgneal@2: ---- bgneal@2: bgneal@2: Flexible Workflows bgneal@2: ================== bgneal@2: bgneal@2: - There is no internal concept of a central repository bgneal@2: - A central repository exits only by convention bgneal@2: - More elaborate topologies and workflows can be created: bgneal@2: bgneal@2: - A SW team may push to a central SW repo bgneal@2: - Periodically changes from the SW repo are pushed to a QA repo bgneal@2: - Changes from the QA repo can be pushed into a release repo bgneal@9: bgneal@9: .. image:: images/flexible_workflows.png bgneal@2: bgneal@2: ---- bgneal@2: bgneal@2: Distributed Backups bgneal@2: =================== bgneal@2: bgneal@2: - With a DVCS, multiple copies of the repository exist on multiple machines bgneal@2: - **Of course, this is no substitute for a real backup strategy!** bgneal@2: - But usually, and with short notice, you can easily designate a repository as bgneal@2: the central repository in an emergency bgneal@2: bgneal@2: ---- bgneal@2: bgneal@2: Easier Merging bgneal@2: ============== bgneal@2: bgneal@2: - Subversion has a bad reputation for merging bgneal@2: bgneal@2: - Some of this is not warranted... bgneal@2: bgneal@2: - Merge tracking was added in SVN v1.5 bgneal@2: bgneal@2: - SVN does not handle file renames and tree conflicts very well bgneal@2: - A lot of teams simply avoid merging out of fear bgneal@2: bgneal@2: ---- bgneal@2: bgneal@2: Easier Merging (cont.) bgneal@2: ====================== bgneal@2: bgneal@2: - Why is merging better in a DVCS? bgneal@2: bgneal@2: - Merging simply has to work correctly and be easy in a DVCS bgneal@2: bgneal@2: - More attention was paid to this aspect by DVCS's bgneal@2: bgneal@2: - DVCS's use directed acyclic graphs internally to represent change sets bgneal@2: bgneal@2: - More information is available to make merge decisions bgneal@2: - Easier to find common ancestors of code bgneal@2: bgneal@2: - Developer changes and merge changes are separate bgneal@2: bgneal@2: - "Commit before merge" bgneal@2: bgneal@2: ---- bgneal@2: bgneal@2: Commit Before Merge bgneal@2: =================== bgneal@2: bgneal@2: - With a CVCS: bgneal@2: bgneal@2: - You make changes in your working copy bgneal@2: - Before you can commit, you often must peform an update bgneal@2: bgneal@2: - This may trigger a merge bgneal@2: - Your changes are now mixed up with your friendly coworkers' changes bgneal@2: - Sometimes this can be a problem... bgneal@2: bgneal@2: - With a DVCS: bgneal@2: bgneal@2: - You make changes in your working copy bgneal@3: - You commit locally! bgneal@2: - You can then choose to pull changes from others and merge bgneal@2: bgneal@2: - **Your changes are already safely tucked away and can be retrieved later if things go wrong** bgneal@2: bgneal@2: ---- bgneal@2: bgneal@2: Okay, what's the catch? bgneal@2: ======================= bgneal@2: bgneal@2: Potential drawbacks to a DVCS bgneal@2: ----------------------------- bgneal@2: bgneal@2: - Practically no support for locks bgneal@2: bgneal@2: - This makes working with binary files difficult in a team environment bgneal@2: bgneal@2: - Huge repositories are not practical bgneal@2: bgneal@2: - Hetrogenous repositories are not practical bgneal@2: bgneal@2: - Not a good idea to mix, say, software, systems, and firmware in the same repo bgneal@2: - Not a good idea to mix multiple products in the same repo bgneal@2: - Arguably, this applies to a CVCS as well bgneal@2: bgneal@7: - No support for path-based access control bgneal@7: bgneal@7: - With current tools, you either can access the full repo, or nothing bgneal@7: bgneal@2: ---- bgneal@2: bgneal@2: Introduction to Mercurial bgneal@2: ========================= bgneal@2: bgneal@5: - Overview bgneal@6: - Repositories & working directories bgneal@2: - Changesets bgneal@4: - Branches & Tags bgneal@4: - Example workflow bgneal@3: - Command overview bgneal@2: bgneal@2: ---- bgneal@2: bgneal@5: Mercurial Overview bgneal@5: ================== bgneal@5: bgneal@5: - Distributed Version Control System bgneal@5: - Free, open source software licensed under GPL Version 2 bgneal@5: - Available for Microsoft Windows, GNU/Linux, Mac OS X, Solaris 11 Express bgneal@5: - Written in Python with a small amount of C bgneal@5: - Extensible with official and 3rd party extensions bgneal@5: - TortoiseHg is a popular GUI for Windows bgneal@5: - Reputation for being fast & easy to get started with bgneal@5: - Can be served via Apache Web server bgneal@5: - Repository hooks bgneal@5: - Integrates with Trac bgneal@5: - Can import history from other tools, including Subversion bgneal@5: bgneal@5: ---- bgneal@5: bgneal@6: Repositories & Working Directories bgneal@6: ================================== bgneal@3: bgneal@3: A repository consists of two things: bgneal@3: bgneal@4: - Your working directory (similar to a working copy in SVN) bgneal@3: - The repository itself (also known as "the store") bgneal@3: bgneal@3: - A .hg directory at the top of your working copy bgneal@3: bgneal@3: Example:: bgneal@3: bgneal@4: $ ls -A bgneal@3: .hg .hgignore images/ slides.cfg slides.css slides.html slides.rst bgneal@3: bgneal@6: - Repositories communicate via the *push* and *pull* commands bgneal@6: bgneal@6: - Push & Pull do not affect your working directory bgneal@6: bgneal@6: - An *update* or *merge* must be performed to receive remote changes into your working directory bgneal@6: bgneal@3: ---- bgneal@3: bgneal@3: What's in a Repository? bgneal@3: ======================= bgneal@3: bgneal@3: A repository consists of a directed, acyclic graph of *changesets* bgneal@3: bgneal@3: .. image:: images/repos.png bgneal@3: bgneal@4: - Each changeset can have 0, 1, or 2 parents (and infinite children) bgneal@3: - A changeset with 0 parents is the root bgneal@3: - A changeset with 2 parents is the result of a merge bgneal@4: - The newest changeset is called the *tip*, a special tag name bgneal@4: bgneal@4: ---- bgneal@4: bgneal@4: What's a Changeset? bgneal@4: =================== bgneal@4: bgneal@4: A changeset is an atomic collection of changes and some meta information. bgneal@4: The meta information includes: bgneal@4: bgneal@4: - Who made the changes bgneal@4: - When the changes were made bgneal@4: - Why - the commit message bgneal@4: - The name of the branch the changes were made on ("default" is the default) bgneal@4: - A local revision number bgneal@4: - A changeset ID; a 40 digit hex number (SHA-1 hash of the changeset & parents) bgneal@4: bgneal@4: A changeset can be named by: bgneal@4: bgneal@4: - Revision number (within a repository) bgneal@4: - Changeset ID (globally) bgneal@4: - Tag name bgneal@4: bgneal@4: ---- bgneal@4: bgneal@4: Branches & Tags bgneal@4: =============== bgneal@4: bgneal@4: - In the simple case, each changeset appear in a line bgneal@4: - When a changeset develops 2 or more children, a branch occurs bgneal@4: bgneal@4: - The latest revision of a branch is called a *head* bgneal@4: - A *merge* is when two branches join back together bgneal@4: - Branches can be given names; the default branch name is *"default"* bgneal@4: bgneal@4: - Changesets can be given human readable names, or *tags* bgneal@4: bgneal@4: - *Local tags* are only visible within a repository bgneal@4: - *Regular tags* are revision controlled and propagate to other repos bgneal@4: - The newest head in a repository is a tag called *tip* bgneal@4: bgneal@4: ---- bgneal@4: bgneal@4: Example Workflow bgneal@4: ================ bgneal@4: bgneal@4: .. image:: images/workflow1.png bgneal@4: bgneal@4: ---- bgneal@4: bgneal@4: Example Workflow (cont.) bgneal@4: ======================== bgneal@4: bgneal@4: .. image:: images/workflow2.png bgneal@4: bgneal@4: ---- bgneal@4: bgneal@4: Example Workflow (cont.) bgneal@4: ======================== bgneal@4: bgneal@4: .. image:: images/workflow3.png bgneal@3: bgneal@6: - Notice that after Alice's pull: bgneal@6: bgneal@6: - Her working directory is unaffected bgneal@6: - Her repository only has one head => no merging required bgneal@6: bgneal@6: bgneal@3: ---- bgneal@3: bgneal@3: SVN Commands for Review bgneal@3: ======================= bgneal@1: bgneal@1: Basic SVN commands: bgneal@1: bgneal@1: - add, remove, copy, move, mkdir bgneal@1: - checkout, commit, update, revert bgneal@1: - merge, resolved, diff bgneal@4: - status, log bgneal@1: - lock, unlock bgneal@1: bgneal@1: ---- bgneal@1: bgneal@4: Basic Mercurial Commands bgneal@4: ======================== bgneal@1: bgneal@1: Mercurial (hg) vs SVN commands: bgneal@1: bgneal@1: - add, remove, copy, move, :strike:`mkdir` bgneal@1: - :strike:`checkout`, commit, update, revert bgneal@4: - merge, resolve, diff, **heads** bgneal@4: - status, log bgneal@1: - :strike:`lock, unlock` bgneal@1: bgneal@1: Additional "distributed commands": bgneal@1: bgneal@5: - **clone**, **push**, **pull** bgneal@5: - **incoming**, **outgoing** bgneal@1: bgneal@4: **Not a whole lot to learn above SVN** bgneal@4: bgneal@4: ---- bgneal@4: bgneal@4: References bgneal@4: ========== bgneal@4: bgneal@4: - Mercurial http://mercurial.selenic.com/ bgneal@4: - Mercurial Wiki http://mercurial.selenic.com/wiki/ bgneal@4: - Mercurial Book (free!) http://hgbook.red-bean.com/ bgneal@4: - Hg Init: A Mercurial Tutorial http://hginit.com bgneal@4: - Version Control By Example (free!) http://www.ericsink.com/vcbe/ bgneal@4: bgneal@5: This presentation is available at:: bgneal@5: bgneal@5: $ hg clone https://bitbucket.org/bgneal/dvcs_intro_brownbag bgneal@5: bgneal@4: ---- bgneal@4: bgneal@4: Questions? bgneal@4: ========== bgneal@4: