diff -r 9b574ea00cde -r cadc468e9a5a gitdevs.rst --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/gitdevs.rst Wed Dec 03 16:06:21 2014 -0800 @@ -0,0 +1,439 @@ +:tocdepth: 2 + +.. _gitdevs: + +Mercurial for git developers +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +.. contents:: + :local: + + +Overview +======== + +This guide is for those most accustomed to git-based development and wanting to +contribute to CPython (or other Mercurial-based projects) with minimal +cognitive load in learning a new source control tool. While there are projects +that focus on automating this to allow seamless bridges between the two systems, +this guide focusses solely on native Mercurial functionality. + +As with most tools, this is not the only method of achieving git-like +workflows with Mercurial. It is intended solely to provide one potential path. + + +Git workflow +============ + +The workflow of a developer might look something like this: + +* Clone CPython +* Find/Create issue in the issue tracker (issueA) + + - Work on issue + - Submit patch for review + +* Work on another issue (issueB) + + - Work on issue + - Commit work in progress + +* Address review comments (issueA) + + - Commit work + - Submit patch for review + +* Continue feature work (issueB) +* *Rinse and repeat* + + +Using git, a simplified workflow may look like this: + +.. code-block:: bash + + git clone git@github.com:python/cpython.git + + # work on issueA + git checkout -b issueA + git commit -a + + # start working on issueB + git checkout master + git checkout -b issueB + git commit -a + + # address review comments and merge + git checkout issueA + git commit -a + git checkout master + git merge issueA + git branch -d issueA + + # continue working on issueB + git checkout issueB + + +This flow will be used as the base for comparison against Mercurial usage that +aims to achieve a similar, if not identical, workflow. + +Main differences between git and hg +=================================== + +.. note:: The differences listed here are only those relevant to this workflow + +Mercurial branches are global and permanent +------------------------------------------- + +This means that if you create a named branch, it is intended to be long-lived: + + Mercurial branch names may be used for whatever reasons users want. + However, a good rule of thumb is to use branch names sparingly and for + rather longer lived concepts like "release branches" (rel-1, rel-2, etc) + and rather not for short lived work of single developers. + + -- http://mercurial.selenic.com/wiki/Branch#Named_branches + + +If you routinely create short-lived branches for development work and then +delete them after they've been merged to master, this is something to be aware +of. You *can* still only push select branches to remotes, so it's not a +functional issue as far as the public repo goes. + + +Mercurial branch types +---------------------- + +There are a number of branch types in Mercurial. These are: + +Named branches +`````````````` + + Mercurial supports giving names to branches, by using the branch name + property of the changeset (see NamedBranches). If no branch name was set, + Mercurial assigns the branch name "default". So the name of the default + branch in a repository is "default" (which, for example, is not displayed + when doing a hg log). + +Bookmarks +````````` + + Bookmarks can be used as an alternative to NamedBranches for tracking + multiple lines of development. Systems like Mercurial, CVS, and Subversion + store their branch information as a permanent part of each commit. This + is useful for future auditing of long-lived branches, as it's always + possible to identify which branch a commit was introduced on. Git, by + contrast, has "branches" that are not stored in history, which is useful + for working with numerous short-lived feature branches, but makes future + auditing impossible. Mercurial's bookmark feature is analogous to Git's + branching scheme, but can also be used in conjunction with Mercurial's + traditional named branches. + +Queues +`````` + + The patch queue extension integrates quilt functionality into Mercurial. + Changes are maintained as patches which are committed into Mercurial. + Commits can be removed or reordered, and the underlying patch can be + refreshed based on changes made in the working directory. The patch + directory can also be placed under revision control, so you can have a + separate history of changes made to your patches. + + +Bookmarks are the branch type that will be used as they allow the user to most +closely emulate a git workflow. They're lightweight, intended for local +development and can be deleted with ease. Note that deleting a bookmark does not +mean that the releated changesets are also deleted. You must use the `strip +extension`_ to do that. + +.. _`strip extension`: http://mercurial.selenic.com/wiki/StripExtension + + +Mercurial workflow +================== + +The following details hg usage with the above git workflow in mind. The +changeset graphs are displayed using :code:`hg log -G`, which can be +tremendously useful when first starting to use hg in order to help you +understand through visuals what it is that hg does with the branches. + + +Cloning +------- + +Pulling the latest CPython code and looking at the current commits: + +.. code-block:: bash + + hg clone https://hg.python.org/cpython + +.. code-block:: bash + + @ changeset: 91935:79a5fbe2c78f + | tag: tip + | parent: 91933:fbd104359ef8 + | user: Antoine Pitrou + | date: Tue Jul 29 19:41:11 2014 -0400 + | summary: Issue #22003: When initialized from a bytes object, io.BytesIO() now + | + | o changeset: 91934:263701e0b77e + | | branch: 2.7 + | | parent: 91924:6c47c6d2033e + | | user: Victor Stinner + | | date: Wed Jul 30 00:39:05 2014 +0200 + | | summary: Issue #22023: Fix %S, %R and %V formats of PyUnicode_FromFormat(). + | | + o | changeset: 91933:fbd104359ef8 + | | user: Victor Stinner + | | date: Tue Jul 29 23:31:34 2014 +0200 + | | summary: Issue #22018: On Windows, signal.set_wakeup_fd() now also supports sockets. + +*Note that in the above graph, `@` represents your current changeset* + +Working on issueA +----------------- + +Assuming you've found a bug logged against default tip (master head in git-speak), +create a bookmark, which automatically activates it. + +.. code-block:: bash + + hg bookmark issueA + +Now, the history graph should look like this: + +.. code-block:: bash + + @ changeset: 91935:79a5fbe2c78f + | bookmark: issueA + | tag: tip + | parent: 91933:fbd104359ef8 + | user: Antoine Pitrou + | date: Tue Jul 29 19:41:11 2014 -0400 + | summary: Issue #22003: When initialized from a bytes object, io.BytesIO() now + | + | o changeset: 91934:263701e0b77e + | | branch: 2.7 + | | parent: 91924:6c47c6d2033e + | | user: Victor Stinner + | | date: Wed Jul 30 00:39:05 2014 +0200 + | | summary: Issue #22023: Fix %S, %R and %V formats of PyUnicode_FromFormat(). + | | + o | changeset: 91933:fbd104359ef8 + | | user: Victor Stinner + | | date: Tue Jul 29 23:31:34 2014 +0200 + | | summary: Issue #22018: On Windows, signal.set_wakeup_fd() now also supports sockets. + +Notice that the only difference between this and the previous one is that +changeset 91935 now also has the bookmark "issue42". Bookmarks are advanced +automatically with each subsequent request. + +Once work has been completed on issueA, commit and prepare a patch for +submission to the issue tracker. Note that Mercurial doesn't have git's concept +of staging, so all changes will be committed. + +.. code-block:: bash + + hg commit -m 'fix for issue42' + +.. code-block:: bash + + @ changeset: 91936:33e3949056ae + | bookmark: issue42 + | tag: tip + | user: Demian Brecht + | date: Wed Jul 30 07:18:38 2014 -0700 + | summary: fix for issueA + | + o changeset: 91935:79a5fbe2c78f + | parent: 91933:fbd104359ef8 + | user: Antoine Pitrou + | date: Tue Jul 29 19:41:11 2014 -0400 + | summary: Issue #22003: When initialized from a bytes object, io.BytesIO() now + | + | o changeset: 91934:263701e0b77e + | | branch: 2.7 + | | parent: 91924:6c47c6d2033e + | | user: Victor Stinner + | | date: Wed Jul 30 00:39:05 2014 +0200 + | | summary: Issue #22023: Fix %S, %R and %V formats of PyUnicode_FromFormat(). + +Notice that the new commit's parent was the previous default tip and the +bookmark has automatically been advanced to the new tip. A patch for submission +to the issue tracker can now be prepared with: + +.. code-block:: bash + + hg diff -c 91936 > issueA.patch + +The above will diff revision 91936 against its parent. This will work +regardless of the commit that you happen to currently updated to. + + +Working on issueB +----------------- + +Now that the patch has been submitted and it's pending review, work on another +issue can be started. This is where another difference between git and +mercurial surfaces: Because of how bookmarks work (and as can be seen in the +previous history graph), the named branch "default" is advanced. A new named +branch (such as in git) has not been created. This means that in order to +update the working copy back to the latest public commit, you must know which +commit to revert back to before creating a new bookmark: + +.. code-block:: bash + + hg update 91935 + hg bookmark issueB + +.. code-block:: bash + + o changeset: 91936:33e3949056ae + | bookmark: issueA + | tag: tip + | user: Demian Brecht + | date: Wed Jul 30 07:18:38 2014 -0700 + | summary: fix for issueA + | + @ changeset: 91935:79a5fbe2c78f + | bookmark: issueB + | parent: 91933:fbd104359ef8 + | user: Antoine Pitrou + | date: Tue Jul 29 19:41:11 2014 -0400 + | summary: Issue #22003: When initialized from a bytes object, io.BytesIO() now + | + | o changeset: 91934:263701e0b77e + | | branch: 2.7 + | | parent: 91924:6c47c6d2033e + | | user: Victor Stinner + | | date: Wed Jul 30 00:39:05 2014 +0200 + | | summary: Issue #22023: Fix %S, %R and %V formats of PyUnicode_FromFormat(). + + +Addressing issueA review comments +--------------------------------- + +While working on my new feature, I've received reviews of my bug fix and want to +finish that up before continuing on this much longer feature task. First step is +to commit my current feature work: +While working on issueB, a review has been completed for issueA. The following +demonstrates one method of store current state of issueB, and update back to +issueA: + +.. code-block:: bash + + hg commit -m 'wip commit' + created new head + +In the above, hg will confirm that a divergent path has been created. This is +intentional and to be expected. + +.. code-block:: bash + + hg update issueA + +Reviewing the history graph, a new head can now be seen: + +.. code-block:: bash + + o changeset: 91937:f207797d4623 + | bookmark: issueB + | tag: tip + | parent: 91935:79a5fbe2c78f + | user: Demian Brecht + | date: Wed Jul 30 07:37:54 2014 -0700 + | summary: wip commit + | + | @ changeset: 91936:33e3949056ae + |/ bookmark: issueA + | user: Demian Brecht + | date: Wed Jul 30 07:18:38 2014 -0700 + | summary: fix for issueA + | + o changeset: 91935:79a5fbe2c78f + | parent: 91933:fbd104359ef8 + | user: Antoine Pitrou + | date: Tue Jul 29 19:41:11 2014 -0400 + | summary: Issue #22003: When initialized from a bytes object, io.BytesIO() now + +Once review comments have been addressed, commit again and prepare an updated +patch: + +.. code-block:: bash + + hg commit -m 'addressing review comments' + +.. code-block:: bash + + @ changeset: 91938:a8b5fd8e6bd6 + | bookmark: issue42 + | tag: tip + | parent: 91936:33e3949056ae + | user: Demian Brecht + | date: Wed Jul 30 07:43:49 2014 -0700 + | summary: addressing review comments + | + | o changeset: 91937:f207797d4623 + | | bookmark: myfeature + | | parent: 91935:79a5fbe2c78f + | | user: Demian Brecht + | | date: Wed Jul 30 07:37:54 2014 -0700 + | | summary: wip commit + | | + o | changeset: 91936:33e3949056ae + |/ user: Demian Brecht + | date: Wed Jul 30 07:18:38 2014 -0700 + | summary: fix for issue42 + | + o changeset: 91935:79a5fbe2c78f + | parent: 91933:fbd104359ef8 + | user: Antoine Pitrou + | date: Tue Jul 29 19:41:11 2014 -0400 + | summary: Issue #22003: When initialized from a bytes object, io.BytesIO() now + + +Continue work on issueB +----------------------- + +Work can now be continued on issueB: + +.. code-block:: bash + + hg update myfeature + +Workflow comparison +=================== + +Comparing against the git workflow above (skipping optional steps), the hg +equivalent in its entirety looks like this: + +.. code-block:: bash + + # git clone git@github.com:python/cpython.git + hg clone https://hg.python.org/cpython + + # work on issueA + # git checkout -b issueA + # git commit -a + hg bookmark issueA + hg commit + + # start work on issueB + # git checkout master + hg update [revision_number] + + # git checkout -b issueB + # git commit -a + hg bookmark issueB + hg commit + + # address review comments and merge + # git checkout issueA + # git commit -a + hg update issueA + hg commit + + # merge/send patch + + # continue working on issueB + # git checkout [feature_name] + hg update issueB diff -r 9b574ea00cde -r cadc468e9a5a index.rst --- a/index.rst Tue Dec 02 01:32:55 2014 +0100 +++ b/index.rst Wed Dec 03 16:06:21 2014 -0800 @@ -49,6 +49,7 @@ * `Buildbot status`_ * :doc:`faq` * PEPs_ (Python Enhancement Proposals) +* :doc:`gitdevs` .. _contributing: @@ -209,6 +210,7 @@ compiler coverity clang + gitdevs faq