Mercurial Tutorial
Mark Gates Nov 2016
1 Outline • Basic commands in single repository • Creating repo • Add & edit files • Viewing history • Fixing last commit • Multiple users / branches • Simple case • Merge without conflicts • Merge with conflicts • Bookmarks • Branches • BitBucket • Fork • Pull requests • Final thoughts
2 Overview of Mercurial • Distributed source control management • Each user has copy of entire repository hg • Commits go to local repo Chris Julia • Push & pull between repos • Similar to git
! server master server • We use central repo on BitBucket to synchronize • Nothing special about BitBucket repo! svn ! Chris Julia • Unlike svn, where all commits
go to server svn server
3 Help! • Extensive help • hg # basic commands • hg help [-v] # all commands • hg help command [-v] # specific command
>> hg Mercurial Distributed SCM >> hg help ! Mercurial Distributed SCM basic commands: ! >> hg help add ! hg add [OPTION]... [FILE]... list of commands: ! >> hg --version add add the specified files on the next commit ! Mercurial Distributed SCM (version 3.9.2) annotate show changeset information by line for each file add the specified files on the next commit add add the specified files on the next commit ! (see https://mercurial-scm.org for more information) clone make a copy of an existing repository addremove add all new files, delete all missing files ! commit commit the specified files or all outstanding changes Schedule files to be version controlled and added to the repository. annotate show changeset information by line for each file ! ! diff diff repository (or selected files) archive create an unversioned archive of a repository revision The files will be added to the repository at the next commit. To undo an ! export dump the header and diffs for one or more changesets backout reverse effect of earlier changeset ! forget forget the specified files on the next commit add before that, see 'hg forget'. bisect subdivision search of changesets ! ! init create a new repository in the given directory bookmarks create a new bookmark or list existing bookmarks ! ... options ([+] can be repeated): branch set or show the current branch name ! ! ! branches list repository named branches -I --include PATTERN [+] include names matching the given patterns ! (use "hg help" for the full list of commands or "hg -v" for details) bundle create a changegroup file -X --exclude PATTERN [+] exclude names matching the given patterns ! cat output the current or given revision of files -n --dry-run do not perform actions, just print output ! ... ! ! ! (some details hidden, use --verbose to show complete help)!
4 * throughout, output is abbreviated to fit on slides Configuration ~/.hgrc [ui] ignore = ~/.hgignore • User: ~/.hgrc ! ~/.hgignore [extensions] syntax: glob hgext.extdiff = ! • color = # latex output files Repo: .hg/hgrc shelve = *.aux ! *.bbl [extdiff] *.blg • Suggested items cmd.opendiff = fmdiff *.fff ! *.idx • ~/.hgignore hides files in [diff] *.log git = True *.marks hg status output ! *.nav # https://www.mercurial-scm.org/wiki/ColorExtension *.out • external diff (e.g., graphical) [color] *.snm status.ignored = black *.synctex.gz • git diff output nicer when status.modified = bold blue *.toc status.added = bold green ! renaming files status.removed = bold magenta # compiled files status.deleted = bold red *.a • status.unknown = black *.d color extension colors diff ! *.o diff.tab = red_background *.pyc and status output diff.trailingwhitespace = red_background*.so ! ! • shelve saves changes [alias] # hg backup files glog = log -G *.orig temporarily slog = log --template=short ! # misc files • alias to shorten commands .DS_Store
5 Creating repo
! • hg init [directory] • Creates repo directory (if needed) and .hg directory • By default uses current “.” directory
home> hg init recipes home> cd recipes/ recipes> ls -a ./ ../ .hg/
6 Adding files • hg add [files] • hg status [-acm] [-q] # hg st • -a added • -c clean pizza.txt Dough • -m modified 1 1/2 cups warm water (105 °F–115 °F) 1 package active dry yeast • -q quiet (hide unknown files) 3 1/2 cups bread flour 2 Tbsp olive oil 2 tsp salt • hg commit [-m “message”] 1 tsp sugar ! Toppings recipes> jedit pizza.txt 2/3 cup tomato sauce recipes> hg add pizza.txt 2/3 cup mozzarella cheese, grated recipes> hg st ! A pizza.txt # A = added Mix dough ingredients; knead for 10 minutes. ! Cover; rise until double, about 1–1 1/2 hours. recipes> hg commit -m 'start pizza’ Divide dough in half; roll out to 10–12 inches diameter. Spread with tomato sauce & sprinkle with toppings. Bake each at 450 °F for 10–15 minutes until golden.
7 Editing files • hg diff [files]
recipes> jedit pizza.txt pizza.txt recipes> hg st M pizza.txt # M = modified Dough ! 1.5 cups warm water (105 °F–115 °F) recipes> hg diff 1 package active dry yeast diff -r 9ab04aa4c434 pizza.txt 3.5 cups bread flour --- a/pizza.txt Tue Oct 25 07:58:39 2016 -0400 2 Tbsp olive oil +++ b/pizza.txt Tue Oct 25 08:03:53 2016 -0400 2 tsp salt @@ -1,7 +1,7 @@ 1 tsp sugar Dough ! -1 1/2 cups warm water (105 °F–115 °F) Toppings +1.5 cups warm water (105 °F–115 °F) 2/3 cup tomato sauce 1 package active dry yeast 2/3 cup mozzarella cheese, grated -3 1/2 cups bread flour +3.5 cups bread flour ! 2 Tbsp olive oil Mix dough ingredients; knead for 10 minutes. 2 tsp salt Cover; rise until double, about 1–1 1/2 hours. 1 tsp sugar Divide dough in half; roll out to 10–12 inches diameter. ! Spread with tomato sauce & sprinkle with toppings. recipes> hg commit -m 'use decimal' Bake each at 450 °F for 10–15 minutes until golden.
8 pizza.txt
History Dough 1.5 cups warm water (105 °F–115 °F) 1 package active dry yeast • hg diff -r revision 3.5 cups bread flour 2 Tbsp olive oil • Working files compared to that revision 2 tsp salt 1 tsp sugar ! • hg diff -c revision Toppings 2/3 cup tomato sauce • Changes that occurred in that revision 2/3 cup mozzarella cheese, grated 1/3 cup feta cheese, crumbled ! Mix dough ingredients; knead for 10 minutes. Cover; rise until double, about 1–1 1/2 hours. Divide dough in half; roll out to 10–12 inches recipes> hg diff -c 1 diameter. diff -r 9ab04aa4c434 -r 0b85839d8a57 pizza.txt Spread with tomato sauce & sprinkle with --- a/pizza.txt Tue Oct 25 07:58:39 2016 -0400 +++ b/pizza.txt Tue Oct 25 08:05:45 2016 -0400 @@ -1,7 +1,7 @@ recipes> hg diff Dough # or -1 1/2 cups warm water (105 °F–115 °F) recipes> hg diff -r 1 +1.5 cups warm water (105 °F–115 °F) diff -r 0b85839d8a57 pizza.txt 1 package active dry yeast --- a/pizza.txt Tue Oct 25 08:05:45 2016 -0400 -3 1/2 cups bread flour +++ b/pizza.txt Tue Oct 25 11:42:24 2016 -0400 +3.5 cups bread flour @@ -9,6 +9,7 @@ 2 Tbsp olive oil 2/3 cup tomato sauce 2 tsp salt 2/3 cup mozzarella cheese, grated 1 tsp sugar +1/3 cup feta cheese, crumbled @@ -11,7 +11,7 @@ 2/3 cup mozzarella cheese, grated Mix dough ingredients; knead for 10 minutes.
9 History recipes> hg log changeset: 1:0b85839d8a57 user: [email protected] • hg log [-l num] [-G] [--stat] date: Tue Oct 25 08:05:45 2016 -0400 summary: use decimal • -l limit to last num commits ! changeset: 0:9ab04aa4c434 user: [email protected] • -G graph date: Tue Oct 25 07:58:39 2016 -0400 • --stat show files changed summary: start pizza recipes> hg log --stat changeset: 1:0b85839d8a57 • commits identified 2 ways user: [email protected] date: Tue Oct 25 08:05:45 2016 -0400 • summary: use decimal Local version number ! (0, 1, 2, ...) pizza.txt | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-) • ! Local only! Different for changeset: 0:9ab04aa4c434 different users user: [email protected] date: Tue Oct 25 07:58:39 2016 -0400 summary: start pizza • Global unique hash ! pizza.txt | 17 +++++++++++++++++ (e.g., 0b85839d8a57) 1 files changed, 17 insertions(+), 0 deletions(-)
• Terminology: commits == revisions == changesets
10 History • Customizable log templates • hg log --template list # show available templates • Examples
• http://hgtip.com/tips/advanced/2010-01-15-styling-mercurials-cli/ • Custom
recipes> hg log --template=custom 9 5231fa16d647 2016-10-28 13:16 misc mgates3 default 8 b1047ddb7fca 2016-10-28 11:57 grind mgates3 sauce @7 90b0579b4629 2016-10-28 11:57 onion mgates3 sauce [*main] 6 83c38f1e80dd 2016-10-28 11:22 merge sauce mgates3 default 3,5 [saucier] 5 ff3b0aca8e36 2016-10-28 11:21 saute mgates3 sauce (v1.1) 4 f82b641f9506 2016-10-28 11:20 brand mgates3 sauce 3 1119625a9723 2016-10-28 11:20 preheat mgates3 default 2 d82ee94655b3 2016-10-28 11:19 meat mgates3 default (v1.0) 1 49bb5328310f 2016-10-28 11:19 start sauce mgates3 sauce 0 6ec9bb1d6c4c 2016-10-28 11:17 start pizza mgates3 default ! recipes> hg slog # alias in ~/.hgrc
11 Copy, move files • hg cp source destination [-A]
• hg mv source destination [-A] pizza.txt Dough veggie.txt recipes> hg cp pizza.txt veggie.txt 1.5 cups warm water (105 °F–115 °F) recipes> jedit veggie.txt 1 package active dry yeast 3.5 cupsDough bread flour recipes> hg st 1.5 cups warm water (105 °F–115 °F) A veggie.txt 2 Tbsp olive oil 2 tsp salt1 package active dry yeast ! 3.5 cups bread flour recipes> hg diff # git option in ~/.hgrc 1 tsp sugar 2 Tbsp olive oil diff --git a/pizza.txt b/veg.txt ! 2 tsp salt copy from pizza.txt Toppings 1 tsp sugar copy to veggie.txt 2/3 cup tomato sauce --- a/pizza.txt 2/3 cup! mozzarella cheese, grated +++ b/veggie.txt ! Toppings 2/3 cup mozzarella cheese, grated Mix dough2/3 cup ingredients tomato sauce; knead for 10 minutes. +1/2 cup bell peppers, thinly sliced Cover;2/3 rise cup until mozzarella double, about cheese, 1–1.5 grated hours. +1/2 cup chopped fresh basil Divide1/2 dough cup bell in half; peppers, roll out thinly to 10–12 sliced inches diameter. +1/2 cup onions, diced Spread1/2 with cup tomato chopped sauce fresh & basilsprinkle with toppings. ! Bake each1/2 cup at 450onions, °F for diced 10–15 minutes until golden. recipes> hg commit -m 'add veggie' ! Mix dough ingredients; knead for 10 minutes. Cover; rise until double, about 1–1.5 hours. Divide dough in half; roll out to 10–12 inches diameter. Spread with tomato sauce & sprinkle with toppings. Bake each at 450 °F for 10–15 minutes until golden.
12 Copy, move files • hg cp source destination [-A]
• hg mv source destination [-A] pizza.txt Dough veggie.txt recipes> hg mv pizza.txt veggie.txt 1.5 cups warm water (105 °F–115 °F) recipes> 1 package active dry yeast hg st Dough A veggie.txt # A = added 3.5 cups bread flour 1.5 cups warm water (105 °F–115 °F) R pizza.txt # R = removed 2 Tbsp olive oil 1 package active dry yeast recipes> hg commit -m 'rename to veggie' 2 tsp salt 1 tsp sugar3.5 cups bread flour 2 Tbsp olive oil recipes> mv pizza.txt veggie.txt ! Toppings2 tsp salt recipes> hg st 1 tsp sugar ! pizza.txt # ! = tracked file missing 2/3 cup! tomato sauce ? veggie.txt # ? = untracked file 2/3 cup mozzarella cheese, grated Toppings recipes> ! hg mv pizza.txt veggie.txt -A 2/3 cup tomato sauce recipes> hg st Mix dough ingredients; knead for 10 minutes. Cover;2/3 rise cup until mozzarella double, about cheese, 1–1.5 grated hours. A veggie.txt 1/2 cup bell peppers, thinly sliced R pizza.txt Divide dough in half; roll out to 10–12 inches diameter. 1/2 cup chopped fresh basil recipes> Spread with tomato sauce & sprinkle with toppings. hg commit -m 'rename to veggie' 1/2 cup onions, diced Bake each! at 450 °F for 10–15 minutes until golden. Mix dough ingredients; knead for 10 minutes. Cover; rise until double, about 1–1.5 hours. Divide dough in half; roll out to 10–12 inches diameter. Spread with tomato sauce & sprinkle with toppings. Bake each at 450 °F for 10–15 minutes until golden.
13 Remove files • hg rm files [-f] [-A]
pizza.txt
recipes> hg rm veggie.txt Dough veggie.txt recipes> hg st 1.5 cups warm water (105 °F–115 °F) R veggie.txt 1 package active dry yeast recipes> hg commit -m 'remove veggie' 3.5 cupsDough bread flour 2 Tbsp1.5 olive cups oil warm water (105 °F–115 °F) recipes> rm veggie.txt 2 tsp salt1 package active dry yeast recipes> hg st 1 tsp sugar3.5 cups bread flour ! veggie.txt ! 2 Tbsp olive oil recipes> hg rm veggie.txt [-A] Toppings2 tsp salt recipes> hg st 2/3 cup1 tsp tomato sugar sauce R veggie.txt 2/3 cup! mozzarella cheese, grated recipes> hg commit -m 'remove veggie' ! Toppings Mix dough2/3 cup ingredients tomato sauce; knead for 10 minutes. recipes> jedit veggie.txt Cover;2/3 rise cup until mozzarella double, about cheese, 1–1.5 grated hours. recipes> hg st Divide1/2 dough cup bellin half; peppers, roll out thinly to 10–12 sliced inches diameter. M veggie.txt Spread1/2 with cup tomato chopped sauce fresh & sprinklebasil with toppings. recipes> hg rm veggie.txt Bake each1/2 cup at 450 onions, °F for diced 10–15 minutes until golden. not removing veggie.txt: file is modified (use -f to force removal) ! recipes> hg rm veggie.txt -f Mix dough ingredients; knead for 10 minutes. recipes> hg st Cover; rise until double, about 1–1.5 hours. R veggie.txt Divide dough in half; roll out to 10–12 inches diameter. recipes> hg commit -m 'remove veggie' Spread with tomato sauce & sprinkle with toppings. Bake each at 450 °F for 10–15 minutes until golden.
14 Reverting changes veggie.txt • hg revert files Dough 1.5 cups warmsupreme.txt water (105 °F–115 °F) recipes> hg cp pizza.txt supreme.txt 1 package active dry yeast recipes> Dough 3.5 cups bread flour hg rm veggie.txt pizza.txt recipes> jedit pizza.txt 1.5 cups warm2 Tbsp water olive (105 oil °F–115 °F) recipes> hg st 1 package active2 tsp salt dry yeast TeigDough M pizza.txt 3.5 cups bread1 tsp flour sugar 1,51.5 Tassencups warm warmes water Wasser (105 °F–115 (105 ° F-115°F) ° F) A supreme.txt 2 Tbsp olive! oil 1 Packungpackage activeaktive dry Trockenhefe yeast R veggie.txt 2 tsp salt Toppings ! 1 tsp3,53.5 sugar Tassencups2/3 bread cupBrotmehl tomatoflour sauce 2 ELTbsp Olivenöl olive oil recipes> hg revert pizza.txt ! 2/3 cup mozzarella cheese, grated 2 TLtsp Salzsalt recipes> hg st Toppings 1/2 cup bell peppers, thinly sliced 1 TLtsp Zuckersugar A supreme.txt 2/3 cup tomato1/2 cup sauce chopped fresh basil R veggie.txt 2/3 cup! mozzarella1/2 cup onions, cheese, diced grated ! italianToppings sausage,! cooked recipes> hg revert . # “.” directory mushrooms,2/3 TassecupMix thinlytomato Tomatensoße dough sliced sauce ingredients; knead for 10 minutes. forgetting supreme.txt bell peppers,2/3 TassecupCover; mozzarellathinly Mozzarella, rise sliced until cheese, geriebendouble, grated about 1–1.5 hours. undeleting veggie.txt chopped! freshDivide basil dough in half; roll out to 10–12 inches diameter. ! pestoMix TeigdoughSpread Zutaten; ingredients with 10 tomato Minuten; knead sauce kneten.for & 10 sprinkle minutes. with toppings. recipes> hg st pepporoniAbdeckung;Cover; Bake rise untileach Steigen atdouble, 450 bis °F doppelt, about for 10–15 1–1.5 ca. minutes 1-1,5hours. Stunden. until golden. ? supreme.txt onions,TeigDivide diced in derdough Hälfte in half; teilen; roll Roll-out out to 10–12 bis 10-12 inches Zoll diameter. Durchmesser. ! ham,MitSpread diced Tomatensauce with tomato bestreichen sauce & sprinkle und mit with Toppings toppings. bestreuen. recipes> ls -1 ! BackenBake each Sie at jeweils 450 °F bei for 450 10–15 ° F minutesfür 10-15 until Minuten, golden. bis golden. pizza.txt Mix dough ingredients; knead for 10 minutes. pizza.txt.orig # backup Cover; rise until double, about 1–1.5 hours. supreme.txt # backup Divide dough in half; roll out to 10–12 inches diameter. veggie.txt Spread with tomato sauce & sprinkle with toppings. Bake each at 450 °F for 10–15 minutes until golden.
15 Fixing last commit (only last!)
• hg rollback pizza.txt Dough recipes> jedit veggie.txt 1.5 cups warm H20 (105 °F–115 °F) recipes> jedit pizza.txt 1 package active dry yeast recipes> 3.5 cups bread flour hg st veggie.txt M pizza.txt 2 Tbsp olive oil M veggie.txt 2 tsp salt Dough recipes> hg commit -m 'H20' 1 tsp sugar 1.5 cups warm H20 (105 °F–115 °F) recipes> hg log -l 2 ! 1 package active dry yeast changeset: 5:22456188656d Toppings 3.5 cups bread flour tag: tip 2/3 cup tomato sauce 2 Tbsp olive oil summary: H20 2/3 cup mozzarella cheese, grated ! ! 2 tsp salt changeset: 4:7a81b46fbf59 Mix dough1 tsp sugar ingredients ; knead for 10 minutes. summary: rename to veggie Cover;! rise until double, about 1–1.5 hours. ! DivideToppings dough in half; roll out to 10–12 inches diameter. recipes> hg rollback Spread2/3 with cup tomatotomato saucesauce & sprinkle with toppings. repository tip rolled back to revision 4 (undo commit) Bake2/3 each cup at 450mozzarella °F for 10–15 cheese, minutes grated until golden. working directory now based on revision 4 1/2 cup bell peppers, thinly sliced ! 1/2 cup chopped fresh basil recipes> hg log -l 2 1/2 cup onions, diced changeset: 4:7a81b46fbf59 ! tag: tip Mix dough ingredients; knead for 10 minutes. summary: rename to veggie Cover; rise until double, about 1–1.5 hours. ! Divide dough in half; roll out to 10–12 inches diameter. recipes> hg st Spread with tomato sauce & sprinkle with toppings. M pizza.txt Bake each at 450 °F for 10–15 minutes until golden. M veggie.txt
16 Fixing last commit (only last!) • hg commit --amend • Destroys rollback information • Changes global hash identifier, but not date • Can change message
recipes> jedit veggie.txt recipes> hg commit --amend veggie.txt recipes> jedit pizza.txt saved backup bundle to /Users/mgates/Documents/ recipes> hg st writing/2016/mercurial/recipes/.hg/strip-backup/ M pizza.txt 167f86be8569-954506e9-amend-backup.hg M veggie.txt ! recipes> hg commit -m 'H20' pizza.txt recipes> hg st recipes> hg st recipes> M veggie.txt ! ! ! recipes> hg log -l 1 --stat recipes> hg log -l 1 --stat changeset: 5:167f86be8569 changeset: 5:65d210f5f675 tag: tip tag: tip date: Tue Oct 25 11:01:21 2016 -0400 date: Tue Oct 25 11:01:21 2016 -0400 summary: H20 summary: H20 ! ! pizza.txt | 2 +- pizza.txt | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) veggie.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
17 Outline • Basic commands in single repository • Creating repo • Add & edit files • Viewing history • Fixing last commit • Multiple users / branches • Simple case • Merge without conflicts • Merge with conflicts • Bookmarks • Branches • BitBucket • Fork • Pull requests • Final thoughts
18 3 kinds of branches • Forks (or clones) — copies of repo • Every copy is a fork! You cannot avoid branching! • Typically for development; periodically synchronize • Same as git forking • Bookmarks • Typically short-lived for feature development • Same as git’s branches • Named branches • Typically long-lived branches like “stable” and “devel” • Branch name permanently recorded in commit log
19 Simple example — one person editing at a time
20 Basic server interaction • Simple example with only one person editing at a time • hg clone url [directory] Chris Julia
• hg push [url] update commit • hg pull [url] [-u] pull push • hg update # hg up server
Server: 0 1 2 3
clone push pull
Chris: 0: pizza 1: feta 2 3
clone push
Julia: 0 1 2: meat 3: preheat
21 dashed lines are copies solid lines are dependencies Basic server interaction
home> hg clone ssh://server/recipes chris home> cd chris chris> ls -a ./ ../ .hg/
.hg/hgrc
[paths] default = ssh://server/recipes
Server:
clone Chris:
Julia:
22 dashed lines are copies solid lines are dependencies Basic server interaction
home> hg clone ssh://server/recipes chris pizza.txt home> cd chris ! Dough pizza.txt chris> jedit pizza.txt 1 1/2 cups warm water (105 °F–115 °F) chris> hg commit -m ‘start pizza' 1 packageDough active dry yeast chris> jedit pizza.txt 3 1/21 cups 1/2 breadcups warm flour water (105 °F–115 °F) chris> hg commit -m ‘feta' 2 Tbsp1 packageolive oil active dry yeast chris> hg push 2 tsp 3salt 1/2 cups bread flour pushing to ssh://server/recipes 1 tsp 2sugar Tbsp olive oil mercurial/recipes ! 2 tsp salt searching for changes Toppings1 tsp sugar adding changesets 2/3 cup! tomato sauce adding manifests 2/3 cup mozzarella cheese, grated adding file changes ! Toppings added 2 changesets with 2 changes to 1 files 2/3 cup tomato sauce Mix dough2/3 cup ingredients mozzarella; knead cheese, for grated 10 minutes. Cover;1/3 rise cup until feta double, cheese, about crumbled 1–1 1/2 hours. Divide! dough in half; roll out to 10–12 inches diameter. SpreadMix with dough tomato ingredients sauce & ;sprinkle knead for with 10 minutes.toppings. Bake each at 450 °F for 10–15 minutes until golden. Server: 0 1 Cover; rise until double, about 1–1 1/2 hours. Divide dough in half; roll out to 10–12 inches diameter. Spread with tomato sauce & sprinkle with toppings. clone push Bake each at 450 °F for 10–15 minutes until golden. Chris: 0: pizza 1: feta
Julia:
23 dashed lines are copies solid lines are dependencies Basic server interaction
home> hg clone ssh://server/recipes julia pizza.txt home> cd julia ! Dough pizza.txt julia> jedit pizza.txt 1 1/2 cups warm water (105 °F–115 °F) julia> hg commit -m ‘meat' 1 package active dry yeast Dough julia> hg commit -m ‘preheat' 3 1/2 cups bread flour 1 1/2 cups warm water (105 °F–115 °F) julia> hg push 2 Tbsp olive oil 1 package active dry yeast pushing to ssh://server/recipes 2 tsp salt 3 1/2 cups bread flour searching for changes 1 tsp sugar adding changesets ! 2 Tbsp olive oil 2 tsp salt adding manifests Toppings 1 tsp sugar adding file changes 2/3 cup tomato sauce added 2 changesets with 2 changes to 1 files 2/3 cup! mozzarella cheese, grated Toppings 1/3 cup feta cheese, crumbled 2/3 cup tomato sauce 1/2 cup Italian sausage, cooked 2/3 cup mozzarella cheese, grated 1/4 cup pepperoni ! 1/3 cup feta cheese, crumbled 1/2 cup Italian sausage, cooked Mix dough ingredients; knead for 10 minutes. 1/4 cup pepperoni Cover; rise until double, about 1–1 1/2 hours. 0 1 2 3 Server: Divide! dough in half; roll out to 10–12 inches diameter. Mix dough ingredients; knead for 10 minutes. Spread with tomato sauce & sprinkle with toppings. Cover; rise until double, about 1–1 1/2 hours. clone push Bake each at 450 °F for 10–15 minutes until golden. Preheat oven to 450 °F. Chris: 0: pizza 1: feta Divide dough in half; roll out to 10–12 inches diameter. Spread with tomato sauce & sprinkle with toppings. Bake each at 450 °F for 10–15 minutes until golden. clone push
Julia: 0 1 2: meat 3: preheat
24 dashed lines are copies solid lines are dependencies Basic server interaction
chris> hg pull chris> hg pull -u pulling from ssh://server/recipes pulling from ssh://server/recipes searching for changes searching for changes adding changesets adding changesets adding manifests – or – adding manifests adding file changes adding file changes added 2 changesets with 2 changes to 1 files added 2 changesets with 2 changes to 1 files pizza.txt (run 'hg update' to get a working copy) 1 files updated, 0 files merged, 0 files removed, 0 files unresolved Dough pizza.txt Note that working copy not yet updated! 1 1/2 cups warm water (105 °F–115 °F) 1 packageDough active dry yeast 3 1/2 cups bread flour chris> hg up 1 1/2 cups warm water (105 °F–115 °F) 2 Tbsp olive oil 1 files updated, 0 files merged, 0 files 1 package active dry yeast removed, 0 files unresolved 2 tsp salt3 1/2 cups bread flour 1 tsp sugar2 Tbsp olive oil ! 2 tsp salt Toppings1 tsp sugar 2/3 cup! tomato sauce 2/3 cup mozzarella cheese, grated Server: 0 1 Toppings 2 3 1/3 cup2/3 feta cup cheese, tomato crumbled sauce ! 2/3 cup mozzarella cheese, grated clone push pull Mix dough1/3 cup ingredients feta cheese,; knead crumbled for 10 minutes. Cover;1/2 rise cup until Italian double, sausage, about cooked 1–1 1/2 hours. 0: pizza 1: feta 2 3 Chris: Divide1/4 dough cup pepperoni in half; roll out to 10–12 inches diameter. Spread! with tomato sauce & sprinkle with toppings. clone Bake eachMix doughat 450 °F ingredients; forpush 10–15 minutes knead for until 10 minutes.golden. Cover; rise until double, about 1–1 1/2 hours. Julia: 0 1 Preheat2: meat oven to3: 450 preheat °F. Divide dough in half; roll out to 10–12 inches diameter. Spread with tomato sauce & sprinkle with toppings. 25 dashed lines are copies solid lines are dependenciesBake each at 450 °F for 10–15 minutes until golden. Simple merge — two simultaneous edits, without conflicts
26 Merge without conflicts • Merge is required if edits happen in parallel • Local commit numbers differ • hg merge
4: veg Server: 0:3 6: merge 5: ham
push pull
4: veg Chris: 0:3 6: merge 5: ham
push pull push
5: veg Julia: 0:3 6: merge 4: ham
27 dashed lines are copies solid lines are dependencies Merge pizza.txt
Dough chris> jedit pizza.txt pizza.txt chris> hg commit -m ‘veggies' 1 1/2 cups warm water (105 °F–115 °F) 1 package active dry yeast chris> hg push Dough 3 1/2 cups bread flour 1 1/2 cups warm water (105 °F–115 °F) 2 Tbsp olive oil julia> jedit pizza.txt 1 package active dry yeast 2 tsp salt julia> hg commit -m ‘ham' 3 1/2 cups bread flour 1 tsp sugar julia> hg push 2 Tbsp olive oil pushing to ssh://server/recipes ! 2 tsp salt Toppings searching for changes 1 tsp sugar remote has heads on branch 'default' that are not known locally: 7dc71c9ebfc4 2/3 cup! tomato sauce 2/3 cup mozzarella cheese, grated abort: push creates new remote head c7f726f74e9a! Toppings (pull and merge or see "hg help push" for details about pushing new heads)1/3 cup feta cheese, crumbled 2/3 cup tomato sauce 1/4 cup mushrooms, thinly sliced 2/3 cup mozzarella cheese, grated 1/4 cup bell peppers, thinly sliced 1/3 cup feta cheese, crumbled 1/2 cup Italian sausage, cooked 4: veg 1/2 cup Italian sausage, cooked 1/4 cup pepperoni Server: 0:3 1/4 cup pepperoni ! 1/4 cup ham Mix dough! ingredients; knead for 10 minutes. Cover; rise until double, about 1–1 1/2 hours. push Mix dough ingredients; knead for 10 minutes. Preheat oven to 450 °F. Cover; rise until double, about 1–1 1/2 hours. Divide dough in half; roll out to 10–12 inches diameter. 4: veg Preheat oven to 450 °F. 0:3 Chris: Divide dough in half; roll out to 10–12 inches diameter. Spread with tomato sauce & sprinkle with toppings.
push
Julia: 0:3 4: ham
28 dashed lines are copies solid lines are dependencies Merge
julia> hg pull julia> hg merge pulling from ssh://server/recipes merging pizza.txt searching for changes 0 files updated, 1 files merged, 0 files removed, 0 files unresolved adding changesets (branch merge, don't forget to commit) adding manifests adding file changes added 1 changesets with 1 changes to 1 files (+1 heads) (run 'hg heads' to see heads, 'hg merge' to merge) ! julia> hg up # warning, does nothing 0 files updated, 0 files merged, 0 files removed, 0 files unresolved 1 other heads for branch "default"
4: veg Server: 0:3
push
4: veg Chris: 0:3
push pull
5: veg Julia: 0:3 6: merge 4: ham
29 dashed lines are copies solid lines are dependencies Merge — verify & commit!
julia> hg heads julia> hg diff -r 5 changeset: 5:962db491f9ca @@ -14,7 +14,6 @@ summary: veggies 1/2 cup Italian sausage, cooked ! 1/4 cup pepperoni changeset: 4:b1473e48944e +1/4 cup ham summary: ham ! ! julia> hg commit -m ‘merge' julia> hg diff -r 4 julia> hg push # optional @@ -10,8 +10,6 @@ pushing to ssh://server/recipes 1/3 cup feta cheese, crumbled searching for changes +1/4 cup mushrooms, thinly sliced adding changesets +1/4 cup bell peppers, thinly sliced adding file changes 1/2 cup Italian sausage, cooked added 2 changesets with 2 changes to 1 files
4: veg Server: 0:3 6: merge 5: ham
push
4: veg Chris: 0:3
push pull push
5: veg Julia: 0:3 6: merge 4: ham
30 dashed lines are copies solid lines are dependencies Merge
chris> hg pull pulling from /Users/mgates/Documents/writing/2016/mercurial/recipes searching for changes adding changesets adding manifests adding file changes added 2 changesets with 2 changes to 1 files (run 'hg update' to get a working copy) ! chris> hg up 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
4: veg Server: 0:3 6: merge 5: ham
push pull
4: veg Chris: 0:3 6: merge 5: ham
push pull push
5: veg Julia: 0:3 6: merge 4: ham
31 dashed lines are copies solid lines are dependencies Conflict merge — two simultaneous edits to same text
32 Merge with conflict • Simplify recipe slightly, then add ingredients in same spot
pizza.txt
Dough 1 1/2 cupspizza.txt warm water (105 °F–115 °F) pizza.txt 1 package active dry yeast 3 1/2 cupsDough bread flour Dough 2 Tbsp olive1 1/2 oil cups warm water (105 °F–115 °F) 1 1/2 cups warm water (105 °F–115 °F) 2 tsp salt1 package active dry yeast 1 package active dry yeast 1 tsp sugar3 1/2 cups bread flour 3 1/2 cups bread flour ! 2 Tbsp extra virgin olive oil 2 Tbsp olive oil Toppings2 tsp sea salt 2 tsp salt 2/3 cup1 tomato tsp sugar sauce 1 tsp sugar 2/3 cup! mozzarella cheese, grated ! 1/2 cupToppings Italian sausage, cooked Toppings ! 2/3 cup tomato sauce 2/3 cup tomato sauce Mix dough2/3 ingredients;cup mozzarella knead cheese, for 10 grated minutes. 2/3 cup mozzarella cheese, grated Cover; rise1/2 cupuntil bell double, peppers, about thinly 1–1 1/2 sliced hours. 1/4 cup mushrooms, sliced Preheat 1/3oven cup to mushrooms450 °F. 1/4 cup onions, diced Divide dough1/2 cup in Italian half; roll sausage, out to cooked10–12 inches diameter. 1/2 cup Italian sausage, cooked Spread with! tomato sauce & sprinkle with toppings. ! Bake eachMix at dough450 °F ingredients;for 10–15 minutes knead until for 10 golden. minutes. Mix dough ingredients; knead for 10 minutes. Cover; rise until double, about 1–1 1/2 hours. Cover; rise until double, about 1–1 1/2 hours. Preheat oven to 450 °F. Preheat oven to 450 °F. Divide dough in half; roll out to 10–12 inches diameter. Divide dough in half; spin in air to 10–12 inches diameter. Spread with tomato sauce & sprinkle with toppings. Spread with tomato sauce & sprinkle with toppings. Bake each at 450 °F for 10–15 minutes until golden. Bake each at 450 °F for 10–15 minutes until golden.
33 Merge with conflict: graphical • Graphical diff (here, Apple’s FileMerge, i.e., opendiff)
• Non-conflicting julia> hg merge merging pizza.txt portions merged 0 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) automatically • Manually resolve conflicting portions • Choose left, right, both, or neither • See & edit final text in bottom pane • Save file & quit
34 Incoming Your code code
Merged code
35 Incoming Your code code
Merged code
36 • Save file & quit Merge with conflict: verify & commit!
julia> hg heads julia> hg diff -r 9 changeset: 9:f41d23390194 1/2 cup bell peppers, thinly sliced summary: peppers -1/3 cup mushrooms ! +1/3 cup mushrooms, sliced changeset: 8:791c8abf0a1d +1/4 cup onions, diced summary: onions 1/2 cup Italian sausage, cooked ! ! julia> hg diff -r 8 Preheat oven to 450 °F. 3 1/2 cups bread flour -Divide dough in half; roll out to 10–12 inches diameter. -2 Tbsp olive oil +Divide dough in half; spin in air to 10–12 inches diameter. -2 tsp salt Spread with tomato sauce & sprinkle with toppings. +2 Tbsp extra virgin olive oil ! +2 tsp sea salt julia> hg commit -m ‘merge’ 1 tsp sugar ! 2/3 cup mozzarella cheese, grated -1/4 cup mushrooms, sliced +1/2 cup bell peppers, thinly sliced +1/3 cup mushrooms, sliced 1/4 cup onions, diced
37 Merge with conflict: manual • hg resolve [-l, -m, -u] [files] pizza.txt Dough • -l list resolved status 1 1/2 cups warm water (105 °F–115 °F) 1 package active dry yeast • -m mark as resolved 3 1/2 cups bread flour 2 Tbsp extra virgin olive oil • -u mark as unresolved 2 tsp sea salt 1 tsp sugar julia> hg merge --tool internal:merge ! merging pizza.txt Toppings warning: conflicts while merging pizza.txt! (edit, then use 'hg resolve --mark') 2/3 cup tomato sauce 0 files updated, 0 files merged, 0 files removed, 1 files unresolved 2/3 cup mozzarella cheese, grated use 'hg resolve' to retry unresolved file merges or 'hg update -C .' to abandon <<<<<<< local ! 1/4 cup mushrooms, sliced julia> hg commit -m 'merge' 1/4 cup onions, diced abort: unresolved merge conflicts (see "hg help resolve") ======! 1/2 cup bell peppers, thinly sliced julia> hg resolve -l # list resolved status 1/3 cup mushrooms U pizza.txt # U = unresolved >>>>>>> other ! 1/2 cup Italian sausage, cooked julia> jedit pizza.txt ! julia> hg resolve -m pizza.txt # mark as resolved Mix dough ingredients; knead for 10 minutes. (no more unresolved files) ! julia> hg resolve -l R pizza.txt # R = resolved ! julia> hg commit -m ‘merge’
38 History • hg log -G # graph branches • hg glog # alias in ~/.hgrc
chris> hg log -G | @ changeset: 10:10ae7218a2bd o changeset: 6:800444945b16 |\ tag: tip |\ parent: 5:b1473e48944e | | parent: 9:791c8abf0a1d | | parent: 4:962db491f9ca | | parent: 8:f41d23390194 | | summary: merge | | summary: merge | | | | | o changeset: 5:b1473e48944e | o changeset: 9:791c8abf0a1d | | parent: 3:0f66f034fa18 | | parent: 7:1b946d5db238 | | summary: ham | | summary: onions | | | | o | changeset: 4:962db491f9ca o | changeset: 8:f41d23390194 |/ summary: veggies |/ summary: peppers | | o changeset: 3:0f66f034fa18 o changeset: 7:1b946d5db238 | summary: preheat | summary: basic | | o changeset: 2:7d60311ab431 . | summary: meat . | . o changeset: 1:92dafa80df69 ! | summary: feta | o changeset: 0:9ab04aa4c434 summary: start pizza
39 Solving merge problems
40 Fixing bad merge (option 1) • hg update --clean • Reverts all files to state before “hg merge” command
! julia> hg merge merging pizza.txt ! 2016-11-04 01:24:24.700 FileMerge[21657:d07] Invalid color System, labelColor (warning given only once) 0 files updated, 1 files merged, 0 files removed, 0 files unresolved ! (branch merge, don't forget to commit) ! ! # utter confusion entails! julia> hg up ! abort: outstanding uncommitted merge ! ! julia> hg st M pizza.txt ! ! julia> hg update --clean ! 1 files updated, 0 files merged, 0 files removed, 0 files unresolved 1 other heads for branch “default" ! ! julia> hg st julia> • Can then do “hg merge” again
41 Fixing bad merge (option 2) • Alternatively, redo merge of specific files • hg resolve -u files # mark files as unresolved • hg resolve files # re-merge files julia> hg merge merging pizza.txt 2016-11-04 01:26:51.567 FileMerge[21675:d07] Invalid color System, labelColor (warning given only once) 0 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) ! julia> hg resolve -l R pizza.txt # R = resolved julia> hg resolve -u pizza.txt julia> hg resolve -l U pizza.txt # U = unresolved ! julia> hg resolve pizza.txt merging pizza.txt 2016-11-04 01:28:11.805 FileMerge[21690:d07] Invalid color System, labelColor (warning given only once) (no more unresolved files) julia> hg st M pizza.txt julia> hg commit -m 'merge'
42 Merge with uncommitted changes
recipes> hg st • hg won’t merge if there M pizza.txt ! are uncommitted changes recipes> hg merge abort: uncommitted changes (use 'hg status' to list changes) • Either commit them, ! recipes> hg shelve -n peppers shelved as peppers or shelve them temporarily 1 files updated, 0 files merged, 0 files removed, 0 files unresolved ! • hg shelve [-n name] [-l] recipes> hg st recipes> hg shelve -l peppers (4s ago) changes to: meat • hg unshelve [name] ! recipes> hg merge merging pizza.txt • Extension in ~/.hgrc 0 files updated, 1 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) ! recipes> hg commit -m 'merge' ! recipes> hg unshelve [peppers] ! unshelving change 'peppers' rebasing shelved changes rebasing 4:8be446f41b74 "changes to: meat" (tip) merging pizza.txt • (Similar to git stash) recipes> hg st M pizza.txt
43 Bookmarks
44 Branching with Bookmarks main • Bookmark is label that 15: merge main sauce tracks head of a branch 13: spin 14: chop main sauce • Add, delete, and rename 12: ham 11: merge at any time sauce main 10: peel 8: parm. sauce • Typically for short-lived main 9: onion feature or bug-fix branches 7: merge main sauce • Essentially same as git’s 5: preheat 6: sauté sauce branches 3: brand main sauce 4: meat 2: sauce sauce main 1: feta
0: pizza
45 Branching with Bookmarks • hg bookmark[s] # lists bookmarks • hg bookmark name # creates bookmark • hg update name # updates working copy to bookmark
recipes> jedit pizza.txt recipes> hg add pizza.txt recipes> hg commit -m 'pizza' ! recipes> jedit pizza.txt recipes> hg commit -m 'feta' ! recipes> hg bookmark main recipes> hg bookmark sauce recipes> hg bookmarks main 1:a1f2a82ea6e0 * sauce 1:a1f2a82ea6e0 sauce main 1: feta
0: pizza
46 Branching with Bookmarks recipes> jedit sauce.txt recipes> hg add sauce.txt recipes> hg commit -m 'sauce' ! recipes> jedit sauce.txt recipes> hg commit -m 'brand' recipes> ls pizza.txt sauce.txt ! recipes> hg slog -G @ @3 brand default [*sauce] (tip) | o 2 sauce default | o 1 feta default [main] | o 0 pizza default sauce 3: brand sauce 2: sauce sauce main 1: feta
0: pizza
47 Branching with Bookmarks recipes> hg up main 0 files updated, 0 files merged, 1 files removed, 0 files unresolved (activating bookmark main) recipes> ls pizza.txt ! recipes> jedit pizza.txt recipes> hg commit -m 'meat' created new head ! recipes> hg commit -m 'preheat' recipes> hg slog -G @ @5 preheat default [*main] (tip) | o 4 meat default main | 5: preheat | o 3 brand default [sauce] | | sauce | o 2 sauce default 3: brand |/ o 1 feta default main | 4: meat 2: sauce o 0 pizza default main 1: feta
0: pizza
48 Branching with Bookmarks recipes> hg up sauce 2 files updated, 0 files merged, 0 files removed, 0 files unresolved (activating bookmark sauce) recipes> hg slog -G o 5 preheat default [main] | o 4 meat default | | @ @3 brand default [*sauce] | | | o 2 sauce default |/ o 1 feta default | o 0 pizza default ! main sauce recipes> jedit sauce.txt 5: preheat 6: sauté recipes> hg commit -m 'saute' recipes> hg slog -G sauce @ @6 saute default [*sauce] 3: brand | | o 5 preheat default [main] | | 4: meat 2: sauce | o 4 meat default | | o | 3 brand default 1: feta | | o | 2 sauce default 0: pizza |/ o 1 feta default | o 0 pizza default 49 Branching with Bookmarks recipes> hg up main 1 files updated, 0 files merged, 1 files removed, 0 files unresolved (activating bookmark main) recipes> hg slog -G o 6 saute default [sauce] | | @ @5 preheat default [*main] | | ! recipes> hg merge sauce 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) main recipes> st 7: merge M sauce.txt recipes> hg commit -m 'merge sauce' main sauce recipes> hg slog -G 5: preheat 6: sauté @ @7 merge sauce default 5,6 [*main] |\ | o 6 saute default [sauce] 3: brand | | o | 5 preheat default | | 4: meat 2: sauce o | 4 meat default | | | o 3 brand default 1: feta | | | o 2 sauce default |/ 0: pizza o 1 feta default | o 0 pizza default 50 Branching with Bookmarks recipes> hg bookmark * main 7:92bf22ea6bd9 sauce 6:058a19c7aec7 recipes> jedit pizza.txt recipes> hg commit -m 'parmesan' ! recipes> hg up sauce 1 files updated, 0 files merged, 0 files removed, 0 files unresolved sauce (activating bookmark sauce) 10: peel recipes> jedit sauce.txt main 8: parm. recipes> hg commit -m 'onion' sauce created new head 9: onion ! main 7: merge recipes> hg commit -m 'peeled' recipes> hg slog -G sauce @ @10 peeled default [*sauce] 5: preheat 6: sauté | o 9 onion default | 3: brand | o 8 parmesan default [main] | | | o 7 merge sauce default 5,6 4: meat 2: sauce |/| o | 6 saute default | | 1: feta | o 5 preheat default | | | o 4 meat default 0: pizza | |
51 Branching with Bookmarks recipes> hg merge main 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) recipes> hg st M pizza.txt sauce recipes> hg commit -m 'merge main' 11: merge recipes> hg slog -G @ @11 merge main default 10,8 [*sauce] sauce |\ 10: peel | o 10 peeled default main | | 8: parm. | o 9 onion default 9: onion | | o | 8 parmesan default [main] 7: merge | | o | 7 merge sauce default 5,6 |\| 5: preheat 6: sauté | o 6 saute default | | o | 5 preheat default 3: brand | | o | 4 meat default | | 4: meat 2: sauce | o 3 brand default | | | o 2 sauce default 1: feta |/ o 1 feta default | 0: pizza o 0 pizza default
52 Branching with Bookmarks recipes> hg up main main 1 files updated, 0 files merged, 15: merge 0 files removed, 0 files unresolved (activating bookmark main) main sauce ! 13: spin 14: chop recipes> jedit pizza.txt main sauce recipes> hg commit -m 'ham' 12: ham 11: merge created new head ! recipes> jedit pizza.txt 10: peel recipes> hg commit -m 'spin' main ! 8: parm. recipes> hg up sauce 9: onion 2 files updated, 0 files merged, 7: merge 0 files removed, 0 files unresolved (activating bookmark sauce) recipes> jedit sauce.txt 5: preheat 6: sauté recipes> hg commit -m 'chop' ! recipes> hg up main 3: brand 2 files updated, 0 files merged, 0 files removed, 0 files unresolved (activating bookmark main) 4: meat 2: sauce ! recipes> hg merge sauce 1 files updated, 0 files merged, 1: feta 0 files removed, 0 files unresolved (branch merge, don't forget to commit) recipes> hg commit -m 'merge sauce' 0: pizza
53 Branching with Bookmarks recipes> hg bookmark --delete sauce main 15: merge recipes> hg slog -G @ @15 merge sauce default 13,14 [*main] sauce |\ 13: spin 14: chop | o 14 chop default | | o | 13 spin default 12: ham 11: merge | | o | 12 ham default | | 10: peel | o 11 merge main default 10,8 |/| 8: parm. | o 10 peeled default 9: onion | | | o 9 onion default 7: merge | | o | 8 parmesan default | | 5: preheat 6: sauté o | 7 merge sauce default 5,6 |\| | o 6 saute default 3: brand | | o | 5 preheat default | | 4: meat 2: sauce o | 4 meat default | | | o 3 brand default 1: feta | | | o 2 sauce default |/ 0: pizza o 1 feta default | o 0 pizza default 54 Pushing bookmarks • hg doesn’t push new bookmarks by default • hg push {--bookmark|-B} bookmark
recipes> hg push pushing to server searching for changes abort: push creates new remote head 42ca2b91c349 with bookmark 'sauce'! (merge or see "hg help push" for details about pushing new heads) ! recipes> hg push --bookmark main # or -B pushing to ../c2 searching for changes adding changesets adding manifests adding file changes added 2 changesets with 2 changes to 1 files exporting bookmark main ! recipes> hg push --bookmark sauce # or -B pushing to ../c2 searching for changes adding changesets adding manifests adding file changes added 2 changesets with 2 changes to 1 files (+1 heads) exporting bookmark sauce
55 Merging divergent bookmarks • Chris & Julia both make changes in sauce branch, Julia pulls in new head as sauce@default
julia> hg pull -u julia> hg merge pulling from server abort: no matching bookmark to merge - please searching for changes merge with an explicit rev or bookmark adding changesets (run 'hg heads' to see all heads) adding manifests ! adding file changes julia> hg up sauce added 1 changesets with 1 changes to 1 files (+1 heads) 2 files updated, 0 files merged, 0 files divergent bookmark sauce stored as sauce@default removed, 0 files unresolved 0 files updated, 0 files merged, (activating bookmark sauce) 0 files removed, 0 files unresolved ! 1 other divergent bookmarks for "sauce" julia> hg bookmarks ! main 4:8f439fe17062 julia> hg heads * sauce 12:4d0841e8279d changeset: 10:207f29b01f7b sauce@default 13:bd2c99f8da7f bookmark: sauce@default ! parent: 8:b6b112e27e33 julia> hg merge summary: finely merging sauce.txt ! 0 files updated, 1 files merged, 0 files changeset: 9:566cd34821bc removed, 0 files unresolved bookmark: sauce (branch merge, don't forget to commit) summary: vidalia ! ! julia> hg commit -m 'merge' changeset: 2:8f439fe17062 bookmark: main summary: pepperoni
56 Named Branches
57 Branching with Named Branches default • Branch is permanent name 15: merge default sauce attached to each commit 13: spin 14: chop default sauce • “default” branch 12: ham 11: merge sauce • Typically for long-lived default 10: peel 8: parm. sauce branches like “stable” and default 9: onion “devel” 7: merge default sauce • Operate similarly to 5: preheat 6: sauté sauce bookmarks 3: brand default sauce 4: meat 2: sauce default 1: feta default 0: pizza
58 Branching with Named Branches • hg branches # lists branches • hg branch name # creates branch • hg update name # updates working copy to branch • hg commit --close-branch [-m “message”]
recipes> jedit pizza.txt recipes> hg add pizza.txt recipes> hg commit -m pizza ! recipes> jedit pizza.txt recipes> hg commit -m feta ! recipes> hg branch sauce marked working directory as branch sauce (branches are permanent and global, did you want a bookmark?) default ! 1: feta recipes> hg branches # new branch not yet visible default 1:98b3df1d5afe default 0: pizza
59 Branching with Bookmarks recipes> jedit sauce.txt recipes> hg add sauce.txt recipes> hg commit -m start sauce recipes> hg branches # new branch visible sauce 2:2a5c5e403030 default 1:98b3df1d5afe (inactive) ! recipes> jedit sauce.txt recipes> hg commit -m 'brand' recipes> ls pizza.txt sauce.txt ! recipes> hg slog -G @ @3 brand sauce | o 2 start sauce | o 1 feta default | sauce o 0 pizza default 3: brand sauce 2: sauce default 1: feta default 0: pizza
60 Branching with Named Branches recipes> hg up default 0 files updated, 0 files merged, 1 files removed, 0 files unresolved ! recipes> ls pizza.txt ! recipes> jedit pizza.txt recipes> hg commit -m 'meat' ! recipes> hg commit -m 'preheat' recipes> hg slog -G @ @5 preheat default | o 4 meat default | default | o 3 brand sauce 5: preheat | | | o 2 start sauce sauce |/ 3: brand o 1 feta default | default sauce o 0 pizza default 4: meat 2: sauce default 1: feta default 0: pizza
61 Branching with Named Branches recipes> hg up sauce 2 files updated, 0 files merged, 0 files removed, 0 files unresolved ! recipes> hg slog -G o 5 preheat default | o 4 meat default | | @ @3 brand sauce | | | o 2 start sauce |/ o 1 feta default | o 0 pizza default ! default sauce recipes> jedit sauce.txt 5: preheat 6: sauté recipes> hg commit -m 'saute' recipes> hg slog -G sauce @ @6 saute sauce 3: brand | | o 5 preheat default default sauce | | 4: meat 2: sauce | o 4 meat default | | default o | 3 brand sauce 1: feta | | o | 2 start sauce default 0: pizza |/ o 1 feta default | o 0 pizza default 62 Branching with Named Branches recipes> hg up default 1 files updated, 0 files merged, 1 files removed, 0 files unresolved ! recipes> hg slog -G o 6 saute sauce | | @ @5 preheat default | | ! recipes> hg merge sauce 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) default recipes> hg st 7: merge M sauce.txt default sauce recipes> hg commit -m 'merge sauce' 5: preheat 6: sauté recipes> hg slog -G @ @7 merge sauce default 5,6 sauce |\ 3: brand | o 6 saute sauce | | default sauce o | 5 preheat default 4: meat 2: sauce | | o | 4 meat default default | | 1: feta | o 3 brand sauce | | default | o 2 start sauce 0: pizza |/ o 1 feta default | 63 o 0 pizza default Branching with Named Branches recipes> hg branches sauce 2:2a5c5e403030 (inactive) default 1:98b3df1d5afe recipes> jedit pizza.txt recipes> hg commit -m 'parmesan' ! recipes> hg up sauce 1 files updated, 0 files merged, 0 files removed, 0 files unresolved sauce ! 10: peel recipes> jedit sauce.txt default 8: parm. recipes> hg commit -m 'onion' sauce ! default 9: onion recipes> hg commit -m 'peeled' 7: merge recipes> hg slog -G @ @10 peeled sauce default sauce | 5: preheat 6: sauté o 9 onion sauce | sauce | o 8 parmesan default 3: brand | | | o 7 merge default 5,6 default sauce |/| 4: meat 2: sauce o | 6 saute sauce | | default | o 5 preheat default 1: feta | | | o 4 meat default default | | 0: pizza
64 Branching with Named Branches recipes> hg merge default 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) recipes> hg st M pizza.txt sauce recipes> hg commit -m 'merge default' 11: merge recipes> hg slog -G @ @11 merge sauce 10,8 sauce |\ 10: peel | o 10 peeled sauce default | | 8: parm. sauce | o 9 onion sauce 9: onion | | default o | 8 parmesan default 7: merge | | o | 7 merge default 5,6 default sauce |\| 5: preheat 6: sauté | o 6 saute sauce | | sauce o | 5 preheat default 3: brand | | o | 4 meat default default sauce | | 4: meat 2: sauce | o 3 brand sauce | | default | o 2 start sauce 1: feta |/ o 1 feta default default | 0: pizza o 0 pizza default
65 Branching with Named Branches recipes> hg up default default 1 files updated, 0 files merged, 15: merge 0 files removed, 0 files unresolved ! default sauce 13: spin 14: chop recipes> jedit pizza.txt recipes> hg commit -m 'ham' default sauce ! 12: ham 11: merge recipes> jedit pizza.txt recipes> hg commit -m 'spin' sauce ! 10: peel recipes> hg up sauce default 8: parm. 2 files updated, 0 files merged, sauce 0 files removed, 0 files unresolved default 9: onion recipes> jedit sauce.txt 7: merge recipes> hg commit -m ‘chop' --close-branch ! default sauce recipes> hg branches 5: preheat 6: sauté default 15:dd9a3e61378b ! sauce recipes> hg branches --closed # or -c 3: brand default 15:dd9a3e61378b sauce 14:c6e4f6cf0870 (closed) default sauce ! 4: meat 2: sauce recipes> hg up default 2 files updated, 0 files merged, default 0 files removed, 0 files unresolved 1: feta ! recipes> hg merge sauce default 0: pizza 1 files updated, 0 files merged, 0 files removed, 0 files unresolved (branch merge, don't forget to commit) 66 recipes> hg commit -m 'merge sauce' Branching with Named Branches recipes> hg slog -G default @ @15 merge default 13,14 15: merge |\ | _ 14 chop sauce default sauce | | closed 13: spin 14: chop o | 13 spin default branch | | default sauce 11: merge o | 12 ham default 12: ham | | sauce | o 11 merge sauce 10,8 |/| default 10: peel | o 10 peeled sauce 8: parm. | | sauce | o 9 onion sauce default 9: onion | | 7: merge o | 8 parmesan default | | default sauce o | 7 merge default 5,6 5: preheat 6: sauté |\| | o 6 saute sauce sauce | | 3: brand o | 5 preheat default | | default sauce o | 4 meat default 4: meat 2: sauce | | | o 3 brand sauce default | | 1: feta | o 2 start sauce |/ default o 1 feta default 0: pizza | o 0 pizza default
67 Pushing branches • hg doesn’t push new branches by default • hg pushes all branches by default • (git pushes only the current branch, which makes more sense to me) • hg push [-b branch] [--new-branch]
recipes> hg push pushing to server searching for changes abort: push creates new remote branches: sauce! (use 'hg push --new-branch' to create new remote branches) ! recipes> hg push -b default pushing to server searching for changes adding changesets adding manifests adding file changes added 1 changesets with 1 changes to 1 files ! recipes> hg push -b sauce --new-branch pushing to server searching for changes adding changesets adding manifests adding file changes 68 added 2 changesets with 2 changes to 1 files (+1 heads) Merging branch heads
julia> hg up default 1 files updated, 0 files merged, 1 files removed, julia> hg pull 0 files unresolved pulling from server julia> hg merge searching for changes abort: branch 'default' has one head - please adding changesets merge with an explicit rev adding manifests (run 'hg heads' to see all heads) adding file changes ! added 1 changesets with 1 changes to 1 files julia> hg up sauce (+1 heads) 2 files updated, 0 files merged, 0 files removed, (run 'hg heads' to see heads, 'hg merge' to merge) 0 files unresolved ! julia> hg merge julia> hg branches merging sauce.txt sauce 4:75a9cc02c946 0 files updated, 1 files merged, 0 files removed, default 1:df75056e704f 0 files unresolved julia> hg heads (branch merge, don't forget to commit) changeset: 5:0cc37f014583 julia> hg commit -m 'merge' branch: sauce ! parent: 3:23cdd918e993 julia> hg slog -G summary: finely diced @ | @6 merge sauce 5,4 ! |\ \ changeset: 4:75a9cc02c946 | o | 5 fine diced sauce branch: sauce | | | parent: 3:23cdd918e993 o | | 4 diced sauce summary: diced |/ / ! o | 3 onion sauce changeset: 1:df75056e704f | | summary: meat o | 2 start sauce | | | o 1 meat default |/ 69 o 0 pizza default Outline • Basic commands in single repository • Creating repo • Add & edit files • Viewing history • Fixing last commit • Multiple users / branches • Simple case • Merge without conflicts • Merge with conflicts • Bookmarks • Branches • BitBucket • Fork • Pull requests • Final thoughts
70 BitBucket • SSH key setup • View profile > BitBucket settings > SSH keys > Add key • Creating repository • Repositories > Create Repository • Fork • In main repo: “...” > Fork > Fork Repository • Pull request • In forked repo: Pull requests > Create a pull request > Create • Approving pull request • In main repo: Pull requests > select pull request > Merge
71 Outline • Basic commands in single repository • Creating repo • Add & edit files • Viewing history • Fixing last commit • Multiple users / branches • Simple case • Merge without conflicts • Merge with conflicts • Bookmarks • Branches • BitBucket • Fork • Pull requests • Final thoughts
72 Hooks • Run on actions (commit, push, pull, ...) • Run on client (under user’s control) or on server • Can verify that action is allowed
! .hg/hgrc [hooks] ! # disallow tab anywhere or trailing whitespace # run before commit transaction finishes ! # see http://hgbook.red-bean.com/read/handling-repository-events-with-hooks.html # (here matching \t fixed using GNU’s --perl-regexp option) ! pretxncommit = hg export tip | (! grep --perl-regexp '^\+.*(\t| $)') ! • Can run scripts, such as emailing notifications, posting to bugzilla, testing compilation, etc. • BitBucket handles many of these features for us
73 Other useful commands • hg outgoing # hg out • hg incoming # hg in • Tells what commits would be pushed or pulled, respectively • hg update --rebase • Rewrite history to avoid merge • hg commit --interactive # or -i • Allows committing some portion of changes
74 Further resources • Mercurial website • https://www.mercurial-scm.org/guide • https://www.mercurial-scm.org/wiki/BeginnersGuides • Mercurial: The Definitive Guide (2009) • Online book • http://hgbook.red-bean.com/ • hginit tutorial • http://hginit.com/ • A Guide to Branching in Mercurial (2009) • http://stevelosh.com/blog/2009/08/a-guide-to-branching-in-mercurial/
75 Mercurial Quick Reference • Create • Branching & merging hg init [dir] hg merge [rev | branch | bookmark] hg clone url [dir] hg update [rev | branch | bookmark | tag] # hg up (alias hg checkout) • Files hg update --clean . # cancel uncommitted merge hg add files hg resolve [-l | -m files] hg mv [-A] source dest hg bookmark [--delete] [name] hg cp [-A] source dest hg branch [name] hg rm [-A] files hg branches hg revert files hg tag [-r rev] [--local] name
• Commits • Viewing changes & history hg commit [-m “message”] [--amend] [files] hg diff [-c rev] [-r rev] [-w -b -B] [files] [--close-branch] hg log [-l num] [-G] [--stat] [files] hg pull [url] [-u] hg status [-acmq] [files] # hg st hg push [url] [-b branch | -B bookmark | -r rev] hg blame [-un] [files] hg rollback hg heads hg outgoing [url] hg incoming [url] • Configuration files ~/.hgrc # user ~/.hgignore # user, set in ~/.hgrc .hg/hgrc # repo .hgignore # repo
76