Mercurial by Example. v0.36. Thorbjörn Jemander - PDF

Description
Mercurial by Example v0.36 by Thorbjörn Jemander Thorbjörn Jemander, All rights reserved. No part of this work may be used to create derivative works, electronic or hard copy, and hard copies

Please download to get full document.

View again

of 27
All materials on our website are shared by users. If you have any questions about copyright issues, please report us to resolve them. We are always happy to assist you.
Information
Category:

Games & Puzzles

Publish on:

Views: 16 | Pages: 27

Extension: PDF | Download: 0

Share
Transcript
Mercurial by Example v0.36 by Thorbjörn Jemander Thorbjörn Jemander, All rights reserved. No part of this work may be used to create derivative works, electronic or hard copy, and hard copies of this may not be sold or in any way used commercially, without the prior, written consent by the author. Usage without consent is restricted to electronic reading, copying, linking, distribution, and printing hard copies for the purpose of personal use only. Feedback is welcome. Contact information is available at Mercurial by Example 1.Table of Contents 1 Introduction Key to reading Installing Mercurial Basics Creating a repository Adding, removing and checking in files History Navigation and tagging Examining: diff and cat Undo: revert, forget and rollback Searching: grep and locate Bisect Diverging history Heads Merge Branching Distributed development Clone Pull Outstanding uncommitted changes Push Restrictions Merge conflicts Fetch Unrelated repositories Import/Export Archive Export Import Bundle/Unbundle Working with patches UNIX patches Patch queues qinit qnew qseries and qapplied qpop qpush qrefresh and qdiff Multiple patches Moving between patches: qgoto Committing patches: qfold and qfinish Rejected patches Extras 4 9.1 Rebase More undo Backout Clone Strip Transplant aka Cherry picking Setting up a server Tracking external software Using two repositories Using an import branch...58 Mercurial by Example 1 Introduction I wanted an examples based Mercurial tutorial, which was quick and to-the-point, without a lot of theory or principles of operation. Here it is, without prating. Do worry if it seems long to you, you'll walk through it rather rapidly. 1.1 Key to reading The table below shows the appearing boxes in this document. Item $ ls -flag # this command foo.txt bar.txt # this file Tip: if you write... Foo bar The file Myfile.sh Description Terminal commands, $ represents the prompt. Input is in bold, output is not bold. Red text is interesting input, the point of the example. Blue text is interesting output. #Green hashed text are comments, not to be typed in. Comment, tip, further reading or reference. Contents of a file, in this case Myfile.sh It is not recommended to skip examples, as later examples may depend on the results of the previous. 5 2 Installing Mercurial 2 Installing Mercurial If you're using a Debian-based Linux PC, which has the apt program manager, you can do the following: $ sudo apt-get install mercurial $ hg version Mercurial Distributed SCM (version 1.3.1) Copyright (C) Matt Mackall and others This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. For other OS:es, see 6 Mercurial by Example 3 Basics 3.1 Creating a repository Create a mercurial repository in an empty directory by using the init command: $ mkdir hg1 $ cd hg1 $ hg init Now there is an empty repository created, locally in your directory. The repository contains both a working copy, and the repository data (the history information). This is unlike non-distributed SCMs, like CVS or SVN, where the the repository contains only the revision history and the working copy only contains the checked out code. 3.2 Adding, removing and checking in files Time to start make some history: $ echo A x1 $ hg add x1 $ hg ci -m added feature A to module x1. This is very similar to SVN. Make some more history and learn how to remove: $ echo A x2 $ echo B y1 $ hg add x2 y1 $ hg ci -m added A to x2 and B to y1. $ hg rm x1 $ hg ci -m removed x1 So now we're added and removed files explicitly. However, there's a command called addremove that detects added and removed files automatically for us: $ echo C z1 $ rm x2 # Note: not hg rm $ hg addremove removing x2 adding z1 $ hg status A z1 R x2 $ hg ci -m adding C to z1 and removing x2 Status is a command to check what the pre-commit status is. It tells you whether files are (A)dded, (R)emoved, (M)odified among other things. Check out the manifest command too. So the status command gives some nice information before commit. Let's look at our log now: 7 3 Basics $ hg log changeset: 3:c9d133e1c054 tip date: Sat Dec 12 10:15: summary: Adding C to z1 and removing x2 changeset: 2:3d8afaf1ac30 date: Sat Dec 12 10:13: summary: Removed x1 changeset: 1:01e9f6a4aae5 date: Sat Dec 12 10:12: summary: Added A to x2 and B to y1. changeset: 0:593b00eec7b1 date: Sat Dec 12 09:49: summary: Added feature A to module x1 We can see that there is a straight history, starting with revision zero and ending with revision three. Revision three is also the so-called tip, which marks the most recent point in the revision history. If you wish, you can look at parts of the history by specify revision ranges: $ hg log -r 1:2 # From 1 to 2 changeset: 2:3d8afaf1ac30 date: Sat Dec 12 10:13: summary: Removed x1 changeset: 1:01e9f6a4aae5 date: Sat Dec 12 10:12: summary: Added A to x2 and B to y1. $ hg log -r :1 # Up to, and including 1. changeset: 1:01e9f6a4aae5 date: Sat Dec 12 10:12: summary: Added A to x2 and B to y1. changeset: 0:593b00eec7b1 date: Sat Dec 12 09:49: summary: Added feature A to module x1 $ hg log -r 2: # From, and including 2. changeset: 3:c9d133e1c054 tip date: Sat Dec 12 10:15: summary: Adding C to z1 and removing x2 changeset: 2:3d8afaf1ac30 date: Sat Dec 12 10:13: summary: Removed x1 8 Mercurial by Example 4 History 4.1 Navigation and tagging Before we start moving where are we right now? Use the identity command to check: $ hg identify -n 3 # We're at revision 3. Currently we're at changeset 3. To move in the repository history, we use the update command: $ hg update -r 0 # Move to revision 0. 1 files updated, 0 files merged, 2 files removed, 0 files unresolved $ ls x1 There is a convention to use -r to specify revisions, but in update, the -r is actually optional. Most commands can be abbreviated: $ hg up # No revision specified we go to the latest. 1 files updated, 0 files merged, 2 files removed, 0 files unresolved $ ls y1 z1 With no argument to update, it moves to the the tip. As mentioned above, the tip is a symbolic name for the latest revision. You can assign your own symbolic names to specific revisions. These are known as tags: $ hg tag -r 2 my-x1-removal # Associate a name to revision 2 $ hg log changeset: 4:4207f3b7f4ee tip date: Sat Dec 12 16:41: summary: Added tag my-x1-removal for changeset 3d8afaf1ac30 changeset: 3:c9d133e1c054 date: Sat Dec 12 10:15: summary: Adding C to z1 and removing x2 changeset: 2:3d8afaf1ac30 my-x1-removal date: Sat Dec 12 10:13: summary: Removed x1 changeset: 1:01e9f6a4aae5 date: Sat Dec 12 10:12: summary: Added A to x2 and B to y1. changeset: user: 0:593b00eec7b1 Thorbjorn Jemander 9 4 History date: Sat Dec 12 09:49: summary: Added feature A to module x1 $ hg tags tip 4:4207f3b7f4ee my-x1-removal 2:3d8afaf1ac30 Thus, the tags can be explicitly listed using the tags command, but they also show up in the revision log. You can use tag names instead of changeset numbers in most commands. 4.2 Examining: diff and cat We can rename files and directories: $ hg rename y1 y2 $ hg ci -m y1 renamed to y2 $ ls y2 z1 $ echo C y2 $ hg ci -m updated module y2 with feature C. New contents, new name, but the identity of a file is tracked. Note that the -f flag is needed to log across renames, or the log command will stop at the rename: $ hg log y2 changeset: 6: f tip date: Sat Dec 12 17:08: summary: Updated module y2 with feature C. changeset: 5:538cc1eb311d date: Sat Dec 12 17:05: summary: y1 renamed to y2 $ hg log -f y2 changeset: 6: f tip date: Sat Dec 12 17:08: summary: Updated module y2 with feature C. changeset: 5:538cc1eb311d date: Sat Dec 12 17:05: summary: y1 renamed to y2 changeset: 1:01e9f6a4aae5 date: Sat Dec 12 10:12: summary: Added A to x2 and B to y1. We don't need to update the entire repository to another revision to look at the contents of individual files. We can check the difference (diff) and print the whole file (cat): 10 Mercurial by Example $ echo D y2 $ hg diff y2 # What's the difference between the repo. and the working copy? diff -r f y2 --- a/y2 Sat Dec 12 17:08: b/y2 Sat Dec 12 17:22: ,1 +1,1 -C +D $ hg diff -r 5 y2 # How is the working copy different form revision 5? diff -r 538cc1eb311d y2 --- a/y2 Sat Dec 12 17:05: b/y2 Sat Dec 12 17:23: ,1 +1,1 -B +D $ hg cat -r 5 y2 # Print (cat) y2 as it were in revision 5. B $ hg ci -m let advance to experimental D version This last example, with cat, can be used to restore files from history, by redirecting the contents to the local file: $ hg tip changeset: 7: a2 tip date: Sat Dec 12 17:31: summary: Let advance to experimental D version $ hg cat -r 6 y2 y2 # Print revision 6 and redirect to local file y2 $ hg diff diff -r a2 y2 --- a/y2 Sat Dec 12 17:31: b/y2 Sat Dec 12 17:34: ,1 +1,1 -D +C $ hg ci -m d caused a thermonuclear explosion. Backed to C. That's a way to undo a previous change, but a bit primitive. Let's move on to the to topic of undoing things. 4.3 Undo: revert, forget and rollback The last example above showed a way to restore from files previous states in the next revision by using cat. However, there is a dedicated command revert that does precisely that (which also works for directories): $ hg revert -r 5 y2 # Restores the local copy to the revision 5 state $ cat y2 B $ hg ci -m y2/c caused a chemical explosion. Going back to y2/b. But what if we've accidentally added files, and want to remove them before we check in? There's an easy way to tell Mercurial to forget about them: 11 4 History $ touch a y2.o z1.o $ hg addremove adding a adding y2.o adding z1.o $ hg forget y2.o z1.o $ hg ci -m adding new module a $ rm *.o Do you always want to ignore.o files? You can specify file patterns to ignore in a file called.hgignore in the root of the repository. Read more in the man page for hgignore: man hgignore. Assume we have committed something very stupid, that we really regret. Fortunately, we can rollback the last transaction. Think of rollback as undo the last check-in : $ mv * /tmp... $ hg addremove # Maybe you get distracted... removing a removing y2 removing z1 $ hg ci -m quick check-in #... and check in something really bad. $ ls # Nothings left. And it's checked in! $ hg rollback # Don't worry, rollback! rolling back last transaction $ hg up -C # We need to update the working copy. 3 files updated, 0 files merged, 0 files removed, 0 files unresolved $ ls # Phew, we're back. a y2 z1 Note that you need to update after the rollback. Note also that you have not just moved back in history one step, you have completely erased the last check-in from history. You cannot perform several consecutive rollbacks as Mercurial only stores information for one rollback. If you stay with us until chapter 9.2, we'll discuss more powerful undo techniques. 4.4 Searching: grep and locate We now know how to commit, undo and how to move back and forth in the history. Next topic is about locating files and finding contents in the history. There are two commands available for this: grep and locate. They work similar to the UNIX shell commands with the same name, but with the addition of history information. In the example below, remember that y1 was renamed to y2 early on, and that y2 has changed contents throughout history (B C D C B). $ hg locate y1 # There's no y1 in the current version $ hg locate -r 1 y1 # There's a y1 in revision 1 y1 $ hg grep B y2 y2:9:b # y2 in rev.9 contained B Do $ hg grep - all B y2 you want to know who is y2:9:+:b # B reappeared in 9 responsible for a particular line in y2:6:-:b # B disappeared in 6 a file? You can find out by using y2:5:+:b # B first appeared in 5 the blame command, or by its $ hg grep -f -all B y2 # With -f it goes across proper y2:9:+:b # renames. name annotate. Use y2:6:-:b hg help annotate to find out y2:5:+:b more. y1:1:+:b 12 Mercurial by Example The flag --all means print all matches, while -f means (just as above) follow renames Bisect Suppose you have received a bug report from a customer, and you want to know when this bug was introduced to deduce how many releases that are affected. Mercurial can help you find the origin of the bug, if you can provide it with a test command. The test command must return 0 if the bug is not present and 1 if the bug is present. Mercurial uses the test command while it jumps back and forth in history to deduce whether revisions are good or bad. It stops when it has found the earliest version that is bad. For example, let say we have a bug in our system that is represented by that the y and z files have different numbers: thus having the files y2 ans z1 simultaneously represents a bug condition, while y1 and z1 would not. Then a (very simple) test function could look like the one to the right, implemented as a shell script. Copy this script to a file named test.sh and make it executable (using chmod). Run it and you'll see that it tells you that the bug is present in the current working copy. For Mercurial to find the bug we need to tell it three things: 1. A version that has the bug/is bad (hg bisect -b), 2. A version that doesn't have the bug/is good (hg bisect -g), 3. The test command (hg bisect -c) #!/bin/sh if [ z* = z1 -a y* = y1 ]; then echo No bug! exit 0 else echo Bug! exit 1 fi The file test.sh We know for a fact that changeset 3 didn't contain the bug and that the current revision (10) does. Enter the following and Mercurial will run your test command on an intelligent selection of revisions to deduce where the bug was first introduced: $ hg bisect -r # Reset the bisect state $ hg bisect -b 10 # Revision 10 (the tip) has the bug $ hg bisect -g 3 # Revision 3 does not. Testing changeset 6:1f6db2bf99f3 (7 changesets remaining, ~2 tests) 1 files updated, 0 files merged, 1 files removed, 0 files unresolved $ hg bisect -c./test.sh Bug! Changeset 6: f: bad No bug! Changeset 4:4207f3b7f4ee: good Bug! Changeset 5:538cc1eb311d: bad The first bad revision is: changeset: 5:538cc1eb311d date: Sat Dec 12 17:05: summary: y1 renamed to y2 $ rm test.sh 13 4 History The bug was introduced in changeset 5, where we renamed y1 to y2. In this example, we could have seen that by looking at the log, but it is usually not so simple to spot bugs. 14 Mercurial by Example 5 Diverging history Before we get into the next subject, let's add an extension to Mercurial that makes it easier to view history: the graphlog extension. Open (or create) the.hgrc file in your home directory. In the file to the right, a user name is given and the graphlog extension is enabled. Save the file and test the glog command: [ui] username = Thorbjorn Jemander [extensions] graphlog= The file ~/.hgrc $ hg glog o changeset: 10:07c3c9ade9e5 tip date: Sun Dec 13 13:15: summary: Adding new module a o changeset: 9:1c03fc41fe77 date: Sat Dec 12 17:46: summary: y2/c caused a chemical explosion. Going back to y2/b. o changeset: 8:6ff8f0a0aa98 date: Sat Dec 12 17:35: summary: D caused a thermonuclear explosion. Backed to C. o changeset: 7: a2 date: Sat Dec 12 17:31: summary: Let advance to experimental D version... If you see the ring-dotted line to the left you have successfully enabled the graphlog extension. There are several other extensions that one can enable, I'll give you some tips later on. Consider the following scenario. You have released R1.0 to the customer a while back (at revision 3), and now are working towards R2.0, and have done a lot of changes. You suddenly get a bug report from the customer on R1.0 and there's an urgent need for a correction. You're nowhere near releasing R2.0, so you need to work on R1.0. Let's see what happens if we go back in history and start working on R1.0 (changeset 3): $ hg update -r 3 # Go to revision 3 1 files updated, 0 files merged, 2 files removed, 0 files unresolved $ ls y1 z1 $ cat y1 B $ echo C y1 # We've fixed the bug by changing y1 $ hg ci -m fixed the R1.0 bug. created new head What? What does created new head mean? To cite the movie Back to the future , you have just created an alternative future or alternative time line . Instead of having one straight line from the 15 5 Diverging history first revision to the last, you now have two parallel lines starting at revision 3. To see what I mean, use graphlog: $ hg changeset: 11:47da354e2d4d tip parent: 3:c9d133e1c054 date: Tue Dec 15 22:14: summary: Fixed the R1.0 bug. o changeset: 10:07c3c9ade9e5 date: Sun Dec 13 13:15: summary: Adding new module a o changeset: 9:1c03fc41fe77 date: Sat Dec 12 17:46: summary: y2/c caused a chemical explosion. Going back to y2/b.... o changeset: 5:538cc1eb311d date: Sat Dec 12 17:05: summary: y1 renamed to y2 o changeset: 4:4207f3b7f4ee / date: Sat Dec 12 16:41: summary: Added tag my-x1-removal for changeset 3d8afaf1ac30 o changeset: 3:c9d133e1c054 date: Sat Dec 12 10:15: summary: Adding C to z1 and removing x2... You now have two heads, changeset 10 and 11. The parent of changeset 10 is 9, while the parent of revision 11 is 3. You have implicitly created a branch, a branch without a name. Their common ancestor is changeset Heads If you want to display the heads of your repository, use the heads command: $ hg heads changeset: 11:47da354e2d4d tip parent: 3:c9d133e1c054 date: Tue Dec 15 22:14: summary: Fixed the R1.0 bug. changeset: 10:07c3c9ade9e5 date: Sun Dec 13 13:15: summary: Adding new module a 16 Mercurial by Example 5.2 Merge You may have one, two or more heads. However, for practical reasons one should always try to have only one head. To merge the two branches, use the merge command: $ hg merge merging y1 and y2 to y2 2 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) $ hg ci -m merged R1.0-fix with pre-2.0 $ hg changeset: 12:90cf941b9def \ tip parent: 11:47da354e2d4d parent: 10:07c3c9ade9e5 date: Tue Dec 15 22:31: summary: Merged R1.0-fix with pre-2.0 o changeset: 11:47da354e2d4d parent: 3:c9d133e1c054 date: Tue Dec 15 22:14: summary: Fixed the R1.0 bug. o changeset: 10:07c3c9ade9e5 date: Sun Dec 13 13:15: summary: Adding new module a Now we're back at only having a single head again. Changeset 12 has two parents, 11 and Branching The proper way to do branching is to use the branch command, and then you get symbolic names for them, as well. The following sequence creates a R1.5 branch, originating from revision 7: $ hg up 7 # Go to revision files updated, 0 files merged, 1 files removed, 0 files unresolved $ hg branch R1.5 # and create branch R1.5 marked working directory as branch R1.5 $ hg ci -m created R1.5 branch created new head Note that these branches are not $ hg branches local, i.e. they will be exported to R1.5 13:a e5 other repositories when you start default 12:90cf941b9def to $ hg glog move changes changeset: 13:a e5 repositories. So don't use them branch: R1.5 for private development. tip parent: 7: a2 date: Tue Dec 15 22:39: summary: Created R1.5 branch o changeset: 12:90cf941b9def \ parent: 11:47da354e2d4d 17 5 Diverging history parent: 10:07c3c9ade9e5 date: Tue Dec 15 22:31: summary: Merged R1.0-fix with pre o changeset: 9:1c03fc41fe77 date: Sat Dec 12 17:46: summary: y2/c caused a chemical explosion. Going back to y2/b. o changeset: 8:6ff8f0a0aa98 / / date: Sat Dec 12 17:35: summary: D caused a thermonuclear explosion. Backed to C. o changeset: 7: a2 date: Sat Dec 12 17:31: summary: Let advance to experimental D version So, now again, we have two heads: 13 and 12. We can jump between branches by using branch names as arguments to the update command (just as tags and revision numbers): $ hg up default 2 files updated, 0 files merged, 0 files removed, 0 files unresolved $ hg up R1.5 1 files updated, 0 files merged, 1 files removed, 0 files unresolved $ hg branch # No argument gives us the branch name R1.5 Before we continue, let's close and merge the R1.5 branch so that we don't have multiple heads: 18 Mercurial by Example $ hg ci --close-branch -m
Related Search
We Need Your Support
Thank you for visiting our website and your interest in our free products and services. We are nonprofit website to share and download documents. To the running of this website, we need your help to support us.

Thanks to everyone for your continued support.

No, Thanks