Wiki

Clone wiki

hgflow / Home

Welcome to hgflow wiki! Here we document hgflow -- a Mercurial extension that implements a generalized Driessen branching model. <<toc / 3>> \\ \\ \\ \\ = What's New = == v0.9.7 == * Removed dependency on the `ConfigParser` module. This is a good news for Windows users. * Smarter error messages. If you make typos in your command, hgflow can now suggest corrections. For example: {{{ #!bash > hg flow hotfis flow: error: Stream not found: <hotfis> flow: note: Did you mean: hotfix? > hg flow hotfix stat 0.9.7.1 flow: error: Invalid action or unknown branch in <hotfix>: 'stat' flow: note: Did you mean: start? > hg flow hotfix close flow: error: Invalid action or unknown branch in <hotfix>: 'close' flow: note: Did you mean: finish or abort? }}} * Minor enhancements and bug fixes == v0.9.6 == * Many minor enhancements and bug fixes * Performance improvement * Added {{{-d --default}}} option for the {{{init}}} command. This feature allows automation of initialization of hgflow. For example, you can automatically initialize hgflow when you initialize hg by adding the following setting in your hg's configuration file: {{{ #!ini ... [hooks] post-init.flow = hg flow init -d }}} * Added {{{--stamp}}} option for all actions or commands that can commit changes. What this option does is to append a user-specified string (such as an issue key) in all commit messages of this hg-flow command. For example: {{{ #!console $ hg flow feature finish --stamp "Issue-20" --dry-run --verbose flow: This is a dry run. flow: note: Hg command history: flow: note: hg commit --message "flow: Closed <feature> 'b'. Issue-20" --close-branch flow: note: hg update develop flow: note: hg merge feature/b flow: note: hg commit --message "flow: Merged <feature> 'b' to <develop> ('develop'). Issue-20" }}} * Added {{{version_prefix}}} configuration keyword to allow user to customize the version prefix. By default, this prefix is 'v'. Usage example: In hg's configuration file: ##**$HOME/.hgrc**## (or ##**%USERPROFILE%/Mercurial.ini**## on Windows): {{{ #!ini ... [flow] autoshelve = yes version_prefix = ver }}} == v0.9.5 == * Added {{{--user}}} for {{{init}}}, {{{start}}}, {{{finish}}}, and {{{promote}}} actions. * {{{--closed}}} is now an option of the {{{log}}} action. This option lets {{{log}}} show the revision history of both open and closed branches in the specified stream. * Added {{{--dirty}}} for the {{{start}}} action. This option enables user to start a new branch from a dirty working directory and move all the uncommitted changes to the new branch. * Added {{{--erase}}} for the {{{finish}}} action. With this option, you erase (i.e., completely delete from the repository) the branch after it is successfully finished. The final effect is as if all changes in the branch were collapsed and then committed as a single changeset to the destination branch which the branch was merged to. Check out {{{hg flow help @finish}}} for a bit more detail. * Added {{{--erase}}} for the {{{abort}}} action. This option enables you to erase (i.e., completely delete from the repository) the entire branch when you abort it. Check out {{{hg flow help @abort}}} for a bit more detail. * Now you can promote a {{{<develop>}}} branch directly to {{{<master>}}}, bypassing {{{<release>}}}. This feature provides a shortcut from the {{{<develop>}}} directly to {{{<master>}}}. I found it very useful especially for small projects, where you don't really need a "release" (or QA) stage and you want continuous deployment of newly developed features. Such a workflow can be considered as a simplified/reduced version of the Driessen's model and was promoted by some people (e.g., github, and they call it [[http://scottchacon.com/2011/08/31/github-flow.html|//github flow//]]). Example usage: {{{ #!console $ # Ensures the working directory is the <develop> branch that we want to release. $ hg flow develop # Now we release. With the '-t' option, you can supply a tag for the released snapshot in the <master> branch. The command takes the '--dry-run' option in order to show what exactly happens. $ hg flow develop promote -t "v0.9.5" --dry-run flow: This is a dry run. flow: note: Hg command history: flow: note: hg update default flow: note: hg merge develop flow: note: hg commit --message "flow: Promoted <develop> 'trunk' (abdae6de9735) to 'default'." flow: note: hg tag v0.9.5 flow: note: hg update develop }}} == v0.9.4 == * Add support for [[Home#!Generalized Driessen's Branching Model|generalized streams]]. * Add an advanced help system. * Add support for colorized messages. * Add {{{promote}}} action. * Add {{{abort}}} action. * Add {{{upgrade}}} command. * Add {{{--dry-run}}} option. * Add a number of command/action's options. * Allow users to customize commit message prefix. == v0.8.x == The latest version in the 0.8 release line is [[https://bitbucket.org/yujiewu/hgflow/get/v0.8.3.tar.gz|v0.8.3]]. * Add [[Home#!commands|##**rebase**## action that can rebase a branch to its parent branch]]. * Add [[Home#!commands|##**log**## action for all streams]]. * Add [[DetailedCommands#!unshelve-changes|##**unshelve**## command]]. * Add [[DetailedCommands#!show-hgflow-version|##**version**## command]]. * Support [[Home#!autoshelve|autoshelve]] -- automatically shelve uncommitted changes before you switch to another branch and automatically unshelve the changes when you switch back to the previous branch. * The ##**list**## action is able to indicates which ones have shelved changes. * Show latest tag of the master stream. * A lot more friendly and capable ##**hg flow-init**## command * Support the ##**--history**## option for ##**hg flow-init**## command. * Honor the ##**--trackback**## option. == v0.7.x == The latest version in the 0.7 release line is [[https://bitbucket.org/yujiewu/hgflow/get/v0.7.2.tar.gz|v0.7.2]]. * Support ##**start**##, ##**finish**##, ##**push**##, ##**publish**##, ##**pull**##, and ##**list**## actions for the **[[DetailedCommands#!feature|feature]]**, **[[DetailedCommands#!release|release]]**, **[[DetailedCommands#!hotfix|hotfix]]**, and **[[DetailedCommands#!support|support]]** streams. * Support ##**push**##, ##**publish**##, and ##**pull**## actions for the **[[DetailedCommands#!develop|develop]]** and **[[DetailedCommands#!feature|master]]** streams. * [[DetailedCommands#!change-to-a-stream|Easy switch to a branch]]. * [[DetailedCommands#!list-a-stream|Shortcut command to list all branches in a stream]]. * [[DetailedCommands#!list-all-streams|Support listing all branches in all streams]]. * Support [[Home#!commands|--history]] option to record the hg commands used by this hgflow command. \\ \\ \\ \\ = History = Version 0.3 and earlier versions of hgflow was written by [[https://bitbucket.org/yinwm/hgflow/overview|yinwm]]. On July 14 2011, I forked the version 0.3. My goals were (1) to provide //superior// Mercurial support for Driessen's branching model and (2) to implement a few ideas that generalize and enhance this model. I completely rewrote the code to get a cleaner code base that I could further work on. This work resulted in [[https://bitbucket.org/yujiewu/hgflow/get/v0.7.2.tar.gz|version 0.7]], which also provided a more complete set of commands than 0.3, and IMO it's even better than [[https://github.com/nvie/gitflow|gitflow]]. I then implemented several important enhancements on usability, such as [[Home#!autoshelve|autoshelve]], ##**--history**## option, [[Home#!commands|##**rebase**##]] and [[Home#!commands|##**log**##]] actions. These made hgflow a lot nicer to use. This work was published as [[https://bitbucket.org/yujiewu/hgflow/get/v0.8.3.tar.gz|version 0.8.x]]. Aftewards, the code was again deeply refactored to support //generalized streams//. In addition, an advanced help system, an infrastructure for parsing subcommand options, and a mechanism for colorizable messages were established. These made hgflow more powerful and friendly, and made it easier for further enhancements. A number of useful options, including ##**--dry-run**## and ##**--onstream**, were implemented. \\ \\ \\ \\ = Introduction = In software engineering, //branching// is diverging the development so that the source code can evolve parallelly on independent tracks. Branching will result in multiple normally complementary versions of source code -- //branches//. Branches eventually will be merged to yield a more mature version that incorporates all necessary features/fixes as individually developed in branches. Branching and merging, if used wisely, will make software development process less messy and more controllable, especially in distributed scenarios. How to systematically branch and merge source code is a common problem facing software engineers in using version control system. Among other successful models, the one proposed by Vincent Driessen is particularly attractive to us. If you haven't, we encourage you to read the [[http://nvie.com/posts/a-successful-git-branching-model/|original article]]. In short, Driessen's model distinguishes 6 types of branches in the purpose of code, namely, master, develop, feature, release, hotfix, and support. Any branch is of one of these types. We can call the entire set of branches of the same type as a //**stream**//. So there are 6 streams: (again) **master**, **develop**, **feature**, **release**, **hotfix**, and **support**. They evolve as its member branches emerge, change, and terminate. In general, a stream can contain 0 or more branches and the number can change along time. The master and develop streams are, however, a bit special in that they contain 1 only 1 branch for all the time. From our understanding, stream is a fundamental concept in Driessen's model. Operations on branches can be redefined in terms of stream, giving us high-level commands that make our life time a bit easier. Hgflow is a Mercurial extension that implements Driessen's model. It supplies users high level stream-based commands for managing branches. The original implementation was inspired by [[https://github.com/nvie/gitflow|git-flow]] - an earlier implementation for the //git// version control system. Many commands and usages in hgflow are similar to git-flow. Experience learned in using gitflow can be directly transferred to hgflow. An excellent introduction to usage of git-flow can be found at [[http://yakiloo.com/getting-started-git-flow/|here]]. \\ \\ \\ \\ = Generalized Driessen's Branching Model = Stream in its bare essence is a set of branches. Removing some restrictions in the original concept, //we generalize stream to refer to any set of branches.// This simple generalization results in a more powerful and flexible model. There is one particularly useful type of streams. Say we have a branch called //trunk//. We can open new branches from the trunk, and later we can merge the branches back to it. This is in fact a common branching and merging pattern. All branches from the same trunk plus the trunk itself natually form a stream, and we call it ##**natural stream**##. We don't have to do something special to create a natural stream, which becomes existent as long as the trunk is. In contrast, the master, develop, feature, release, hotfix, and support are preexisting streams, and they are sortof artificial. Hgflow has been enhanced to support natural streams since v0.9. Let's see how it can be used. Say we want a branch called A in the feature stream. We can start it using the following command: {{{ #!console $ hg flow develop $ hg flow feature start A }}} Now we have a branch: <feature-prefix>/A. Since we can consider any branch as a trunk from which we open other branches, a natural stream is spontaneously created whenever a new branch is created. In the example here, we have a natural stream: feature/A. {{{ #!console $ hg flow feature/A $ # Switch to the trunk of <feature/A>. $ # This command is largely equivalent to the more familiar command: $ # hg flow feature A $ hg flow feature/A start a1 $ # Start a new branch in <feature/A>. The new branch is named after <feature-prefix>/A/a1. $ hg flow feature/A a1 $ hg flow feature/A finish $ # Finish the <feature-prefix>/A/a1 branch. $ # Merge it to the trunk of <feature/A>, and close it. }}} You can call <feature/A> as a substream of <feature>. Branches in <feature/A> are, of course, also in <feature>. So you can operate branches in <feature/A> at the level of <feature>. For example, you can finish the <feature-prefix>/A/a1 branch as a regular branch in <feature>. {{{ #!console $ hg flow feature/A a1 $ hg flow feature finish $ # Finish the <feature-prefix>/A/a1 branch. $ # Merge it to <develop>, and close it. $ # Note how the effect differs from that of the prior command: hg flow feature/A finish. }}} == Branches in Develop Stream == We allow users to start branches in the develop stream. Each branch in <develop> is a substream in <develop>. You can use this substream to start new branches in <release> and/or <feature>. Examples. {{{ #!console $ hg flow develop $ # Update workspace to <develop>'s trunk. $ hg flow develop start spring $ # Start a new branch called <develop-prefix>/spring. $ hg flow develop/spring:feature start feature_for_spring_release $ # Start a new branch called <feature-prefix>/feature_for_spring_release. $ # This branch is started from <develop/spring> instead of <develop>. $ # Note the syntax for specifying the stream: <source-stream>:<stream>, which is $ # available since v0.9 and means that the action will operate on a branch in <stream>, $ # but the source (or destination) stream is not the default, but specified by <source-stream>. $ # This is a more general syntax. You can consider the familiar command: $ # hg flow feature start <name> $ # as a shorthand of this command: $ # hg flow develop:feature start <name> $ hg flow develop/spring:feature finish $ # Finish a <feature> branch. Merge the branch to the trunk of <develop/sprint>, instead of <develop>. }}} One special thing about <develop> substreams is that when a feature branch is being finished and merged into a <develop> substream, the trunk of the substream will be automatically merged into the <develop> trunk as part of the workflow. For example: {{{ #!console $ hg flow develop/spring:feature finish --dry-run flow: This is a dry run. flow: note: Hg command history: flow: note: hg commit --message "flow: Closed <feature> 'new_spring_feature'." --close-branch flow: note: hg update develop/spring flow: note: hg merge feature/new_spring_feature flow: note: hg commit --message "flow: Merged <feature> 'new_spring_feature' to <develop/spring> ('develop/spring')." flow: note: hg update develop flow: note: hg merge develop/spring flow: note: hg commit --message "flow: Merged <develop/spring:feature> 'new_spring_feature' to <develop> ('develop')." }}} The effects are similar for finishing a <release> branch. For example: {{{ #!console $ hg flow develop/spring:release finish --dry-run flow: This is a dry run. flow: note: Hg command history: flow: note: hg commit --message "flow: Closed <release> '2012_spring_release'." --close-branch flow: note: hg update develop/spring flow: note: hg merge release/2012_spring_release flow: note: hg commit --message "flow: Merged <release> '2012_spring_release' to <develop/spring> ('develop/spring')." flow: note: hg update develop flow: note: hg merge develop/spring flow: note: hg commit --message "flow: Merged <develop/spring:release> '2012_spring_release' to <develop> ('develop')." flow: note: hg update default flow: note: hg merge release/2012_spring_release flow: note: hg commit --message "flow: Merged <release> '2012_spring_release' to <master> ('default')." flow: note: hg tag v2012_spring_release }}} Another special thing of <develop> branches is that when you finish a branch in <develop> stream (not in a develop substream though), a new <release> branch will be created. For example: {{{ #!console $ hg flow develop spring $ # Update workspace to <develop-prefix>/spring branch. $ hg flow develop finish --dry-run flow: This is a dry run. flow: note: Hg command history: flow: note: hg update develop/spring flow: note: hg branch release/spring flow: note: hg commit --message "flow: Created branch 'release/spring'." flow: note: hg update develop/spring flow: note: hg commit --message "flow: Closed <develop> 'spring'." --close-branch flow: note: hg update develop flow: note: hg merge develop/spring flow: note: hg commit --message "flow: Merged <develop> 'spring' to <develop> ('develop')." flow: note: hg update release/spring }}} == Act on a Stream == Several actions can act on a stream with the --onstream option: finish, rebase, log, and abort. In other words, they act on each branch in the stream. \\ \\ \\ \\ = License = GPL 2.0. \\ \\ \\ \\ = Installation = 0. Requirements: You need ##hg## version 1.6 or later. Some features, for example, [[Home#!autoshelve|autoshelve]] and [[Home#!commands|rebase]], need the [[http://mercurial.selenic.com/wiki/MqExtension|mq]] and [[http://mercurial.selenic.com/wiki/RebaseExtension|rebase]] extensions.\\ 1. To get hgflow, you can either clone the repository, or download the latest version from the link: [[https://bitbucket.org/yujiewu/hgflow/downloads/hgflow-v0.9.5.tar.bz2|hgflow v0.9.5]].\\ 2. Unpack and copy the ##hgflow.py## file to an arbitrary directory, e.g., ##**$HOME/.hgext/**##.\\ 3. Edit hg configuration file: ##**$HOME/.hgrc**## (or ##**%USERPROFILE%/Mercurial.ini**## on Windows; refer to [[http://www.selenic.com/mercurial/hgrc.5.html#files|here]] if you are unsure which file to edit.). Add the following lines: {{{ #!ini [extensions] flow = /PATH/TO/hgflow.py }}} 4. (//optional//) If you use a pager, you might want to let it ignore hgflow, since it could hide hgflow's input prompts. For example, I have the following lines in my ##**$HOME/.hgrc**## file to let the pager ignore {{{hg flow init}}} command (among others): {{{ #!ini [pager] pager = LESS='FSRX' less ignore = version, help, update, flow init }}} \\ \\ = Initialization and Configuration = You have to initialize hgflow for every repository where you want to use hgflow. {{{ #!console $ cd <my_repository_dir> $ hg flow init }}} The ##**flow init**## command will create a configuration file: ##**.hgflow**## in the root dir of the repository. Before doing so, it will ask you branch names or prefixes for each basic stream. Type your preferred names or press return to use the default. {{{ Branch name for master stream: [default] Branch name for develop stream: [develop] Branch name prefix for release stream: [release/] Branch name prefix for feature stream: [feature/] Branch name prefix for hotfix stream: [hotfix/] Branch name prefix for support stream: [support/] }}} Since the configuration file is tracked by ##hg##, if you have multiple existing branches, hgflow will need to write the configuration file in each open branch. This will be done automatically by ##**hg flow init**## command. == Autoshelve == Versions 0.8 and later provide a feature called **autoshelve**. It can automatically shelve uncommitted changes in the current workspace right before you switch to a different branch, and later when you switch back, it will automatically unshelve the changes. You can turn on this feature by adding the following lines in your [[http://www.selenic.com/mercurial/hgrc.5.html#files|hg configuration file]]: {{{ #!ini [flow] autoshelve = true }}} This feature needs the [[http://mercurial.selenic.com/wiki/MqExtension|mq extension]]. == Commit Message Prefix == Versions 0.9.3 and later allow users to customize the commit-message prefix, which by default is {{{flow: }}}, thanks to [[https://bitbucket.org/drylouvre|Greg Salt]] for the initial implementation. You can customize the prefix in your hg's configuration file, for example: {{{ #!ini [flow] prefix = "my_custom_prefix: " }}} You can remove the prefix entirely by setting {{{prefix}}} to an empty string: {{{""}}}. == Upgrade to v0.9 == Use ##**hg flow upgrade**## to make the change for your repository. \\ \\ \\ \\ = Commands = Basic syntax of hgflow commands: {{{ #!console $ hg flow {<stream> [<action> [<arg>...]] | <command>} [<option>...] }}} where {{{<stream>}}} should be a (generalized) stream, which can be one of the basic streams: ##**master**##, ##**develop**##, ##**feature**##, ##**hotfix**##, ##**release**##, and ##**support**##, or a natural stream, e.g., ##**feature/log_options**##. Actions: |=Action |=Description | |**start** | Open a new branch in the stream.| |**finish** | Close workspace branch and merge it to destination stream(s).| |**push** | Push workspace branch to the remote repository.| |**publish**| Same as **push**| |**pull** | Pull from the remote repository and update workspace branch.| |**list** | List all open branches in the stream.| |**log** | Show revision history of branch.| |**promote**| Merge workspace to other branches. (not closing any branches.)| |**rebase** | Rebase workspace branch to its parent branch.| |**abort** | Abort branch. Close branch without merging.| \\ Commands: |=Command |=Description | |**init** | Initialize flow.| |**unshelve**| Unshelve the previously shelved changes for workspace branch.| |**upgrade** | Upgrade the configuration file to v0.9.5 or later.| |**help** | Show help for a specific topic. Example: {{{hg flow help @help}}}| |**version** | Show flow's version number.| \\ Options: |=Option |=Description |=Actions/Commands | |**--history** | Print history of hg commands used in this workflow.| all | |**--dry-run** | Do not perform actions, only print history. | all | |**--dirty** | Start a new branch from a dirty workspace, and move all uncommitted changes to the new branch. | start | |**--traceback** | Print trace back when hgflow command fails.| all | |**--verbose** | Call hg commands with the **--verbose** option, and\\ print history of hg commands used in this workflow.| all | |** -c --closed**| Show normal and closed branches in stream. |{{{list, log}}}| |** -c --commit**| Commit changes before closing the branch. |{{{finish}}}| |** -d --default**| Initialize flow with default configuration. | {{{init}}} | |** -d --date** DATE| Record the specified date as commit date. |{{{start, finish,}}}\\{{{promote}}}| |** -d --date** DATE| Show revisions matching date spec. |{{{log}}}| |** -d --dest** REV| Destination changeset of rebasing. |{{{rebase}}}| |** -e --erase**| Erase branch after it is merged or aborted successfully. |{{{finish, abort}}}| |** -F --file** FILE [+]| File to show history of. |{{{log}}}| |** -f --force**| Force reinitializing flow.| {{{init}}} | |** -g --git**| Use git extended diff format to show patch. |{{{log}}}| |** -k --keyword** TEXT| Do case-insensitive search for a given text. |{{{log}}}| |** -l --limit** VALUE| Limit number of changesets displayed. |{{{log}}}| |** -m --message** TEXT| Record TEXT as commit message. |{{{start, finish,}}}\\{{{promote, abort}}}| |** -p --stamp** TEXT| Append TEXT to all commit messages. | {{{init, upgrade}}}\\{{{start, finish}}}\\{{{promote, rebase}}}\\{{{abort}}}| |** -p --patch**| Show patch. |{{{log}}}| |** -r --rev** REV| Revision to start a new branch from.| {{{start}}}| |** -r --rev** REV| Revision to promote to other branches. |{{{promote}}}| |** -s --onstream**| Act on stream. |{{{finish, rebase,}}}\\{{{log, abort}}}| |** -t --tag** NAME| Tag the merging changeset with NAME. |{{{promote}}}| |** -t --tag** NAME| Tag the <master> trunk with NAME after merging. |{{{finish}}}| |** -u --user** USER| Use specified user as committer. |{{{init, start,}}}\\{{{finish, promote}}}| |** -u --user** USER| Show revisions committed by specified user. |{{{log}}}| \\ \\ \\ \\ = Developer Manual = [[html/frames.html|Developer Manual]] (HTML format)

Updated

Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.