Mercurial SCM (Hg) Toomas Laasik
Total Page:16
File Type:pdf, Size:1020Kb
Mercurial SCM (Hg) Toomas Laasik 1.06.2018 Mercurial Mercurial is a free, distributed source control management tool, like git Mercurial Mercurial is a free, distributed source control management tool, like git Philosophy and key points: ● Usability first, has consistent syntax and help Mercurial Mercurial is a free, distributed source control management tool, like git Philosophy and key points: ● Usability first, has consistent syntax and help ● Each command does one thing Mercurial Mercurial is a free, distributed source control management tool, like git Philosophy and key points: ● Usability first, has consistent syntax and help ● Each command does one thing ● History should be preserved Mercurial Mercurial is a free, distributed source control management tool, like git Philosophy and key points: ● Usability first, has consistent syntax and help ● Each command does one thing ● History should be preserved ● Works well on all major OSes, including Windows Mercurial Mercurial is a free, distributed source control management tool, like git Philosophy and key points: ● Usability first, has consistent syntax and help ● Each command does one thing ● History should be preserved ● Works well on all major OSes, including Windows ● Easy to install and configure. It just works Mercurial Mercurial is a free, distributed source control management tool, like git Philosophy and key points: ● Usability first, has consistent syntax and help ● Each command does one thing ● History should be preserved ● Works well on all major OSes, including Windows ● Easy to install and configure. It just works ● Extensible (but base version is often enough) Mercurial. Who uses it? Facebook ● Why? Because git had trouble handling huge repositories ● Facebook has its own extensions for Hg Mozilla Firefox ● 10+ million LOC Mercurial anatomy Hg repository consists of a working directory and .hg/ directory Working directory is a copy of the project's files at a given point in time plus uncommited edits (rev 2 is a parent of working directory) Mercurial anatomy .hgignore lists files that are not syntax: glob revisioned. Same as .gitignore *.sln Temp/* It is tracked as any other file site.cache Mercurial anatomy .hgtags relates revisions to given 85a9d168e7aa1cd2e... build_273 human readable tag names 16c18a4302b89afd2... build_305 It is tracked as any other file Mercurial anatomy Commit records state of the working directory relative to its parent in a new changeset (rev 4). That changeset will become new parent for working directory. Rev 4 is now a branch because “line of development diverged” Mercurial anatomy A changeset: ● is an atomic group of related changes to multiple files ● has a revision number and hash id ● has one or two parents (merge) Changeset without children is called a head, latest head is called a tip Mercurial anatomy Hg is a distribured SCM Each team member has their own cloned repository. Sometimes more than one No central repository is needed, but often it is convenient to have a passive central repository (eg BitBucket) https://homes.cs.washington.edu/~mernst/advice/version-control.html Tools Hg has CLI interface (hg <command> …) There are plugins to integrate Hg into all major IDEs: Eclipse, Visual Studio, IntelliJ, etc There are multiple standalone GUIs for Hg. One of them is TortoiseHg: ● hg CLI tool ● TortoiseHg Workbench ● Windows Shell extension ● TortoisePlink for SSH tunnel Tools. TortoiseHg Setup and config Install TortoiseHg ~/.hgrc or Mercurial.ini Edit user wide config and add [ui] username = Toomas Laasik <[email protected]> at least who you are (~/.hgrc) hg config --edit Each repository has its own .hg/hgrc file that has repo specific lines and can override parts of user config Setup and config Normally access to remote ~/.hgrc or Mercurial.ini private repo prompt you for [ui] password. It may be a good username = Toomas Laasik <[email protected]> idea to use keys instead ssh = tortoiseplink.exe -ssh -i "c:\keys\toomas.ppk" [extensions] strip = An actual config I use --> Workflows Workflow is a way how you, your team and others use SCM for a project. Some basic workflows (https://www.mercurial-scm.org/guide): ● Log keeping ● Lone developer with nonlinear history ● Separate features ● Sharing changes Many workflows can be mixed and matched. Each team usually has a custom workflow best suitable for them Log keeping workflow ● Use Case: Look back when you did which changes ● 1 developer, 1 local repo Very basic, this is here just to get accustomed to syntax Log keeping workflow hg init - create repo $ mkdir uthg/ $ cd uthg/ hg add <filename> - add $ echo Hello > hello.txt a file on the next commit. $ hg init Without filename all files $ hg add hello.txt are added $ hg commit -m "First commit" hg commit - commit $ hg log changes to default branch changeset: 0:f4d00ef06737 user: Toomas Laasik <[email protected]> hg log - show revision date: Tue May 29 21:47:54 2018 +0300 summary: First commit history Log keeping workflow hg status - show changes $ echo world >> hello.txt in the working directory $ echo Read this > README $ hg status Commit changes M hello.txt ? README $ hg commit Log keeping workflow hg status - show changes $ echo world >> hello.txt in the working directory $ echo Read this > README $ hg status Commit changes M hello.txt ? README $ hg commit Oops, forgot to add $ hg add README! --amend flag adding README lets you recommit last change $ hg commit --amend saved backup bundle to c:\work\uth... Log keeping workflow hg status - show changes $ echo world >> hello.txt in the working directory $ echo Read this > README $ hg status Commit changes M hello.txt ? README $ hg commit Oops, forgot to add $ hg add README! --amend flag adding README lets you recommit last change $ hg commit --amend saved backup bundle to c:\work\uth... There is also hg rollback Log keeping workflow hg diff - see changes $ echo asdasd >> hello.txt $ hg diff hg revert <filename> - diff -r 9fc99ad93c03 hello.txt reverts uncommited --- a/hello.txt Tue May 29 23:25:44 2018 +0300 +++ b/hello.txt Wed May 30 00:55:13 2018 +0300 changes. Creates backup @@ -1,2 +1,3 @@ file with orig extension Hello (disable with -C flag) world +asdasd $ hg revert hello.txt $ hg status ? hello.txt.orig $ rm *.orig Log keeping workflow hg cp <old> <new> $ hg cp hello.txt copy_of_hello.txt hg mv <old> <new> - $ hg mv hello.txt renamed_hello.txt copy or move file without $ hg summary loosing revision history. parent: 1:9fc99ad93c03 tip Don’t forget to commit! Added readme, changed hello branch: default hg summary - show commit: 1 renamed, 1 copied update: (current) working directory state $ hg commit -m “copy and rename” Log keeping workflow hg log -G - show revision $ hg log -G history with graph @ changeset: 2:4ca546cbe96a | tag: tip | user: Toomas Laasik <[email protected]> | date: Wed May 30 01:36:00 2018 +0300 | summary: copy and rename | o changeset: 1:9fc99ad93c03 | user: Toomas Laasik <[email protected]> | date: Tue May 29 23:25:44 2018 +0300 | summary: Added readme, changed hello | o changeset: 0:f4d00ef06737 user: Toomas Laasik <[email protected]> date: Tue May 29 21:47:54 2018 +0300 summary: First commit Lone developer with nonlinear history ● Use Case: Go back at times and work onward from there ● 1 developer, 1 local repo Basic, but shows how automatic anonymous branching and merging works. Lone developer with nonlinear history hg update <rev> - update ### continuing from code above working directory to $ hg update 1 changeset (needs clean $ echo Hello world! > hello.txt working directory) $ hg commit -m "Put hello on one line" created new head After commit we have two heads. Later on heads need to be merged or closed Lone developer with nonlinear history hg merge - merge working $ hg merge directory with another merging hello.txt and copy_of_hello.txt to copy_of_.. merging hello.txt and renamed_hello.txt to renamed_.. revision. 0 files updated, 2 files merged, 0 files removed, 0.. (branch merge, don't forget to commit) No conflicts. $ hg commit -m “Merge” Here no arguments are given, because there we are on one head and there is only exactly one other head. Lone developer with nonlinear history hg merge - merge working $ hg merge directory with another merging hello.txt and copy_of_hello.txt to copy_of_.. merging hello.txt and renamed_hello.txt to renamed_.. revision. 0 files updated, 0 files merged, 0 files removed, 2.. (branch merge, don't forget to commit) Merge conflicts! If hg couldn’t resolve them $ hg resolve --list automatically you need to somefile.txt do it manually, mark them (edit files listed to manually resolve conflicts or resolved and commit retry automatic resolving hg resolve somefile.txt) Nicer to do in GUI $ hg resolve --mark somefile.txt $ hg commit -m “Merge” Lone developer with nonlinear history hg merge - merge working $ hg merge directory with another merging hello.txt and copy_of_hello.txt to copy_of_.. merging hello.txt and renamed_hello.txt to renamed_.. revision. 0 files updated, 0 files merged, 0 files removed, 2.. (branch merge, don't forget to commit) Merge conflicts! If you can’t resolve conflicts or $ hg resolve --list just want to cancel merge, somefile.txt then update to some other (edit files listed to manually resolve conflicts or revision retry automatic resolving hg resolve somefile.txt) $ hg update --clean Lone dev... Merge conflict resolving in TortoiseHg Next: repo branches as TortoiseHg shows it Lone developer with nonlinear history Separate features ● Use Case: Work on several features in parallel ● 1 developer, many repos Each feature is kept and developed in cloned repo. In practice you can have many variations of it: ● stable, feature1, feature2, … ● stable, testing, features (Using named branches gives somewhat similar workflow) Separate features hg clone <src> <dst> - ### continuing from code above makes a clone of a repo. $ cd .