unexist.dev

Changeset 370:a69f6d10da84

Updated hggit extension
author unexist
date Sun, 07 Aug 2011 15:57:53 +0200
parents 8d07d1399494
children 18014711b856
files .hgext/hg-git/.gitignore .hgext/hg-git/COPYING .hgext/hg-git/DESIGN.txt .hgext/hg-git/Makefile .hgext/hg-git/README.md .hgext/hg-git/TODO.txt .hgext/hg-git/hggit/__init__.py .hgext/hg-git/hggit/_ssh.py .hgext/hg-git/hggit/git_handler.py .hgext/hg-git/hggit/gitrepo.py .hgext/hg-git/hggit/hgrepo.py .hgext/hg-git/hggit/overlay.py .hgext/hg-git/hggit/util.py .hgext/hg-git/setup.py .hgext/hg-git/tests/latin-1-encoding .hgext/hg-git/tests/run-tests.py .hgext/hg-git/tests/test-conflict-1 .hgext/hg-git/tests/test-conflict-1.out .hgext/hg-git/tests/test-conflict-2 .hgext/hg-git/tests/test-conflict-2.out .hgext/hg-git/tests/test-convergedmerge .hgext/hg-git/tests/test-convergedmerge.out .hgext/hg-git/tests/test-empty-working-tree .hgext/hg-git/tests/test-empty-working-tree.out .hgext/hg-git/tests/test-encoding .hgext/hg-git/tests/test-encoding.out .hgext/hg-git/tests/test-file-removal .hgext/hg-git/tests/test-file-removal.out .hgext/hg-git/tests/test-git-clone .hgext/hg-git/tests/test-git-clone.out .hgext/hg-git/tests/test-git-submodules .hgext/hg-git/tests/test-git-submodules.out .hgext/hg-git/tests/test-git-tags .hgext/hg-git/tests/test-git-tags.out .hgext/hg-git/tests/test-git-workflow .hgext/hg-git/tests/test-git-workflow.out .hgext/hg-git/tests/test-hg-author .hgext/hg-git/tests/test-hg-author.out .hgext/hg-git/tests/test-hg-branch .hgext/hg-git/tests/test-hg-branch.out .hgext/hg-git/tests/test-hg-tags .hgext/hg-git/tests/test-hg-tags.out .hgext/hg-git/tests/test-incoming .hgext/hg-git/tests/test-incoming.out .hgext/hg-git/tests/test-merge .hgext/hg-git/tests/test-merge.out .hgext/hg-git/tests/test-octopus .hgext/hg-git/tests/test-octopus.out .hgext/hg-git/tests/test-outgoing .hgext/hg-git/tests/test-outgoing.out .hgext/hg-git/tests/test-pull .hgext/hg-git/tests/test-pull-after-strip .hgext/hg-git/tests/test-pull-after-strip.out .hgext/hg-git/tests/test-pull.out .hgext/hg-git/tests/test-push .hgext/hg-git/tests/test-push-r .hgext/hg-git/tests/test-push-r.out .hgext/hg-git/tests/test-push.out .hgext/hg-git/tests/test-sane-without-bookmarks .hgext/hg-git/tests/test-sane-without-bookmarks.out .hgext/hg-git/tests/test-tree-decomposition .hgext/hg-git/tests/test-tree-decomposition.out .hgext/hg-git/tests/test-url-parsing.py .hgext/hg-git/tests/test-url-parsing.py.out .hgext/hggit/COPYING .hgext/hggit/DESIGN.txt .hgext/hggit/Makefile .hgext/hggit/README.md .hgext/hggit/TODO.txt .hgext/hggit/hggit/__init__.py .hgext/hggit/hggit/__init__.pyc .hgext/hggit/hggit/_ssh.py .hgext/hggit/hggit/git_handler.py .hgext/hggit/hggit/git_handler.pyc .hgext/hggit/hggit/gitrepo.py .hgext/hggit/hggit/gitrepo.pyc .hgext/hggit/hggit/hgrepo.py .hgext/hggit/hggit/hgrepo.pyc .hgext/hggit/hggit/util.py .hgext/hggit/setup.py .hgext/hggit/tests/latin-1-encoding .hgext/hggit/tests/run-tests.py .hgext/hggit/tests/test-empty-working-tree .hgext/hggit/tests/test-empty-working-tree.out .hgext/hggit/tests/test-encoding .hgext/hggit/tests/test-encoding.out .hgext/hggit/tests/test-file-removal .hgext/hggit/tests/test-file-removal.out .hgext/hggit/tests/test-git-clone .hgext/hggit/tests/test-git-clone.out .hgext/hggit/tests/test-git-submodules .hgext/hggit/tests/test-git-submodules.out .hgext/hggit/tests/test-git-tags .hgext/hggit/tests/test-git-tags.out .hgext/hggit/tests/test-git-workflow .hgext/hggit/tests/test-git-workflow.out .hgext/hggit/tests/test-hg-author .hgext/hggit/tests/test-hg-author.out .hgext/hggit/tests/test-hg-branch .hgext/hggit/tests/test-hg-branch.out .hgext/hggit/tests/test-hg-tags .hgext/hggit/tests/test-hg-tags.out .hgext/hggit/tests/test-merge .hgext/hggit/tests/test-merge.out .hgext/hggit/tests/test-octopus .hgext/hggit/tests/test-octopus.out .hgext/hggit/tests/test-outgoing .hgext/hggit/tests/test-outgoing.out .hgext/hggit/tests/test-pull .hgext/hggit/tests/test-pull-after-strip .hgext/hggit/tests/test-pull-after-strip.out .hgext/hggit/tests/test-pull.out .hgext/hggit/tests/test-push .hgext/hggit/tests/test-push-r .hgext/hggit/tests/test-push-r.out .hgext/hggit/tests/test-push.out .hgext/hggit/tests/test-sane-without-bookmarks .hgext/hggit/tests/test-sane-without-bookmarks.out .hgext/hggit/tests/test-tree-decomposition .hgext/hggit/tests/test-tree-decomposition.out .hgext/hggit/tests/test-url-parsing.py .hgext/hggit/tests/test-url-parsing.py.out
diffstat 122 files changed, 6109 insertions(+), 5290 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/.gitignore	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,5 @@
+*.pyc
+tests/*.err
+build
+dist
+*.egg-info
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/COPYING	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,340 @@
+		    GNU GENERAL PUBLIC LICENSE
+		       Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+			    Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+		    GNU GENERAL PUBLIC LICENSE
+   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+			    NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+		     END OF TERMS AND CONDITIONS
+
+	    How to Apply These Terms to Your New Programs
+
+  If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+  To do so, attach the following notices to the program.  It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+    <one line to give the program's name and a brief idea of what it does.>
+    Copyright (C) <year>  <name of author>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+    Gnomovision version 69, Copyright (C) year  name of author
+    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+    This is free software, and you are welcome to redistribute it
+    under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License.  Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary.  Here is a sample; alter the names:
+
+  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+  `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+  <signature of Ty Coon>, 1 April 1989
+  Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs.  If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library.  If this is what you want to do, use the GNU Library General
+Public License instead of this License.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/DESIGN.txt	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,69 @@
+Hg-Git Plugin Design Notes
+==========================
+
+This plugin is designed to allow you to push to a Git server over the Git protocol and to pull from a Git based project.  All data is stored in Hg native format with a mapping table.  People collaborating in Git should not  even be able to tell that you're using Hg to collaborate on their project (except for the '--HG--' section added to commit message). 
+
+Nothing should need to be kept in the Git format - you should be able to run 'hg gclear' at any time to wipe out the Git directory and everything can be rebuilt losslessly from the existing Hg data - it is a cache only.
+
+We are using the Dulwich library, which I've modified quite a bit - I'll have to get these changes back upstream at some point.
+
+I've been adding 'TODO' comments all over the place where I only partially implemented something so I could get the entire first draft of functionality completed.  The TODO areas should be mostly edge cases (executable bits, file rename info, tags, submodules, etc).
+
+Lossless Two Way
+================
+
+We need to store data that Git records that Merc does not in a git/extra_data file.  This would be parents over two and committer information (author will be mapped to Hg committer).  This way two Hg developers can collaborate without the Git transport messing up the local commits.
+
+Each Git commit should be reproducible as a Merc ID and vice versa on any system without losing data (ie changing the SHA).
+
+Branch Translation Policy
+=========================
+
+Branches in Hg and Git are pretty different.  This is meant to provide a clear policy on how one is converted to the other.
+
+* Without Bookmarks: *
+
+If you don't have bookmarks enabled, Git simply maps your 'tip' to the 'master' branch of the repository you're pushing to, since that is the most commonly used default branch name.  Actually, pulling will map whatever the server points to as HEAD, but when pushing it will assume 'master' is your tip.
+
+	$ hg gpush origin        # will push tip to remote 'master'
+	$ hg gpush origin master # same as above
+	$ hg gpush origin --all  # same as above
+
+If the remote server has divergent branches (branches with commits not reachable from HEAD) it will basically ignore them, not convert them into Hg changesets.  It will tell you this (and why) when fetched.
+
+Conversely, on pushing, Hg named branches are ignored if they are not reachable from traversing the parents of tip. (SC: is this best?)
+
+* With Bookmarks: *
+
+If you have bookmarks enabled, it will treat your bookmarks like Git branches and will only push up references if you specify them.
+
+	hg gpush origin        # will error, you have to specify a branch
+	hg gpush origin master # pushes the master branch
+	hg gpush origin --all  # pushes all local branches
+
+If a fetch gets branches, it _will_ import them and will create bookmarks that point to them, even if they have no common ancestors with the mainline (HEAD).
+
+* Other points *
+
+If you do not specify a remote name, it will assume 'origin'.  This is helpful if you do not have bookmarks enabled as it will push tip automatically.  If you have bookmarks enabled this is not helpful because you have to specify a branch name after.
+
+Eventually, I would like to setup tracking branch refspecs much like Git - say 'this local branch pushes and pulls to/from this remote and branch', but that will be one of the last things done.
+
+Testing Hg-Git
+==============
+
+Tests are implemented in the Mercurial-standard way of small shell scripts.
+The scripts are located in the tests directory, and to run them you should
+change to that directory and then run tests/run-tests.py from the Mercurial
+sources. For example, if you have a copy of the Mercurial source code at
+/Stuff/hg-crew, you would do something like this:
+
+cd tests ; /Stuff/hg-crew/tests/run-tests.py
+
+And you should see output like this:
+.
+# Ran 1 tests, 0 skipped, 0 failed.
+
+Note that due to limitations of Dulwich at the moment, the tests need to
+start a git-daemon process. Right now, they use the default port, so will
+skip if they detect an already-running git-daemon.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/Makefile	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,25 @@
+PYTHON=python
+
+help:
+	@echo 'Commonly used make targets:'
+	@echo '  tests              - run all tests in the automatic test suite'
+	@echo '  all-version-tests - run all tests against many hg versions'
+	@echo '  tests-%s           - run all tests in the specified hg version'
+
+all: help
+
+tests:
+	cd tests && $(PYTHON) run-tests.py --with-hg=`which hg` $(TESTFLAGS)
+
+test-%:
+	cd tests && $(PYTHON) run-tests.py --with-hg=`which hg` $(TESTFLAGS) $@
+
+tests-%:
+	@echo "Path to crew repo is $(CREW) - set this with CREW= if needed."
+	hg -R $(CREW) checkout $$(echo $@ | sed s/tests-//) && \
+	(cd $(CREW) ; $(MAKE) clean ) && \
+	cd tests && $(PYTHON) $(CREW)/tests/run-tests.py $(TESTFLAGS)
+
+all-version-tests: tests-1.4.3 tests-1.5.4 tests-1.6.2 tests-1.7.2 tests-tip
+
+.PHONY: tests all-version-tests
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/README.md	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,156 @@
+Hg-Git Mercurial Plugin
+=======================
+
+This is the Hg-Git plugin for Mercurial, adding the ability to push
+and pull to/from a Git server repository from Hg.  This means you can
+collaborate on Git based projects from Hg, or use a Git server as a
+collaboration point for a team with developers using both Git and Hg.
+
+The Hg-Git plugin can convert commits/changesets losslessly from one
+system to another, so you can push via an Hg repository and another Hg
+client can pull it and their changeset node ids will be identical -
+Mercurial data does not get lost in translation.  It is intended that
+Hg users may wish to use this to collaborate even if no Git users are
+involved in the project, and it may even provide some advantages if
+you're using Bookmarks (see below).
+
+Dependencies
+============
+
+This plugin is implemented entirely in Python - there are no Git
+binary dependencies, you do not need to have Git installed on your
+system.  The only dependencies are Mercurial and Dulwich.  The plugin
+is known to work on Hg versions 1.3 through 1.5 and requires at least
+Dulwich 0.6.0.
+
+Usage
+=====
+
+You can clone a Git repository from Hg by running `hg clone [url]`.  For
+example, if you were to run
+
+    $ hg clone git://github.com/schacon/hg-git.git
+
+hg-git would clone the repository down into the directory 'munger.git', then
+convert it to an Hg repository for you.
+
+If you want to clone a github repository for later pushing (or any
+other repository you access via ssh), you need to convert the ssh url
+to a format with an explicit protocol prefix. For example, the git url
+with push access
+
+    git@github.com:schacon/hg-git.git
+
+would read
+
+    git+ssh://git@github.com/schacon/hg-git.git
+
+(Mind the switch from colon to slash after the host!)
+
+Your clone command would thus look like this:
+
+    $ hg clone git+ssh://git@github.com/schacon/hg-git.git
+
+If you are starting from an existing Hg repository, you have to setup
+a Git repository somewhere that you have push access to, add it as
+default path or default-push path in your .hg/hgrc and then run `hg
+push` from within your project.  For example:
+
+    $ cd hg-git # (an Hg repository)
+    $ # edit .hg/hgrc and add the target git url in the paths section
+    $ hg push
+
+This will convert all your Hg data into Git objects and push them up to the Git server.
+
+Now that you have an Hg repository that can push/pull to/from a Git
+repository, you can fetch updates with `hg pull`.
+
+    $ hg pull
+
+That will pull down any commits that have been pushed to the server in
+the meantime and give you a new head that you can merge in.
+
+Hg-Git can also be used to convert a Mercurial repository to Git.  As
+Dulwich doesn't support local repositories yet, the easiest way is to
+setup up a local SSH server.  Then use the following commands to
+convert the repository (it assumes your running this in $HOME).
+
+    $ mkdir git-repo; cd git-repo; git init; cd ..
+    $ cd hg-repo
+    $ hg bookmarks hg
+    $ hg push git+ssh://localhost:git-repo
+
+The hg bookmark is necessary to prevent problems as otherwise hg-git
+pushes to the currently checked out branch confusing Git. This will
+create a branch named hg in the Git repository. To get the changes in
+master use the following command (only necessary in the first run,
+later just use git merge or rebase).
+
+    $ cd git-repo
+    $ git checkout -b master hg
+
+To import new changesets into the Git repository just rerun the hg
+push command and then use git merge or git rebase in your Git
+repository.
+
+Commands
+========
+
+gclear
+------
+
+TODO
+
+gimport
+-------
+
+TODO
+
+gexport
+-------
+
+TODO
+
+git-cleanup
+-----------
+
+TODO
+
+Hg Bookmarks Integration
+========================
+
+If you have the bookmarks extension enabled, Hg-Git will use it. It
+will push your bookmarks up to the Git server as branches and will
+pull Git branches down and set them up as bookmarks.
+
+This is actually pretty cool, since you can use this extension to
+transfer your Hg bookmarks via the Git protocol, rather than having to
+scp them, as the Hg transfer protocol does not currently support
+transferring bookmarks.
+
+Installing
+==========
+
+Clone this repository somewhere and make the 'extensions' section in
+your `~/.hgrc` file look something like this:
+
+    [extensions]
+    hgext.bookmarks =
+    hggit = [path-to]/hg-git/hggit
+
+That will enable the Hg-Git extension for you.  The bookmarks section
+is not compulsory, but it makes some things a bit nicer for you.
+
+Configuration
+=============
+
+git.intree
+----------
+
+hg-git keeps a git repository clone for reading and updating. By default, the
+git clone is the subdirectory `git` in your local Mercurial repository. If you
+would like this git clone to be at the same level of your Mercurial repository
+instead (named `.git`), add the following to your `hgrc`:
+
+    [git]
+    intree = True
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/TODO.txt	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,33 @@
+GENERAL
+==========
+* work fine with eclipse plugin or tortoise-hg
+
+MAPPING ISSUES
+==============
+* work in Git on a named branch created in Hg is forward-ported to be named branch commits in Hg and stripped back out if re-exported
+
+
+REMOTE/BRANCH STUFF
+=====================
+* explain what branch mapping policy determined when updating refs
+* error nicer if pushing to remote without push access (over git://)
+
+WEBSITE
+===========
+* more usage documentation
+* screencast
+
+
+SPEED/EFFICIENCY
+================
+* dulwich improvements
+  - don't send blobs/trees already on server
+  - thin packs
+  - packfile creation benchmarking (seems to take a while sometimes)
+  - at least provide status output
+
+MAYBE
+==========
+* submodules?
+* .gitignore, etc - try to convert? 
+  - (probably not automatically, but perhaps a generator?)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/hggit/__init__.py	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,184 @@
+# git.py - git server bridge
+#
+# Copyright 2008 Scott Chacon <schacon at gmail dot com>
+#   also some code (and help) borrowed from durin42
+#
+# This software may be used and distributed according to the terms
+# of the GNU General Public License, incorporated herein by reference.
+
+'''push and pull from a Git server
+
+This extension lets you communicate (push and pull) with a Git server.
+This way you can use Git hosting for your project or collaborate with a
+project that is in Git.  A bridger of worlds, this plugin be.
+
+Try hg clone git:// or hg clone git+ssh://
+'''
+
+import inspect
+import os
+
+from mercurial import bundlerepo
+from mercurial import commands
+from mercurial import demandimport
+from mercurial import extensions
+from mercurial import hg
+from mercurial import localrepo
+from mercurial import util as hgutil
+from mercurial import url
+from mercurial.i18n import _
+
+demandimport.ignore.extend([
+    'collections',
+    ])
+
+import gitrepo, hgrepo
+from git_handler import GitHandler
+
+# support for `hg clone git://github.com/defunkt/facebox.git`
+# also hg clone git+ssh://git@github.com/schacon/simplegit.git
+hg.schemes['git'] = gitrepo
+hg.schemes['git+ssh'] = gitrepo
+
+# support for `hg clone localgitrepo`
+_oldlocal = hg.schemes['file']
+
+try:
+    urlcls = hgutil.url
+except AttributeError:
+    class urlcls(object):
+        def __init__(self, path):
+            self.p = hgutil.drop_scheme('file', path)
+
+        def localpath(self):
+            return self.p
+
+def _local(path):
+    p = urlcls(path).localpath()
+    if (os.path.exists(os.path.join(p, '.git')) and
+        not os.path.exists(os.path.join(p, '.hg'))):
+        return gitrepo
+    # detect a bare repository
+    if (os.path.exists(os.path.join(p, 'HEAD')) and
+        os.path.exists(os.path.join(p, 'objects')) and
+        os.path.exists(os.path.join(p, 'refs')) and
+        not os.path.exists(os.path.join(p, '.hg'))):
+        return gitrepo
+    return _oldlocal(path)
+
+hg.schemes['file'] = _local
+
+hgdefaultdest = hg.defaultdest
+def defaultdest(source):
+    for scheme in ('git', 'git+ssh'):
+        if source.startswith('%s://' % scheme) and source.endswith('.git'):
+            source = source[:-4]
+            break
+    return hgdefaultdest(source)
+hg.defaultdest = defaultdest
+
+# defend against tracebacks if we specify -r in 'hg pull'
+def safebranchrevs(orig, lrepo, repo, branches, revs):
+    revs, co = orig(lrepo, repo, branches, revs)
+    if getattr(lrepo, 'changelog', False) and co not in lrepo.changelog:
+        co = None
+    return revs, co
+if getattr(hg, 'addbranchrevs', False):
+    extensions.wrapfunction(hg, 'addbranchrevs', safebranchrevs)
+
+def reposetup(ui, repo):
+    if not isinstance(repo, gitrepo.gitrepo):
+        klass = hgrepo.generate_repo_subclass(repo.__class__)
+        repo.__class__ = klass
+
+def gimport(ui, repo, remote_name=None):
+    git = GitHandler(repo, ui)
+    git.import_commits(remote_name)
+
+def gexport(ui, repo):
+    git = GitHandler(repo, ui)
+    git.export_commits()
+
+def gclear(ui, repo):
+    repo.ui.status(_("clearing out the git cache data\n"))
+    git = GitHandler(repo, ui)
+    git.clear()
+
+def git_cleanup(ui, repo):
+    new_map = []
+    for line in repo.opener(GitHandler.mapfile):
+        gitsha, hgsha = line.strip().split(' ', 1)
+        if hgsha in repo:
+            new_map.append('%s %s\n' % (gitsha, hgsha))
+    f = repo.opener(GitHandler.mapfile, 'wb')
+    map(f.write, new_map)
+    ui.status(_('git commit map cleaned\n'))
+
+# drop this when we're 1.6-only, this just backports new behavior
+def sortednodetags(orig, *args, **kwargs):
+    ret = orig(*args, **kwargs)
+    ret.sort()
+    return ret
+extensions.wrapfunction(localrepo.localrepository, 'nodetags', sortednodetags)
+
+try:
+    from mercurial import discovery
+    kwname = 'heads'
+    if hg.util.version() >= '1.7':
+        kwname = 'remoteheads'
+    if getattr(discovery, 'findcommonoutgoing', None):
+        kwname = 'onlyheads'
+    def findoutgoing(orig, local, remote, *args, **kwargs):
+        if isinstance(remote, gitrepo.gitrepo):
+            # clean up this cruft when we're 1.7-only, remoteheads and
+            # the return value change happened between 1.6 and 1.7.
+            kw = {}
+            kw.update(kwargs)
+            for val, k in zip(args, ('base', kwname, 'force')):
+                kw[k] = val
+            git = GitHandler(local, local.ui)
+            base, heads = git.get_refs(remote.path)
+            newkw = {'base': base, kwname: heads}
+            newkw.update(kw)
+            kw = newkw
+            if kwname == 'heads':
+                r = orig(local, remote, **kw)
+                return [x[0] for x in r]
+            if kwname == 'onlyheads':
+                del kw['base']
+            return orig(local, remote, **kw)
+        return orig(local, remote, *args, **kwargs)
+    if getattr(discovery, 'findoutgoing', None):
+        extensions.wrapfunction(discovery, 'findoutgoing', findoutgoing)
+    else:
+        extensions.wrapfunction(discovery, 'findcommonoutgoing',
+                                findoutgoing)
+except ImportError:
+    pass
+
+def getremotechanges(orig, ui, repo, other, *args, **opts):
+    if isinstance(other, gitrepo.gitrepo):
+        revs = opts.get('onlyheads', opts.get('revs'))
+        git = GitHandler(repo, ui)
+        r, c, cleanup = git.getremotechanges(other, revs)
+        # ugh. This is ugly even by mercurial API compatibility standards
+        if 'onlyheads' not in orig.func_code.co_varnames:
+            cleanup = None
+        return r, c, cleanup
+    return orig(ui, repo, other, *args, **opts)
+try:
+    extensions.wrapfunction(bundlerepo, 'getremotechanges', getremotechanges)
+except AttributeError:
+    # 1.7+
+    pass
+
+cmdtable = {
+  "gimport":
+        (gimport, [], _('hg gimport')),
+  "gexport":
+        (gexport, [], _('hg gexport')),
+  "gclear":
+      (gclear, [], _('Clears out the Git cached data')),
+  "git-cleanup": (git_cleanup, [], _(
+        "Cleans up git repository after history editing"))
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/hggit/_ssh.py	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,30 @@
+from mercurial import util
+
+class SSHVendor(object):
+    """Parent class for ui-linked Vendor classes."""
+
+
+def generate_ssh_vendor(ui):
+    """
+    Allows dulwich to use hg's ui.ssh config. The dulwich.client.get_ssh_vendor
+    property should point to the return value.
+    """
+
+    class _Vendor(SSHVendor):
+        def connect_ssh(self, host, command, username=None, port=None):
+            from dulwich.client import SubprocessWrapper
+            from mercurial import util
+            import subprocess
+
+            sshcmd = ui.config("ui", "ssh", "ssh")
+            args = util.sshargs(sshcmd, host, username, port)
+            cmd = '%s %s %s' % (sshcmd, args, 
+                                util.shellquote(' '.join(command)))
+            ui.debug('calling ssh: %s\n' % cmd)
+            print command
+            proc = subprocess.Popen(util.quotecommand(cmd), shell=True,
+                                    stdin=subprocess.PIPE,
+                                    stdout=subprocess.PIPE)
+            return SubprocessWrapper(proc)
+
+    return _Vendor
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/hggit/git_handler.py	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,1083 @@
+import os, math, urllib, re
+
+from dulwich.errors import HangupException, GitProtocolError
+from dulwich.index import commit_tree
+from dulwich.objects import Blob, Commit, Tag, Tree, parse_timezone
+from dulwich.pack import create_delta, apply_delta
+from dulwich.repo import Repo
+from dulwich import client
+
+try:
+    from mercurial import bookmarks
+    bookmarks.update
+    from mercurial import commands
+except ImportError:
+    from hgext import bookmarks
+from mercurial.i18n import _
+from mercurial.node import hex, bin, nullid
+from mercurial import context, util as hgutil
+from mercurial import error
+
+import _ssh
+import util
+from overlay import overlayrepo
+
+class GitProgress(object):
+    """convert git server progress strings into mercurial progress"""
+    def __init__(self, ui):
+        self.ui = ui
+
+        self.lasttopic = None
+        self.msgbuf = ''
+
+    def progress(self, msg):
+        # 'Counting objects: 33640, done.\n'
+        # 'Compressing objects:   0% (1/9955)   \r
+        msgs = re.split('[\r\n]', self.msgbuf + msg)
+        self.msgbuf = msgs.pop()
+
+        for msg in msgs:
+            td = msg.split(':', 1)
+            data = td.pop()
+            if not td:
+                self.flush(data)
+                continue
+            topic = td[0]
+
+            m = re.search('\((\d+)/(\d+)\)', data)
+            if m:
+                if self.lasttopic and self.lasttopic != topic:
+                    self.flush()
+                self.lasttopic = topic
+
+                pos, total = map(int, m.group(1, 2))
+                util.progress(self.ui, topic, pos, total=total)
+            else:
+                self.flush(msg)
+
+    def flush(self, msg=None):
+        if self.lasttopic:
+            util.progress(self.ui, self.lasttopic, None)
+        self.lasttopic = None
+        if msg:
+            self.ui.note(msg + '\n')
+
+class GitHandler(object):
+    mapfile = 'git-mapfile'
+    tagsfile = 'git-tags'
+
+    def __init__(self, dest_repo, ui):
+        self.repo = dest_repo
+        self.ui = ui
+
+        if ui.configbool('git', 'intree'):
+            self.gitdir = self.repo.wjoin('.git')
+        else:
+            self.gitdir = self.repo.join('git')
+
+        self.paths = ui.configitems('paths')
+
+        self.load_map()
+        self.load_tags()
+
+    # make the git data directory
+    def init_if_missing(self):
+        if os.path.exists(self.gitdir):
+            self.git = Repo(self.gitdir)
+        else:
+            os.mkdir(self.gitdir)
+            self.git = Repo.init_bare(self.gitdir)
+
+    ## FILE LOAD AND SAVE METHODS
+
+    def map_set(self, gitsha, hgsha):
+        self._map_git[gitsha] = hgsha
+        self._map_hg[hgsha] = gitsha
+
+    def map_hg_get(self, gitsha):
+        return self._map_git.get(gitsha)
+
+    def map_git_get(self, hgsha):
+        return self._map_hg.get(hgsha)
+
+    def load_map(self):
+        self._map_git = {}
+        self._map_hg = {}
+        if os.path.exists(self.repo.join(self.mapfile)):
+            for line in self.repo.opener(self.mapfile):
+                gitsha, hgsha = line.strip().split(' ', 1)
+                self._map_git[gitsha] = hgsha
+                self._map_hg[hgsha] = gitsha
+
+    def save_map(self):
+        file = self.repo.opener(self.mapfile, 'w+', atomictemp=True)
+        for hgsha, gitsha in sorted(self._map_hg.iteritems()):
+            file.write("%s %s\n" % (gitsha, hgsha))
+        file.rename()
+
+    def load_tags(self):
+        self.tags = {}
+        if os.path.exists(self.repo.join(self.tagsfile)):
+            for line in self.repo.opener(self.tagsfile):
+                sha, name = line.strip().split(' ', 1)
+                self.tags[name] = sha
+
+    def save_tags(self):
+        file = self.repo.opener(self.tagsfile, 'w+', atomictemp=True)
+        for name, sha in sorted(self.tags.iteritems()):
+            if not self.repo.tagtype(name) == 'global':
+                file.write("%s %s\n" % (sha, name))
+        file.rename()
+
+    ## END FILE LOAD AND SAVE METHODS
+
+    ## COMMANDS METHODS
+
+    def import_commits(self, remote_name):
+        self.import_git_objects(remote_name)
+        self.save_map()
+
+    def fetch(self, remote, heads):
+        self.export_commits()
+        refs = self.fetch_pack(remote, heads)
+        remote_name = self.remote_name(remote)
+
+        oldrefs = self.git.get_refs()
+        if refs:
+            self.import_git_objects(remote_name, refs)
+            self.import_tags(refs)
+            self.update_hg_bookmarks(refs)
+            if remote_name:
+                self.update_remote_branches(remote_name, refs)
+            elif not self.paths:
+                # intial cloning
+                self.update_remote_branches('default', refs)
+
+                # "Activate" a tipmost bookmark.
+                bms = getattr(self.repo['tip'], 'bookmarks',
+                              lambda : None)()
+                if bms:
+                    bookmarks.setcurrent(self.repo, bms[0])
+
+        def remoteref(ref):
+            rn = remote_name or 'default'
+            return 'refs/remotes/' + rn + ref[10:]
+
+        modheads = [refs[k] for k in refs if k.startswith('refs/heads/')
+                    and not k.endswith('^{}')
+                    and refs[k] != oldrefs.get(remoteref(k))]
+
+        if not modheads:
+            self.ui.status(_("no changes found\n"))
+
+        self.save_map()
+
+        return len(modheads)
+
+    def export_commits(self):
+        try:
+            self.export_git_objects()
+            self.export_hg_tags()
+            self.update_references()
+        finally:
+            self.save_map()
+
+    def get_refs(self, remote):
+        self.export_commits()
+        client, path = self.get_transport_and_path(remote)
+        old_refs = {}
+        new_refs = {}
+        def changed(refs):
+            old_refs.update(refs)
+            to_push = set(self.local_heads().values() + self.tags.values())
+            new_refs.update(self.get_changed_refs(refs, to_push, True))
+            # don't push anything
+            return {}
+
+        try:
+            client.send_pack(path, changed, None)
+
+            changed_refs = [ref for ref, sha in new_refs.iteritems()
+                            if sha != old_refs.get(ref)]
+            new = [bin(self.map_hg_get(new_refs[ref])) for ref in changed_refs]
+            old = {}
+            for r in old_refs:
+                old_ref = self.map_hg_get(old_refs[r])
+                if old_ref:
+                    old[bin(old_ref)] = 1
+
+            return old, new
+        except (HangupException, GitProtocolError), e:
+            raise hgutil.Abort(_("git remote error: ") + str(e))
+
+    def push(self, remote, revs, force):
+        self.export_commits()
+        changed_refs = self.upload_pack(remote, revs, force)
+        remote_name = self.remote_name(remote)
+
+        if remote_name and changed_refs:
+            for ref, sha in changed_refs.iteritems():
+                self.ui.status("    %s::%s => GIT:%s\n" %
+                               (remote_name, ref, sha[0:8]))
+
+            self.update_remote_branches(remote_name, changed_refs)
+
+    def clear(self):
+        mapfile = self.repo.join(self.mapfile)
+        if os.path.exists(self.gitdir):
+            for root, dirs, files in os.walk(self.gitdir, topdown=False):
+                for name in files:
+                    os.remove(os.path.join(root, name))
+                for name in dirs:
+                    os.rmdir(os.path.join(root, name))
+            os.rmdir(self.gitdir)
+        if os.path.exists(mapfile):
+            os.remove(mapfile)
+
+    # incoming support
+    def getremotechanges(self, remote, revs):
+        self.export_commits()
+        refs = self.fetch_pack(remote.path, revs)
+
+        # refs contains all remote refs. Prune to only those requested.
+        if revs:
+            reqrefs = {}
+            for rev in revs:
+                for n in ('refs/heads/' + rev, 'refs/tags/' + rev):
+                    if n in refs:
+                        reqrefs[n] = refs[n]
+        else:
+            reqrefs = refs
+
+        commits = [bin(c) for c in self.getnewgitcommits(reqrefs)[1]]
+
+        b = overlayrepo(self, commits, refs)
+
+        return (b, commits, lambda: None)
+
+    ## CHANGESET CONVERSION METHODS
+
+    def export_git_objects(self):
+        self.init_if_missing()
+
+        nodes = [self.repo.lookup(n) for n in self.repo]
+        export = [node for node in nodes if not hex(node) in self._map_hg]
+        total = len(export)
+        if total:
+            self.ui.status(_("exporting hg objects to git\n"))
+        for i, rev in enumerate(export):
+            util.progress(self.ui, 'exporting', i, total=total)
+            ctx = self.repo.changectx(rev)
+            state = ctx.extra().get('hg-git', None)
+            if state == 'octopus':
+                self.ui.debug("revision %d is a part "
+                              "of octopus explosion\n" % ctx.rev())
+                continue
+            self.export_hg_commit(rev)
+        util.progress(self.ui, 'importing', None, total=total)
+
+
+    # convert this commit into git objects
+    # go through the manifest, convert all blobs/trees we don't have
+    # write the commit object (with metadata info)
+    def export_hg_commit(self, rev):
+        self.ui.note(_("converting revision %s\n") % hex(rev))
+
+        oldenc = self.swap_out_encoding()
+
+        ctx = self.repo.changectx(rev)
+        extra = ctx.extra()
+
+        commit = Commit()
+
+        (time, timezone) = ctx.date()
+        commit.author = self.get_git_author(ctx)
+        commit.author_time = int(time)
+        commit.author_timezone = -timezone
+
+        if 'committer' in extra:
+            # fixup timezone
+            (name, timestamp, timezone) = extra['committer'].rsplit(' ', 2)
+            commit.committer = name
+            commit.commit_time = timestamp
+
+            # work around a timezone format change
+            if int(timezone) % 60 != 0: #pragma: no cover
+                timezone = parse_timezone(timezone)
+                # Newer versions of Dulwich return a tuple here
+                if isinstance(timezone, tuple):
+                    timezone, neg_utc = timezone
+                    commit._commit_timezone_neg_utc = neg_utc
+            else:
+                timezone = -int(timezone)
+            commit.commit_timezone = timezone
+        else:
+            commit.committer = commit.author
+            commit.commit_time = commit.author_time
+            commit.commit_timezone = commit.author_timezone
+
+        commit.parents = []
+        for parent in self.get_git_parents(ctx):
+            hgsha = hex(parent.node())
+            git_sha = self.map_git_get(hgsha)
+            if git_sha:
+                commit.parents.append(git_sha)
+
+        commit.message = self.get_git_message(ctx)
+
+        if 'encoding' in extra:
+            commit.encoding = extra['encoding']
+
+        tree_sha = commit_tree(self.git.object_store, self.iterblobs(ctx))
+        commit.tree = tree_sha
+
+        self.git.object_store.add_object(commit)
+        self.map_set(commit.id, ctx.hex())
+
+        self.swap_out_encoding(oldenc)
+        return commit.id
+
+    def get_git_author(self, ctx):
+        # hg authors might not have emails
+        author = ctx.user()
+
+        # check for git author pattern compliance
+        regex = re.compile('^(.*?) \<(.*?)\>(.*)$')
+        a = regex.match(author)
+
+        if a:
+            name = a.group(1)
+            email = a.group(2)
+            if len(a.group(3)) > 0:
+                name += ' ext:(' + urllib.quote(a.group(3)) + ')'
+            author = name + ' <' + email + '>'
+        elif '@' in author:
+            author = author + ' <' + author + '>'
+        else:
+            author = author + ' <none@none>'
+
+        if 'author' in ctx.extra():
+            author = "".join(apply_delta(author, ctx.extra()['author']))
+
+        return author
+
+    def get_git_parents(self, ctx):
+        def is_octopus_part(ctx):
+            return ctx.extra().get('hg-git', None) in ('octopus', 'octopus-done')
+
+        parents = []
+        if ctx.extra().get('hg-git', None) == 'octopus-done':
+            # implode octopus parents
+            part = ctx
+            while is_octopus_part(part):
+                (p1, p2) = part.parents()
+                assert not is_octopus_part(p1)
+                parents.append(p1)
+                part = p2
+            parents.append(p2)
+        else:
+            parents = ctx.parents()
+
+        return parents
+
+    def get_git_message(self, ctx):
+        extra = ctx.extra()
+
+        message = ctx.description() + "\n"
+        if 'message' in extra:
+            message = "".join(apply_delta(message, extra['message']))
+
+        # HG EXTRA INFORMATION
+        add_extras = False
+        extra_message = ''
+        if not ctx.branch() == 'default':
+            add_extras = True
+            extra_message += "branch : " + ctx.branch() + "\n"
+
+        renames = []
+        for f in ctx.files():
+            if f not in ctx.manifest():
+                continue
+            rename = ctx.filectx(f).renamed()
+            if rename:
+                renames.append((rename[0], f))
+
+        if renames:
+            add_extras = True
+            for oldfile, newfile in renames:
+                extra_message += "rename : " + oldfile + " => " + newfile + "\n"
+
+        for key, value in extra.iteritems():
+            if key in ('author', 'committer', 'encoding', 'message', 'branch', 'hg-git'):
+                continue
+            else:
+                add_extras = True
+                extra_message += "extra : " + key + " : " +  urllib.quote(value) + "\n"
+
+        if add_extras:
+            message += "\n--HG--\n" + extra_message
+
+        return message
+
+    def iterblobs(self, ctx):
+        for f in ctx:
+            fctx = ctx[f]
+            blobid = self.map_git_get(hex(fctx.filenode()))
+
+            if not blobid:
+                blob = Blob.from_string(fctx.data())
+                self.git.object_store.add_object(blob)
+                self.map_set(blob.id, hex(fctx.filenode()))
+                blobid = blob.id
+
+            if 'l' in ctx.flags(f):
+                mode = 0120000
+            elif 'x' in ctx.flags(f):
+                mode = 0100755
+            else:
+                mode = 0100644
+
+            yield f, blobid, mode
+
+    def getnewgitcommits(self, refs=None):
+        self.init_if_missing()
+
+        # import heads and fetched tags as remote references
+        todo = []
+        done = set()
+        convert_list = {}
+
+        # get a list of all the head shas
+        seenheads = set()
+        if refs is None:
+            refs = self.git.refs.as_dict()
+        if refs:
+            for sha in refs.itervalues():
+                # refs contains all the refs in the server, not just the ones
+                # we are pulling
+                if sha in self.git.object_store:
+                    obj = self.git.get_object(sha)
+                    while isinstance(obj, Tag):
+                        obj_type, sha = obj.object
+                        obj = self.git.get_object(sha)
+                    if isinstance (obj, Commit) and sha not in seenheads:
+                        seenheads.add(sha)
+                        todo.append(sha)
+
+        # sort by commit date
+        def commitdate(sha):
+            obj = self.git.get_object(sha)
+            return obj.commit_time-obj.commit_timezone
+
+        todo.sort(key=commitdate, reverse=True)
+
+        # traverse the heads getting a list of all the unique commits
+        commits = []
+        seen = set(todo)
+        while todo:
+            sha = todo[-1]
+            if sha in done:
+                todo.pop()
+                continue
+            assert isinstance(sha, str)
+            obj = self.git.get_object(sha)
+            assert isinstance(obj, Commit)
+            for p in obj.parents:
+                if p not in done:
+                    todo.append(p)
+                    break
+            else:
+                commits.append(sha)
+                convert_list[sha] = obj
+                done.add(sha)
+                todo.pop()
+
+        return convert_list, [commit for commit in commits if not commit in self._map_git]
+
+    def import_git_objects(self, remote_name=None, refs=None):
+        convert_list, commits = self.getnewgitcommits(refs)
+        # import each of the commits, oldest first
+        total = len(commits)
+        if total:
+            self.ui.status(_("importing git objects into hg\n"))
+
+        for i, csha in enumerate(commits):
+            util.progress(self.ui, 'importing', i, total=total, unit='commits')
+            commit = convert_list[csha]
+            self.import_git_commit(commit)
+        util.progress(self.ui, 'importing', None, total=total, unit='commits')
+
+        # Remove any dangling tag references.
+        for name, rev in self.repo.tags().items():
+            if not rev in self.repo:
+                if hasattr(self, 'tagscache') and self.tagscache and \
+                        'name' in self.tagscache:
+                    # Mercurial 1.4 and earlier.
+                    del self.repo.tagscache[name]
+                elif hasattr(self, '_tags') and self._tags and \
+                        'name' in self._tags:
+                    # Mercurial 1.5 and later.
+                    del self.repo._tags[name]
+                if name in self.repo._tagtypes:
+                    del self.repo._tagtypes[name]
+
+    def import_git_commit(self, commit):
+        self.ui.debug(_("importing: %s\n") % commit.id)
+
+        (strip_message, hg_renames,
+         hg_branch, extra) = self.extract_hg_metadata(commit.message)
+
+        # get a list of the changed, added, removed files
+        files = self.get_files_changed(commit)
+
+        date = (commit.author_time, -commit.author_timezone)
+        text = strip_message
+
+        origtext = text
+        try:
+            text.decode('utf-8')
+        except UnicodeDecodeError:
+            text = self.decode_guess(text, commit.encoding)
+
+        text = '\n'.join([l.rstrip() for l in text.splitlines()]).strip('\n')
+        if text + '\n' != origtext:
+            extra['message'] = create_delta(text +'\n', origtext)
+
+        author = commit.author
+
+        # convert extra data back to the end
+        if ' ext:' in commit.author:
+            regex = re.compile('^(.*?)\ ext:\((.*)\) <(.*)\>$')
+            m = regex.match(commit.author)
+            if m:
+                name = m.group(1)
+                ex = urllib.unquote(m.group(2))
+                email = m.group(3)
+                author = name + ' <' + email + '>' + ex
+
+        if ' <none@none>' in commit.author:
+            author = commit.author[:-12]
+
+        try:
+            author.decode('utf-8')
+        except UnicodeDecodeError:
+            origauthor = author
+            author = self.decode_guess(author, commit.encoding)
+            extra['author'] = create_delta(author, origauthor)
+
+        oldenc = self.swap_out_encoding()
+
+        def findconvergedfiles(p1, p2):
+            # If any files have the same contents in both parents of a merge
+            # (and are therefore not reported as changed by Git) but are at
+            # different file revisions in Mercurial (because they arrived at
+            # those contents in different ways), we need to include them in
+            # the list of changed files so that Mercurial can join up their
+            # filelog histories (same as if the merge was done in Mercurial to
+            # begin with).
+            if p2 == nullid:
+                return []
+            manifest1 = self.repo.changectx(p1).manifest()
+            manifest2 = self.repo.changectx(p2).manifest()
+            return [path for path, node1 in manifest1.iteritems()
+                    if path not in files and manifest2.get(path, node1) != node1]
+
+        def getfilectx(repo, memctx, f):
+            info = files.get(f)
+            if info != None:
+                # it's a file reported as modified from Git
+                delete, mode, sha = info
+                if delete:
+                    raise IOError
+
+                data = self.git[sha].data
+                copied_path = hg_renames.get(f)
+                e = self.convert_git_int_mode(mode)
+            else:
+                # it's a converged file
+                fc = context.filectx(self.repo, f, changeid=memctx.p1().rev())
+                data = fc.data()
+                e = fc.flags()
+                copied_path = fc.renamed()
+
+            return context.memfilectx(f, data, 'l' in e, 'x' in e, copied_path)
+
+        gparents = map(self.map_hg_get, commit.parents)
+        p1, p2 = (nullid, nullid)
+        octopus = False
+
+        if len(gparents) > 1:
+            # merge, possibly octopus
+            def commit_octopus(p1, p2):
+                ctx = context.memctx(self.repo, (p1, p2), text,
+                                     list(files) + findconvergedfiles(p1, p2),
+                                     getfilectx, author, date, {'hg-git': 'octopus'})
+                return hex(self.repo.commitctx(ctx))
+
+            octopus = len(gparents) > 2
+            p2 = gparents.pop()
+            p1 = gparents.pop()
+            while len(gparents) > 0:
+                p2 = commit_octopus(p1, p2)
+                p1 = gparents.pop()
+        else:
+            if gparents:
+                p1 = gparents.pop()
+
+        pa = None
+        if not (p2 == nullid):
+            node1 = self.repo.changectx(p1)
+            node2 = self.repo.changectx(p2)
+            pa = node1.ancestor(node2)
+
+        # if named branch, add to extra
+        if hg_branch:
+            extra['branch'] = hg_branch
+
+        # if committer is different than author, add it to extra
+        if commit.author != commit.committer \
+               or commit.author_time != commit.commit_time \
+               or commit.author_timezone != commit.commit_timezone:
+            extra['committer'] = "%s %d %d" % (
+                commit.committer, commit.commit_time, -commit.commit_timezone)
+
+        if commit.encoding:
+            extra['encoding'] = commit.encoding
+
+        if hg_branch:
+            extra['branch'] = hg_branch
+
+        if octopus:
+            extra['hg-git'] ='octopus-done'
+
+        # TODO use 'n in self.repo' when we require hg 1.5
+        def repo_contains(n):
+            try:
+                return bool(self.repo.lookup(n))
+            except error.RepoLookupError:
+                return False
+
+        if not (repo_contains(p1) and repo_contains(p2)):
+            raise hgutil.Abort(_('you appear to have run strip - '
+                                 'please run hg git-cleanup'))
+        ctx = context.memctx(self.repo, (p1, p2), text,
+                             list(files) + findconvergedfiles(p1, p2),
+                             getfilectx, author, date, extra)
+
+        node = self.repo.commitctx(ctx)
+
+        self.swap_out_encoding(oldenc)
+
+        # save changeset to mapping file
+        cs = hex(node)
+        self.map_set(commit.id, cs)
+
+    ## PACK UPLOADING AND FETCHING
+
+    def upload_pack(self, remote, revs, force):
+        client, path = self.get_transport_and_path(remote)
+        def changed(refs):
+            to_push = revs or set(self.local_heads().values() + self.tags.values())
+            return self.get_changed_refs(refs, to_push, force)
+
+        genpack = self.git.object_store.generate_pack_contents
+        try:
+            self.ui.status(_("creating and sending data\n"))
+            changed_refs = client.send_pack(path, changed, genpack)
+            return changed_refs
+        except (HangupException, GitProtocolError), e:
+            raise hgutil.Abort(_("git remote error: ") + str(e))
+
+    def get_changed_refs(self, refs, revs, force):
+        new_refs = refs.copy()
+
+        #The remote repo is empty and the local one doesn't have bookmarks/tags
+        if refs.keys()[0] == 'capabilities^{}':
+            del new_refs['capabilities^{}']
+            if not self.local_heads():
+                tip = hex(self.repo.lookup('tip'))
+                try:
+                    commands.bookmark(self.ui, self.repo, 'master', tip, force=True)
+                except NameError:
+                    bookmarks.bookmark(self.ui, self.repo, 'master', tip, force=True)
+                bookmarks.setcurrent(self.repo, 'master')
+                new_refs['refs/heads/master'] = self.map_git_get(tip)
+
+        for rev in revs:
+            ctx = self.repo[rev]
+            if getattr(ctx, 'bookmarks', None):
+                labels = lambda c: ctx.tags() + ctx.bookmarks()
+            else:
+                labels = lambda c: ctx.tags()
+            prep = lambda itr: [i.replace(' ', '_') for i in itr]
+
+            heads = [t for t in prep(labels(ctx)) if t in self.local_heads()]
+            tags = [t for t in prep(labels(ctx)) if t in self.tags]
+
+            if not (heads or tags):
+                raise hgutil.Abort("revision %s cannot be pushed since"
+                                   " it doesn't have a ref" % ctx)
+
+            # Check if the tags the server is advertising are annotated tags,
+            # by attempting to retrieve it from the our git repo, and building a
+            # list of these tags.
+            #
+            # This is possible, even though (currently) annotated tags are
+            # dereferenced and stored as lightweight ones, as the annotated tag
+            # is still stored in the git repo.
+            uptodate_annotated_tags = []
+            for r in tags:
+                ref = 'refs/tags/'+r
+                # Check tag.
+                if not ref in refs:
+                    continue
+                try:
+                    # We're not using Repo.tag(), as it's deprecated.
+                    tag = self.git.get_object(refs[ref])
+                    if not isinstance(tag, Tag):
+                        continue
+                except KeyError:
+                    continue
+
+                # If we've reached here, the tag's good.
+                uptodate_annotated_tags.append(ref)
+
+            for r in heads + tags:
+                if r in heads:
+                    ref = 'refs/heads/'+r
+                else:
+                    ref = 'refs/tags/'+r
+
+                if ref not in refs:
+                    new_refs[ref] = self.map_git_get(ctx.hex())
+                elif new_refs[ref] in self._map_git:
+                    rctx = self.repo[self.map_hg_get(new_refs[ref])]
+                    if rctx.ancestor(ctx) == rctx or force:
+                        new_refs[ref] = self.map_git_get(ctx.hex())
+                    else:
+                        raise hgutil.Abort("pushing %s overwrites %s"
+                                           % (ref, ctx))
+                elif ref in uptodate_annotated_tags:
+                    # we already have the annotated tag.
+                    pass
+                else:
+                    raise hgutil.Abort("%s changed on the server, please pull "
+                                       "and merge before pushing" % ref)
+
+        return new_refs
+
+
+    def fetch_pack(self, remote_name, heads):
+        client, path = self.get_transport_and_path(remote_name)
+        graphwalker = self.git.get_graph_walker()
+        def determine_wants(refs):
+            if heads:
+                want = []
+                # contains pairs of ('refs/(heads|tags|...)/foo', 'foo')
+                # if ref is just '<foo>', then we get ('foo', 'foo')
+                stripped_refs = [
+                    (r, r[r.find('/', r.find('/')+1)+1:])
+                        for r in refs]
+                for h in heads:
+                    r = [pair[0] for pair in stripped_refs if pair[1] == h]
+                    if not r:
+                        raise hgutil.Abort("ref %s not found on remote server" % h)
+                    elif len(r) == 1:
+                        want.append(refs[r[0]])
+                    else:
+                        raise hgutil.Abort("ambiguous reference %s: %r" % (h, r))
+            else:
+                want = [sha for ref, sha in refs.iteritems()
+                        if not ref.endswith('^{}')
+                        and ( ref.startswith('refs/heads/') or ref.startswith('refs/tags/') ) ]
+            want = [x for x in want if x not in self.git]
+            return want
+        f, commit = self.git.object_store.add_pack()
+        try:
+            try:
+                progress = GitProgress(self.ui)
+                ret = client.fetch_pack(path, determine_wants, graphwalker,
+                                        f.write, progress.progress)
+                progress.flush()
+                return ret
+            except (HangupException, GitProtocolError), e:
+                raise hgutil.Abort(_("git remote error: ") + str(e))
+        finally:
+            commit()
+
+    ## REFERENCES HANDLING
+
+    def update_references(self):
+        heads = self.local_heads()
+
+        # Create a local Git branch name for each
+        # Mercurial bookmark.
+        for key in heads:
+            git_ref = self.map_git_get(heads[key])
+            if git_ref:
+                self.git.refs['refs/heads/' + key] = self.map_git_get(heads[key])
+
+    def export_hg_tags(self):
+        for tag, sha in self.repo.tags().iteritems():
+            if self.repo.tagtype(tag) in ('global', 'git'):
+                tag = tag.replace(' ', '_')
+                self.git.refs['refs/tags/' + tag] = self.map_git_get(hex(sha))
+                self.tags[tag] = hex(sha)
+
+    def local_heads(self):
+        try:
+            if getattr(bookmarks, 'parse', None):
+                bms = bookmarks.parse(self.repo)
+            else:
+                bms = self.repo._bookmarks
+            return dict([(bm, hex(bms[bm])) for bm in bms])
+        except AttributeError: #pragma: no cover
+            return {}
+
+    def import_tags(self, refs):
+        keys = refs.keys()
+        if not keys:
+            return
+        for k in keys[:]:
+            ref_name = k
+            parts = k.split('/')
+            if parts[0] == 'refs' and parts[1] == 'tags':
+                ref_name = "/".join([v for v in parts[2:]])
+                # refs contains all the refs in the server, not just
+                # the ones we are pulling
+                if refs[k] not in self.git.object_store:
+                    continue
+                if ref_name[-3:] == '^{}':
+                    ref_name = ref_name[:-3]
+                if not ref_name in self.repo.tags():
+                    obj = self.git.get_object(refs[k])
+                    sha = None
+                    if isinstance (obj, Commit): # lightweight
+                        sha = self.map_hg_get(refs[k])
+                        self.tags[ref_name] = sha
+                    elif isinstance (obj, Tag): # annotated
+                        (obj_type, obj_sha) = obj.object
+                        obj = self.git.get_object(obj_sha)
+                        if isinstance (obj, Commit):
+                            sha = self.map_hg_get(obj_sha)
+                            # TODO: better handling for annotated tags
+                            self.tags[ref_name] = sha
+        self.save_tags()
+
+    def update_hg_bookmarks(self, refs):
+        try:
+            oldbm = getattr(bookmarks, 'parse', None)
+            if oldbm:
+                bms = bookmarks.parse(self.repo)
+            else:
+                bms = self.repo._bookmarks
+            heads = dict([(ref[11:],refs[ref]) for ref in refs
+                          if ref.startswith('refs/heads/')])
+
+            for head, sha in heads.iteritems():
+                # refs contains all the refs in the server, not just
+                # the ones we are pulling
+                if sha not in self.git.object_store:
+                    continue
+                hgsha = bin(self.map_hg_get(sha))
+                if not head in bms:
+                    # new branch
+                    bms[head] = hgsha
+                else:
+                    bm = self.repo[bms[head]]
+                    if bm.ancestor(self.repo[hgsha]) == bm:
+                        # fast forward
+                        bms[head] = hgsha
+            if heads:
+                if oldbm:
+                    bookmarks.write(self.repo, bms)
+                else:
+                    self.repo._bookmarks = bms
+                    bookmarks.write(self.repo)
+
+        except AttributeError:
+            self.ui.warn(_('creating bookmarks failed, do you have'
+                         ' bookmarks enabled?\n'))
+
+    def update_remote_branches(self, remote_name, refs):
+        tagfile = self.repo.join(os.path.join('git-remote-refs'))
+        tags = self.repo.gitrefs()
+        # since we re-write all refs for this remote each time, prune
+        # all entries matching this remote from our tags list now so
+        # that we avoid any stale refs hanging around forever
+        for t in list(tags):
+            if t.startswith(remote_name + '/'):
+                del tags[t]
+        tags = dict((k, hex(v)) for k, v in tags.iteritems())
+        store = self.git.object_store
+        for ref_name, sha in refs.iteritems():
+            if ref_name.startswith('refs/heads'):
+                if sha not in store:
+                    continue
+                hgsha = self.map_hg_get(sha)
+                head = ref_name[11:]
+                tags['/'.join((remote_name, head))] = hgsha
+                # TODO(durin42): what is this doing?
+                new_ref = 'refs/remotes/%s/%s' % (remote_name, head)
+                self.git.refs[new_ref] = sha
+            elif (ref_name.startswith('refs/tags')
+                  and not ref_name.endswith('^{}')):
+                self.git.refs[ref_name] = sha
+
+        tf = open(tagfile, 'wb')
+        for tag, node in tags.iteritems():
+            tf.write('%s %s\n' % (node, tag))
+        tf.close()
+
+
+    ## UTILITY FUNCTIONS
+
+    def convert_git_int_mode(self, mode):
+        # TODO: make these into constants
+        convert = {
+         0100644: '',
+         0100755: 'x',
+         0120000: 'l'}
+        if mode in convert:
+            return convert[mode]
+        return ''
+
+    def extract_hg_metadata(self, message):
+        split = message.split("\n--HG--\n", 1)
+        renames = {}
+        extra = {}
+        branch = False
+        if len(split) == 2:
+            message, meta = split
+            lines = meta.split("\n")
+            for line in lines:
+                if line == '':
+                    continue
+
+                command, data = line.split(" : ", 1)
+
+                if command == 'rename':
+                    before, after = data.split(" => ", 1)
+                    renames[after] = before
+                if command == 'branch':
+                    branch = data
+                if command == 'extra':
+                    before, after = data.split(" : ", 1)
+                    extra[before] = urllib.unquote(after)
+        return (message, renames, branch, extra)
+
+    def get_file(self, commit, f):
+        otree = self.git.tree(commit.tree)
+        parts = f.split('/')
+        for part in parts:
+            (mode, sha) = otree[part]
+            obj = self.git.get_object(sha)
+            if isinstance (obj, Blob):
+                return (mode, sha, obj._text)
+            elif isinstance(obj, Tree):
+                otree = obj
+
+    def get_files_changed(self, commit):
+        tree = commit.tree
+        btree = None
+
+        if commit.parents:
+            btree = self.git[commit.parents[0]].tree
+
+        changes = self.git.object_store.tree_changes(btree, tree)
+        files = {}
+        for (oldfile, newfile), (oldmode, newmode), (oldsha, newsha) in changes:
+            # don't create new submodules
+            if newmode == 0160000:
+                if oldfile:
+                    # become a regular delete
+                    newfile, newmode = None, None
+                else:
+                    continue
+            # so old submodules shoudn't exist
+            if oldmode == 0160000:
+                if newfile:
+                    # become a regular add
+                    oldfile, oldmode = None, None
+                else:
+                    continue
+
+            if newfile is None:
+                file = oldfile
+                delete = True
+            else:
+                file = newfile
+                delete = False
+
+            files[file] = (delete, newmode, newsha)
+
+        return files
+
+    def remote_name(self, remote):
+        names = [name for name, path in self.paths if path == remote]
+        if names:
+            return names[0]
+
+    # Stolen from hgsubversion
+    def swap_out_encoding(self, new_encoding='UTF-8'):
+        try:
+            from mercurial import encoding
+            old = encoding.encoding
+            encoding.encoding = new_encoding
+        except ImportError:
+            old = hgutil._encoding
+            hgutil._encoding = new_encoding
+        return old
+
+    def decode_guess(self, string, encoding):
+        # text is not valid utf-8, try to make sense of it
+        if encoding:
+            try:
+                return string.decode(encoding).encode('utf-8')
+            except UnicodeDecodeError:
+                pass
+
+        try:
+            return string.decode('latin-1').encode('utf-8')
+        except UnicodeDecodeError:
+            return string.decode('ascii', 'replace').encode('utf-8')
+
+    def get_transport_and_path(self, uri):
+        # pass hg's ui.ssh config to dulwich
+        if not issubclass(client.get_ssh_vendor, _ssh.SSHVendor):
+            client.get_ssh_vendor = _ssh.generate_ssh_vendor(self.ui)
+
+        for handler, transport in (("git://", client.TCPGitClient),
+                                   ("git@", client.SSHGitClient),
+                                   ("git+ssh://", client.SSHGitClient)):
+            if uri.startswith(handler):
+                # We need to split around : or /, whatever comes first
+                hostpath = uri[len(handler):]
+                if (hostpath.find(':') > 0 and hostpath.find('/') > 0):
+                    # we have both, whatever is first wins.
+                    if hostpath.find(':') < hostpath.find('/'):
+                      hostpath_seper = ':'
+                    else:
+                      hostpath_seper = '/'
+                elif hostpath.find(':') > 0:
+                    hostpath_seper = ':'
+                else:
+                    hostpath_seper = '/'
+
+                port = None
+                host, path = hostpath.split(hostpath_seper, 1)
+                if hostpath_seper == '/':
+                    transportpath = '/' + path
+                else:
+                    # port number should be recognized
+                    m = re.match('^(?P<port>\d+)?(?P<path>.*)$', path)
+                    if m.group('port'):
+                        client.port = m.group('port')
+                        port = client.port
+                        transportpath = m.group('path')
+                    else:
+                        transportpath = path
+
+                return transport(host, thin_packs=False, port=port), transportpath
+        # if its not git or git+ssh, try a local url..
+        return client.SubprocessGitClient(thin_packs=False), uri
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/hggit/gitrepo.py	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,43 @@
+from mercurial import repo, util
+try:
+    from mercurial.error import RepoError
+except ImportError:
+    from mercurial.repo import RepoError
+
+from git_handler import GitHandler
+
+class gitrepo(repo.repository):
+    capabilities = ['lookup']
+
+    def __init__(self, ui, path, create):
+        if create: # pragma: no cover
+            raise util.Abort('Cannot create a git repository.')
+        self.ui = ui
+        self.path = path
+
+    def lookup(self, key):
+        if isinstance(key, str):
+            return key
+
+    def local(self):
+        if not self.path:
+            raise RepoError
+
+    def heads(self):
+        return []
+
+    def listkeys(self, namespace):
+        return {}
+
+    def pushkey(self, namespace, key, old, new):
+        return False
+
+    # used by incoming in hg <= 1.6
+    def branches(self, nodes):
+        return []
+
+instance = gitrepo
+
+def islocal(path):
+    u = util.url(path)
+    return not u.scheme or u.scheme == 'file'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/hggit/hgrepo.py	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,81 @@
+import os
+
+from mercurial.node import bin
+
+from git_handler import GitHandler
+from gitrepo import gitrepo
+
+
+def generate_repo_subclass(baseclass):
+    class hgrepo(baseclass):
+        def pull(self, remote, heads=None, force=False):
+            if isinstance(remote, gitrepo):
+                git = GitHandler(self, self.ui)
+                return git.fetch(remote.path, heads)
+            else: #pragma: no cover
+                return super(hgrepo, self).pull(remote, heads, force)
+
+        # TODO figure out something useful to do with the newbranch param
+        def push(self, remote, force=False, revs=None, newbranch=None):
+            if isinstance(remote, gitrepo):
+                git = GitHandler(self, self.ui)
+                git.push(remote.path, revs, force)
+            else: #pragma: no cover
+                # newbranch was added in 1.6
+                if newbranch is None:
+                    return super(hgrepo, self).push(remote, force, revs)
+                else:
+                    return super(hgrepo, self).push(remote, force, revs,
+                                                    newbranch)
+
+        def findoutgoing(self, remote, base=None, heads=None, force=False):
+            if isinstance(remote, gitrepo):
+                git = GitHandler(self, self.ui)
+                base, heads = git.get_refs(remote.path)
+                out, h = super(hgrepo, self).findoutgoing(remote, base, heads, force)
+                return out
+            else: #pragma: no cover
+                return super(hgrepo, self).findoutgoing(remote, base, heads, force)
+
+        def _findtags(self):
+            (tags, tagtypes) = super(hgrepo, self)._findtags()
+
+            git = GitHandler(self, self.ui)
+            for tag, rev in git.tags.iteritems():
+                tags[tag] = bin(rev)
+                tagtypes[tag] = 'git'
+
+            return (tags, tagtypes)
+
+        def gitrefs(self):
+            tagfile = self.join(os.path.join('git-remote-refs'))
+            if os.path.exists(tagfile):
+                tf = open(tagfile, 'rb')
+                tagdata = tf.read().split('\n')
+                td = [line.split(' ', 1) for line in tagdata if line]
+                return dict([(name, bin(sha)) for sha, name in td])
+            return {}
+
+        def tags(self):
+            if hasattr(self, 'tagscache') and self.tagscache:
+                # Mercurial 1.4 and earlier.
+                return self.tagscache
+            elif hasattr(self, '_tags') and self._tags:
+                # Mercurial 1.5 and later.
+                return self._tags
+
+            git = GitHandler(self, self.ui)
+            tagscache = super(hgrepo, self).tags()
+            tagscache.update(self.gitrefs())
+            for tag, rev in git.tags.iteritems():
+                if tag in tagscache:
+                    continue
+
+                tagscache[tag] = bin(rev)
+                if hasattr(self, '_tagstypecache'):
+                    # Only present in Mercurial 1.3 and earlier.
+                    self._tagstypecache[tag] = 'git'
+
+            return tagscache
+
+    return hgrepo
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/hggit/overlay.py	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,254 @@
+# overlay classes for repositories
+# unifies access to unimported git objects and committed hg objects
+# designed to support incoming
+#
+# incomplete, implemented on demand
+
+from mercurial import context
+from mercurial.node import bin, hex, nullid
+
+class overlaymanifest(object):
+    def __init__(self, repo, sha):
+        self.repo = repo
+        self.tree = repo.handler.git.get_object(sha)
+        self._map = None
+        self._flagmap = None
+
+    def copy(self):
+        return overlaymanifest(self.repo, self.tree.id)
+
+    def keys(self):
+        self.load()
+        return self._map.keys()
+
+    def flags(self, path):
+        self.load()
+
+        def hgflag(gitflag):
+            if gitflag & 0100:
+                return 'x'
+            elif gitflag & 020000:
+                return 'l'
+            else:
+                return ''
+
+        return hgflag(self._flagmap[path])
+
+    def load(self):
+        if self._map is not None:
+            return
+
+        self._map = {}
+        self._flagmap = {}
+
+        def addtree(tree, dirname):
+            for entry in tree.entries():
+                if entry[0] & 040000:
+                    # expand directory
+                    subtree = self.repo.handler.git.get_object(entry[2])
+                    addtree(subtree, dirname + entry[1] + '/')
+                else:
+                    path = dirname + entry[1]
+                    self._map[path] = bin(entry[2])
+                    self._flagmap[path] = entry[0]
+
+        addtree(self.tree, '')
+
+    def __iter__(self):
+        self.load()
+        return self._map.__iter__()
+
+    def __getitem__(self, path):
+        self.load()
+        return self._map[path]
+
+    def __delitem__(self, path):
+        del self._map[path]
+
+class overlayfilectx(object):
+    def __init__(self, repo, path, fileid=None):
+        self.repo = repo
+        self._path = path
+        self.fileid = fileid
+
+    # this is a hack to skip copy detection
+    def ancestors(self):
+        return [self, self]
+
+    def rev(self):
+        return -1
+
+    def path(self):
+        return self._path
+
+    def filelog(self):
+        return self.fileid
+
+    def data(self):
+        blob = self.repo.handler.git.get_object(self.fileid)
+        return blob.data
+
+class overlaychangectx(context.changectx):
+    def __init__(self, repo, sha):
+        self.repo = repo
+        self.commit = repo.handler.git.get_object(sha)
+
+    def node(self):
+        return bin(self.commit.id)
+
+    def rev(self):
+        return self.repo.rev(bin(self.commit.id))
+
+    def date(self):
+        return self.commit.author_time, self.commit.author_timezone
+
+    def branch(self):
+        return 'default'
+
+    def user(self):
+        return self.commit.author
+
+    def files(self):
+        return []
+
+    def extra(self):
+        return {}
+
+    def description(self):
+        return self.commit.message
+
+    def parents(self):
+        return [overlaychangectx(self.repo, sha) for sha in self.commit.parents]
+
+    def manifestnode(self):
+        return bin(self.commit.tree)
+
+    def hex(self):
+        return self.commit.id
+
+    def tags(self):
+        return []
+
+    def bookmarks(self):
+        return []
+
+    def manifest(self):
+        return overlaymanifest(self.repo, self.commit.tree)
+
+    def filectx(self, path, filelog=None):
+        mf = self.manifest()
+        return overlayfilectx(self.repo, path, mf[path])
+
+    def flags(self, path):
+        mf = self.manifest()
+        return mf.flags(path)
+
+    def __nonzero__(self):
+        return True
+
+class overlayrevlog(object):
+    def __init__(self, repo, base):
+        self.repo = repo
+        self.base = base
+
+    def parents(self, n):
+        gitrev = self.repo.revmap.get(n)
+        if not gitrev:
+            # we've reached a revision we have
+            return self.base.parents(n)
+        commit = self.repo.handler.git.get_object(n)
+
+        def gitorhg(n):
+            hn = self.repo.handler.map_hg_get(hex(n))
+            if hn is not None:
+                return bin(hn)
+            return n
+
+        # currently ignores the octopus
+        p1 = gitorhg(bin(commit.parents[0]))
+        if len(commit.parents) > 1:
+            p2 = gitorhg(bin(commit.parents[1]))
+        else:
+            p2 = nullid
+
+        return [p1, p2]
+
+    def parentrevs(self, rev):
+        return [self.rev(p) for p in self.parents(self.node(rev))]
+
+    def node(self, rev):
+        gitnode = self.repo.nodemap.get(rev)
+        if gitnode is None:
+            return self.base.node(rev)
+        return gitnode
+
+    def rev(self, n):
+        gitrev = self.repo.revmap.get(n)
+        if gitrev is None:
+             return self.base.rev(n)
+        return gitrev
+
+    def nodesbetween(self, nodelist, revs):
+        # this is called by pre-1.9 incoming with the nodelist we returned from
+        # getremotechanges. Just return it back.
+        return [nodelist]
+
+    def __len__(self):
+        return len(self.repo.handler.repo) + len(self.repo.revmap)
+
+
+class overlayrepo(object):
+    def __init__(self, handler, commits, refs):
+        self.handler = handler
+
+        self.changelog = overlayrevlog(self, handler.repo.changelog)
+        self.manifest = overlayrevlog(self, handler.repo.manifest)
+
+        # for incoming -p
+        self.root = handler.repo.root
+        self.getcwd = handler.repo.getcwd
+        self.status = handler.repo.status
+        self.ui = handler.repo.ui
+
+        self.revmap = None
+        self.nodemap = None
+        self.refmap = None
+        self.tagmap = None
+
+        self._makemaps(commits, refs)
+
+    def __getitem__(self, n):
+        if n not in self.revmap:
+            return self.handler.repo[n]
+        return overlaychangectx(self, n)
+
+    def nodebookmarks(self, n):
+        return self.refmap.get(n, [])
+
+    def nodetags(self, n):
+        return self.tagmap.get(n, [])
+
+    def rev(self, n):
+        return self.revmap[n]
+
+    def filectx(self, path, fileid=None):
+        return overlayfilectx(self, path, fileid=fileid)
+
+    def _makemaps(self, commits, refs):
+        baserev = self.handler.repo['tip'].rev()
+        self.revmap = {}
+        self.nodemap = {}
+        for i, n in enumerate(commits):
+            rev = baserev + i + 1
+            self.revmap[n] = rev
+            self.nodemap[rev] = n
+
+        self.refmap = {}
+        self.tagmap = {}
+        for ref in refs:
+            if ref.startswith('refs/heads/'):
+                refname = ref[11:]
+                self.refmap.setdefault(bin(refs[ref]), []).append(refname)
+            elif ref.startswith('refs/tags/'):
+                tagname = ref[10:]
+                self.tagmap.setdefault(bin(refs[ref]), []).append(tagname)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/hggit/util.py	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,5 @@
+"""Compatability functions for old Mercurial versions."""
+
+def progress(ui, *args, **kwargs):
+    """Shim for progress on hg < 1.4. Remove when 1.3 is dropped."""
+    getattr(ui, 'progress', lambda *x, **kw: None)(*args, **kwargs)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/setup.py	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,23 @@
+try:
+    from setuptools import setup
+except:
+    from distutils.core import setup
+
+setup(
+    name='hg-git',
+    version='0.2.6',
+    author='Scott Chacon',
+    maintainer='Augie Fackler',
+    maintainer_email='durin42@gmail.com',
+    url='http://hg-git.github.com/',
+    description='push and pull from a Git server using Mercurial',
+    long_description="""
+This extension lets you communicate (push and pull) with a Git server.
+This way you can use Git hosting for your project or collaborate with a
+project that is in Git.  A bridger of worlds, this plugin be.
+    """.strip(),
+    keywords='hg git mercurial',
+    license='GPLv2',
+    packages=['hggit'],
+    install_requires=['dulwich>=0.6.0'],
+)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/latin-1-encoding	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,18 @@
+# -*- coding: latin-1 -*-
+
+# this file contains some latin-1 messages for test-encoding
+
+GIT_AUTHOR_NAME='tst ncdng'; export GIT_AUTHOR_NAME
+echo beta > beta
+git add beta
+commit -m 'add beta'
+
+echo gamma > gamma
+git add gamma
+commit -m 'add gmm'
+
+# test the commit encoding field
+git config i18n.commitencoding latin-1
+echo delta > delta
+git add delta
+commit -m 'add dlt'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/run-tests.py	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,708 @@
+#!/usr/bin/env python
+#
+# run-tests.py - Run a set of tests on Mercurial
+#
+# Copyright 2006 Matt Mackall <mpm@selenic.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2, incorporated herein by reference.
+
+import difflib
+import errno
+import optparse
+import os
+try:
+    import subprocess
+    subprocess.Popen  # trigger ImportError early
+    closefds = os.name == 'posix'
+    def Popen4(cmd, bufsize=-1):
+        p = subprocess.Popen(cmd, shell=True, bufsize=bufsize,
+                             close_fds=closefds,
+                             stdin=subprocess.PIPE, stdout=subprocess.PIPE,
+                             stderr=subprocess.STDOUT)
+        p.fromchild = p.stdout
+        p.tochild = p.stdin
+        p.childerr = p.stderr
+        return p
+except ImportError:
+    subprocess = None
+    from popen2 import Popen4
+import shutil
+import signal
+import sys
+import tempfile
+import time
+
+# reserved exit code to skip test (used by hghave)
+SKIPPED_STATUS = 80
+SKIPPED_PREFIX = 'skipped: '
+FAILED_PREFIX  = 'hghave check failed: '
+PYTHON = sys.executable
+
+requiredtools = ["python", "diff", "grep", "unzip", "gunzip", "bunzip2", "sed"]
+
+defaults = {
+    'jobs': ('HGTEST_JOBS', 1),
+    'timeout': ('HGTEST_TIMEOUT', 180),
+    'port': ('HGTEST_PORT', 20059),
+}
+
+def parseargs():
+    parser = optparse.OptionParser("%prog [options] [tests]")
+    parser.add_option("-C", "--annotate", action="store_true",
+        help="output files annotated with coverage")
+    parser.add_option("--child", type="int",
+        help="run as child process, summary to given fd")
+    parser.add_option("-c", "--cover", action="store_true",
+        help="print a test coverage report")
+    parser.add_option("-f", "--first", action="store_true",
+        help="exit on the first test failure")
+    parser.add_option("-i", "--interactive", action="store_true",
+        help="prompt to accept changed output")
+    parser.add_option("-j", "--jobs", type="int",
+        help="number of jobs to run in parallel"
+             " (default: $%s or %d)" % defaults['jobs'])
+    parser.add_option("--keep-tmpdir", action="store_true",
+        help="keep temporary directory after running tests"
+             " (best used with --tmpdir)")
+    parser.add_option("-R", "--restart", action="store_true",
+        help="restart at last error")
+    parser.add_option("-p", "--port", type="int",
+        help="port on which servers should listen"
+             " (default: $%s or %d)" % defaults['port'])
+    parser.add_option("-r", "--retest", action="store_true",
+        help="retest failed tests")
+    parser.add_option("-s", "--cover_stdlib", action="store_true",
+        help="print a test coverage report inc. standard libraries")
+    parser.add_option("-t", "--timeout", type="int",
+        help="kill errant tests after TIMEOUT seconds"
+             " (default: $%s or %d)" % defaults['timeout'])
+    parser.add_option("--tmpdir", type="string",
+        help="run tests in the given temporary directory")
+    parser.add_option("-v", "--verbose", action="store_true",
+        help="output verbose messages")
+    parser.add_option("-n", "--nodiff", action="store_true",
+        help="skip showing test changes")
+    parser.add_option("--with-hg", type="string",
+        help="test existing install at given location")
+    parser.add_option("--pure", action="store_true",
+        help="use pure Python code instead of C extensions")
+
+    for option, default in defaults.items():
+        defaults[option] = int(os.environ.get(*default))
+    parser.set_defaults(**defaults)
+    (options, args) = parser.parse_args()
+
+    global vlog
+    options.anycoverage = (options.cover or
+                           options.cover_stdlib or
+                           options.annotate)
+
+    if options.verbose:
+        def vlog(*msg):
+            for m in msg:
+                print m,
+            print
+    else:
+        vlog = lambda *msg: None
+
+    if options.jobs < 1:
+        print >> sys.stderr, 'ERROR: -j/--jobs must be positive'
+        sys.exit(1)
+    if options.interactive and options.jobs > 1:
+        print '(--interactive overrides --jobs)'
+        options.jobs = 1
+
+    return (options, args)
+
+def rename(src, dst):
+    """Like os.rename(), trade atomicity and opened files friendliness
+    for existing destination support.
+    """
+    shutil.copy(src, dst)
+    os.remove(src)
+
+def splitnewlines(text):
+    '''like str.splitlines, but only split on newlines.
+    keep line endings.'''
+    i = 0
+    lines = []
+    while True:
+        n = text.find('\n', i)
+        if n == -1:
+            last = text[i:]
+            if last:
+                lines.append(last)
+            return lines
+        lines.append(text[i:n+1])
+        i = n + 1
+
+def parsehghaveoutput(lines):
+    '''Parse hghave log lines.
+    Return tuple of lists (missing, failed):
+      * the missing/unknown features
+      * the features for which existence check failed'''
+    missing = []
+    failed = []
+    for line in lines:
+        if line.startswith(SKIPPED_PREFIX):
+            line = line.splitlines()[0]
+            missing.append(line[len(SKIPPED_PREFIX):])
+        elif line.startswith(FAILED_PREFIX):
+            line = line.splitlines()[0]
+            failed.append(line[len(FAILED_PREFIX):])
+
+    return missing, failed
+
+def showdiff(expected, output):
+    for line in difflib.unified_diff(expected, output,
+            "Expected output", "Test output"):
+        sys.stdout.write(line)
+
+def findprogram(program):
+    """Search PATH for a executable program"""
+    for p in os.environ.get('PATH', os.defpath).split(os.pathsep):
+        name = os.path.join(p, program)
+        if os.access(name, os.X_OK):
+            return name
+    return None
+
+def checktools():
+    # Before we go any further, check for pre-requisite tools
+    # stuff from coreutils (cat, rm, etc) are not tested
+    for p in requiredtools:
+        if os.name == 'nt':
+            p += '.exe'
+        found = findprogram(p)
+        if found:
+            vlog("# Found prerequisite", p, "at", found)
+        else:
+            print "WARNING: Did not find prerequisite tool: "+p
+
+def cleanup(options):
+    if not options.keep_tmpdir:
+        if options.verbose:
+            print "# Cleaning up HGTMP", HGTMP
+        shutil.rmtree(HGTMP, True)
+
+def usecorrectpython():
+    # some tests run python interpreter. they must use same
+    # interpreter we use or bad things will happen.
+    exedir, exename = os.path.split(sys.executable)
+    if exename == 'python':
+        path = findprogram('python')
+        if os.path.dirname(path) == exedir:
+            return
+    vlog('# Making python executable in test path use correct Python')
+    mypython = os.path.join(BINDIR, 'python')
+    try:
+        os.symlink(sys.executable, mypython)
+    except AttributeError:
+        # windows fallback
+        shutil.copyfile(sys.executable, mypython)
+        shutil.copymode(sys.executable, mypython)
+
+def installhg(options):
+    global PYTHON
+    vlog("# Performing temporary installation of HG")
+    installerrs = os.path.join("tests", "install.err")
+    pure = options.pure and "--pure" or ""
+
+    # Run installer in hg root
+    os.chdir(os.path.join(os.path.dirname(sys.argv[0]), '..'))
+    cmd = ('%s setup.py %s clean --all'
+           ' install --force --prefix="%s" --install-lib="%s"'
+           ' --install-scripts="%s" >%s 2>&1'
+           % (sys.executable, pure, INST, PYTHONDIR, BINDIR, installerrs))
+    vlog("# Running", cmd)
+    if os.system(cmd) == 0:
+        if not options.verbose:
+            os.remove(installerrs)
+    else:
+        f = open(installerrs)
+        for line in f:
+            print line,
+        f.close()
+        sys.exit(1)
+    os.chdir(TESTDIR)
+
+    os.environ["PATH"] = "%s%s%s" % (BINDIR, os.pathsep, os.environ["PATH"])
+
+    pydir = os.pathsep.join([PYTHONDIR, TESTDIR])
+    pythonpath = os.environ.get("PYTHONPATH")
+    if pythonpath:
+        pythonpath = pydir + os.pathsep + pythonpath
+    else:
+        pythonpath = pydir
+    os.environ["PYTHONPATH"] = pythonpath
+
+    usecorrectpython()
+    global hgpkg
+    hgpkg = _hgpath()
+
+    vlog("# Installing dummy diffstat")
+    f = open(os.path.join(BINDIR, 'diffstat'), 'w')
+    f.write('#!' + sys.executable + '\n'
+            'import sys\n'
+            'files = 0\n'
+            'for line in sys.stdin:\n'
+            '    if line.startswith("diff "):\n'
+            '        files += 1\n'
+            'sys.stdout.write("files patched: %d\\n" % files)\n')
+    f.close()
+    os.chmod(os.path.join(BINDIR, 'diffstat'), 0700)
+
+    if options.anycoverage:
+        vlog("# Installing coverage wrapper")
+        os.environ['COVERAGE_FILE'] = COVERAGE_FILE
+        if os.path.exists(COVERAGE_FILE):
+            os.unlink(COVERAGE_FILE)
+        # Create a wrapper script to invoke hg via coverage.py
+        os.rename(os.path.join(BINDIR, "hg"), os.path.join(BINDIR, "_hg.py"))
+        f = open(os.path.join(BINDIR, 'hg'), 'w')
+        f.write('#!' + sys.executable + '\n')
+        f.write('import sys, os; os.execv(sys.executable, [sys.executable, '
+                '"%s", "-x", "%s"] + sys.argv[1:])\n' %
+                (os.path.join(TESTDIR, 'coverage.py'),
+                 os.path.join(BINDIR, '_hg.py')))
+        f.close()
+        os.chmod(os.path.join(BINDIR, 'hg'), 0700)
+        PYTHON = '"%s" "%s" -x' % (sys.executable,
+                                   os.path.join(TESTDIR,'coverage.py'))
+
+def _hgpath():
+    cmd = '%s -c "import mercurial; print mercurial.__path__[0]"'
+    hgpath = os.popen(cmd % PYTHON)
+    path = hgpath.read().strip()
+    hgpath.close()
+    return path
+
+def outputcoverage(options):
+    vlog("# Producing coverage report")
+    omit = [BINDIR, TESTDIR, PYTHONDIR]
+    if not options.cover_stdlib:
+        # Exclude as system paths (ignoring empty strings seen on win)
+        omit += [x for x in sys.path if x != '']
+    omit = ','.join(omit)
+    os.chdir(PYTHONDIR)
+    cmd = '"%s" "%s" -i -r "--omit=%s"' % (
+        sys.executable, os.path.join(TESTDIR, 'coverage.py'), omit)
+    vlog("# Running: "+cmd)
+    os.system(cmd)
+    if options.annotate:
+        adir = os.path.join(TESTDIR, 'annotated')
+        if not os.path.isdir(adir):
+            os.mkdir(adir)
+        cmd = '"%s" "%s" -i -a "--directory=%s" "--omit=%s"' % (
+            sys.executable, os.path.join(TESTDIR, 'coverage.py'),
+            adir, omit)
+        vlog("# Running: "+cmd)
+        os.system(cmd)
+
+class Timeout(Exception):
+    pass
+
+def alarmed(signum, frame):
+    raise Timeout
+
+def run(cmd, options):
+    """Run command in a sub-process, capturing the output (stdout and stderr).
+    Return the exist code, and output."""
+    # TODO: Use subprocess.Popen if we're running on Python 2.4
+    if os.name == 'nt' or sys.platform.startswith('java'):
+        tochild, fromchild = os.popen4(cmd)
+        tochild.close()
+        output = fromchild.read()
+        ret = fromchild.close()
+        if ret == None:
+            ret = 0
+    else:
+        proc = Popen4(cmd)
+        try:
+            output = ''
+            proc.tochild.close()
+            output = proc.fromchild.read()
+            ret = proc.wait()
+            if os.WIFEXITED(ret):
+                ret = os.WEXITSTATUS(ret)
+        except Timeout:
+            vlog('# Process %d timed out - killing it' % proc.pid)
+            os.kill(proc.pid, signal.SIGTERM)
+            ret = proc.wait()
+            if ret == 0:
+                ret = signal.SIGTERM << 8
+            output += ("\n### Abort: timeout after %d seconds.\n"
+                       % options.timeout)
+    return ret, splitnewlines(output)
+
+def runone(options, test, skips, fails):
+    '''tristate output:
+    None -> skipped
+    True -> passed
+    False -> failed'''
+
+    def skip(msg):
+        if not options.verbose:
+            skips.append((test, msg))
+        else:
+            print "\nSkipping %s: %s" % (test, msg)
+        return None
+
+    def fail(msg):
+        fails.append((test, msg))
+        if not options.nodiff:
+            print "\nERROR: %s %s" % (test, msg)
+        return None
+
+    vlog("# Test", test)
+
+    # create a fresh hgrc
+    hgrc = file(HGRCPATH, 'w+')
+    hgrc.write('[ui]\n')
+    hgrc.write('slash = True\n')
+    hgrc.write('[defaults]\n')
+    hgrc.write('backout = -d "0 0"\n')
+    hgrc.write('commit = -d "0 0"\n')
+    hgrc.write('debugrawcommit = -d "0 0"\n')
+    hgrc.write('tag = -d "0 0"\n')
+    hgrc.close()
+
+    err = os.path.join(TESTDIR, test+".err")
+    ref = os.path.join(TESTDIR, test+".out")
+    testpath = os.path.join(TESTDIR, test)
+
+    if os.path.exists(err):
+        os.remove(err)       # Remove any previous output files
+
+    # Make a tmp subdirectory to work in
+    tmpd = os.path.join(HGTMP, test)
+    os.mkdir(tmpd)
+    os.chdir(tmpd)
+
+    try:
+        tf = open(testpath)
+        firstline = tf.readline().rstrip()
+        tf.close()
+    except:
+        firstline = ''
+    lctest = test.lower()
+
+    if lctest.endswith('.py') or firstline == '#!/usr/bin/env python':
+        cmd = '%s "%s"' % (PYTHON, testpath)
+    elif lctest.endswith('.bat'):
+        # do not run batch scripts on non-windows
+        if os.name != 'nt':
+            return skip("batch script")
+        # To reliably get the error code from batch files on WinXP,
+        # the "cmd /c call" prefix is needed. Grrr
+        cmd = 'cmd /c call "%s"' % testpath
+    else:
+        # do not run shell scripts on windows
+        if os.name == 'nt':
+            return skip("shell script")
+        # do not try to run non-executable programs
+        if not os.path.exists(testpath):
+            return fail("does not exist")
+        elif not os.access(testpath, os.X_OK):
+            return skip("not executable")
+        cmd = '"%s"' % testpath
+
+    if options.timeout > 0:
+        signal.alarm(options.timeout)
+
+    vlog("# Running", cmd)
+    ret, out = run(cmd, options)
+    vlog("# Ret was:", ret)
+
+    if options.timeout > 0:
+        signal.alarm(0)
+
+    mark = '.'
+
+    skipped = (ret == SKIPPED_STATUS)
+    # If reference output file exists, check test output against it
+    if os.path.exists(ref):
+        f = open(ref, "r")
+        refout = splitnewlines(f.read())
+        f.close()
+    else:
+        refout = []
+    if skipped:
+        mark = 's'
+        missing, failed = parsehghaveoutput(out)
+        if not missing:
+            missing = ['irrelevant']
+        if failed:
+            fail("hghave failed checking for %s" % failed[-1])
+            skipped = False
+        else:
+            skip(missing[-1])
+    elif out != refout:
+        mark = '!'
+        if ret:
+            fail("output changed and returned error code %d" % ret)
+        else:
+            fail("output changed")
+        if not options.nodiff:
+            showdiff(refout, out)
+        ret = 1
+    elif ret:
+        mark = '!'
+        fail("returned error code %d" % ret)
+
+    if not options.verbose:
+        sys.stdout.write(mark)
+        sys.stdout.flush()
+
+    if ret != 0 and not skipped:
+        # Save errors to a file for diagnosis
+        f = open(err, "wb")
+        for line in out:
+            f.write(line)
+        f.close()
+
+    # Kill off any leftover daemon processes
+    try:
+        fp = file(DAEMON_PIDS)
+        for line in fp:
+            try:
+                pid = int(line)
+            except ValueError:
+                continue
+            try:
+                os.kill(pid, 0)
+                vlog('# Killing daemon process %d' % pid)
+                os.kill(pid, signal.SIGTERM)
+                time.sleep(0.25)
+                os.kill(pid, 0)
+                vlog('# Daemon process %d is stuck - really killing it' % pid)
+                os.kill(pid, signal.SIGKILL)
+            except OSError, err:
+                if err.errno != errno.ESRCH:
+                    raise
+        fp.close()
+        os.unlink(DAEMON_PIDS)
+    except IOError:
+        pass
+
+    os.chdir(TESTDIR)
+    if not options.keep_tmpdir:
+        shutil.rmtree(tmpd, True)
+    if skipped:
+        return None
+    return ret == 0
+
+def runchildren(options, expecthg, tests):
+    if not options.with_hg:
+        installhg(options)
+        if hgpkg != expecthg:
+            print '# Testing unexpected mercurial: %s' % hgpkg
+
+    optcopy = dict(options.__dict__)
+    optcopy['jobs'] = 1
+    optcopy['with_hg'] = INST
+    opts = []
+    for opt, value in optcopy.iteritems():
+        name = '--' + opt.replace('_', '-')
+        if value is True:
+            opts.append(name)
+        elif value is not None:
+            opts.append(name + '=' + str(value))
+
+    tests.reverse()
+    jobs = [[] for j in xrange(options.jobs)]
+    while tests:
+        for job in jobs:
+            if not tests: break
+            job.append(tests.pop())
+    fps = {}
+    for j, job in enumerate(jobs):
+        if not job:
+            continue
+        rfd, wfd = os.pipe()
+        childopts = ['--child=%d' % wfd, '--port=%d' % (options.port + j * 3)]
+        cmdline = [PYTHON, sys.argv[0]] + opts + childopts + job
+        vlog(' '.join(cmdline))
+        fps[os.spawnvp(os.P_NOWAIT, cmdline[0], cmdline)] = os.fdopen(rfd, 'r')
+        os.close(wfd)
+    failures = 0
+    tested, skipped, failed = 0, 0, 0
+    skips = []
+    fails = []
+    while fps:
+        pid, status = os.wait()
+        fp = fps.pop(pid)
+        l = fp.read().splitlines()
+        test, skip, fail = map(int, l[:3])
+        split = -fail or len(l)
+        for s in l[3:split]:
+            skips.append(s.split(" ", 1))
+        for s in l[split:]:
+            fails.append(s.split(" ", 1))
+        tested += test
+        skipped += skip
+        failed += fail
+        vlog('pid %d exited, status %d' % (pid, status))
+        failures |= status
+    print
+    for s in skips:
+        print "Skipped %s: %s" % (s[0], s[1])
+    for s in fails:
+        print "Failed %s: %s" % (s[0], s[1])
+
+    if hgpkg != expecthg:
+        print '# Tested unexpected mercurial: %s' % hgpkg
+    print "# Ran %d tests, %d skipped, %d failed." % (
+        tested, skipped, failed)
+    sys.exit(failures != 0)
+
+def runtests(options, expecthg, tests):
+    global DAEMON_PIDS, HGRCPATH
+    DAEMON_PIDS = os.environ["DAEMON_PIDS"] = os.path.join(HGTMP, 'daemon.pids')
+    HGRCPATH = os.environ["HGRCPATH"] = os.path.join(HGTMP, '.hgrc')
+
+    try:
+        if not options.with_hg:
+            installhg(options)
+
+            if hgpkg != expecthg:
+                print '# Testing unexpected mercurial: %s' % hgpkg
+
+        if options.timeout > 0:
+            try:
+                signal.signal(signal.SIGALRM, alarmed)
+                vlog('# Running tests with %d-second timeout' %
+                     options.timeout)
+            except AttributeError:
+                print 'WARNING: cannot run tests with timeouts'
+                options.timeout = 0
+
+        tested = 0
+        failed = 0
+        skipped = 0
+
+        if options.restart:
+            orig = list(tests)
+            while tests:
+                if os.path.exists(tests[0] + ".err"):
+                    break
+                tests.pop(0)
+            if not tests:
+                print "running all tests"
+                tests = orig
+
+        skips = []
+        fails = []
+        for test in tests:
+            if options.retest and not os.path.exists(test + ".err"):
+                skipped += 1
+                continue
+            ret = runone(options, test, skips, fails)
+            if ret is None:
+                skipped += 1
+            elif not ret:
+                if options.interactive:
+                    print "Accept this change? [n] ",
+                    answer = sys.stdin.readline().strip()
+                    if answer.lower() in "y yes".split():
+                        rename(test + ".err", test + ".out")
+                        tested += 1
+                        fails.pop()
+                        continue
+                failed += 1
+                if options.first:
+                    break
+            tested += 1
+
+        if options.child:
+            fp = os.fdopen(options.child, 'w')
+            fp.write('%d\n%d\n%d\n' % (tested, skipped, failed))
+            for s in skips:
+                fp.write("%s %s\n" % s)
+            for s in fails:
+                fp.write("%s %s\n" % s)
+            fp.close()
+        else:
+            print
+            for s in skips:
+                print "Skipped %s: %s" % s
+            for s in fails:
+                print "Failed %s: %s" % s
+            if hgpkg != expecthg:
+                print '# Tested unexpected mercurial: %s' % hgpkg
+            print "# Ran %d tests, %d skipped, %d failed." % (
+                tested, skipped, failed)
+
+        if options.anycoverage:
+            outputcoverage(options)
+    except KeyboardInterrupt:
+        failed = True
+        print "\ninterrupted!"
+
+    if failed:
+        sys.exit(1)
+
+hgpkg = None
+def main():
+    (options, args) = parseargs()
+    if not options.child:
+        os.umask(022)
+
+        checktools()
+
+    # Reset some environment variables to well-known values so that
+    # the tests produce repeatable output.
+    os.environ['LANG'] = os.environ['LC_ALL'] = 'C'
+    os.environ['TZ'] = 'GMT'
+    os.environ["EMAIL"] = "Foo Bar <foo.bar@example.com>"
+    os.environ['CDPATH'] = ''
+
+    global TESTDIR, HGTMP, INST, BINDIR, PYTHONDIR, COVERAGE_FILE
+    TESTDIR = os.environ["TESTDIR"] = os.getcwd()
+    HGTMP = os.environ['HGTMP'] = os.path.realpath(tempfile.mkdtemp('', 'hgtests.',
+                                                   options.tmpdir))
+    DAEMON_PIDS = None
+    HGRCPATH = None
+
+    os.environ["HGEDITOR"] = sys.executable + ' -c "import sys; sys.exit(0)"'
+    os.environ["HGMERGE"] = "internal:merge"
+    os.environ["HGUSER"]   = "test"
+    os.environ["HGENCODING"] = "ascii"
+    os.environ["HGENCODINGMODE"] = "strict"
+    os.environ["HGPORT"] = str(options.port)
+    os.environ["HGPORT1"] = str(options.port + 1)
+    os.environ["HGPORT2"] = str(options.port + 2)
+
+    if options.with_hg:
+        INST = options.with_hg
+    else:
+        INST = os.path.join(HGTMP, "install")
+    BINDIR = os.environ["BINDIR"] = os.path.join(INST, "bin")
+    PYTHONDIR = os.path.join(INST, "lib", "python")
+    COVERAGE_FILE = os.path.join(TESTDIR, ".coverage")
+
+    expecthg = os.path.join(HGTMP, 'install', 'lib', 'python', 'mercurial')
+
+    if len(args) == 0:
+        args = os.listdir(".")
+        args.sort()
+
+    tests = []
+    for test in args:
+        if (test.startswith("test-") and '~' not in test and
+            ('.' not in test or test.endswith('.py') or
+             test.endswith('.bat'))):
+            tests.append(test)
+
+    vlog("# Using TESTDIR", TESTDIR)
+    vlog("# Using HGTMP", HGTMP)
+
+    try:
+        if len(tests) > 1 and options.jobs > 1:
+            runchildren(options, expecthg, tests)
+        else:
+            runtests(options, expecthg, tests)
+    finally:
+        cleanup(options)
+
+main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-conflict-1	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,63 @@
+#!/bin/sh
+
+# Fails for some reason, need to investigate
+# "$TESTDIR/hghave" git || exit 80
+
+# bail if the user does not have dulwich
+python -c 'import dulwich, dulwich.repo' || exit 80
+
+# bail early if the user is already running git-daemon
+echo hi | nc localhost 9418 2>/dev/null && exit 80
+
+echo "[extensions]" >> $HGRCPATH
+echo "hggit=$(echo $(dirname $(dirname $0)))/hggit" >> $HGRCPATH
+echo 'hgext.graphlog =' >> $HGRCPATH
+echo 'hgext.bookmarks =' >> $HGRCPATH
+
+hg init hgrepo1
+cd hgrepo1
+echo A > afile
+hg add afile
+hg ci -m "origin"
+
+echo B > afile
+hg ci -m "A->B"
+
+hg up -r0
+echo C > afile
+hg ci -m "A->C"
+
+hg merge -r1 | sed 's/-C ./-C/' | grep -v 'merging afile'
+# resolve using first parent
+echo C > afile
+hg resolve -m afile
+hg ci -m "merge to C"
+
+hg log --graph --style compact | sed 's/\[.*\]//g'
+
+cd ..
+
+mkdir gitrepo
+cd gitrepo
+git init --bare | python -c "import sys; print sys.stdin.read().replace('$(dirname $(pwd))/', '')"
+
+# dulwich does not presently support local git repos, workaround
+cd ..
+git daemon --base-path="$(pwd)"\
+ --listen=localhost\
+ --export-all\
+ --pid-file="$DAEMON_PIDS" \
+ --detach --reuseaddr \
+ --enable=receive-pack
+
+cd hgrepo1
+hg bookmark -r tip master
+hg push -r master git://localhost/gitrepo
+cd ..
+
+hg clone git://localhost/gitrepo hgrepo2 | grep -v '^updating'
+cd hgrepo2
+echo % expect the same revision ids as above
+hg log --graph --style compact | sed 's/\[.*\]//g'
+
+cd ..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-conflict-1.out	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,38 @@
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+created new head
+warning: conflicts during merge.
+merging afile failed!
+0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon
+@    3:2,1   6c53bc0f062f   1970-01-01 00:00 +0000   test
+|\     merge to C
+| |
+| o  2:0   ea82b67264a1   1970-01-01 00:00 +0000   test
+| |    A->C
+| |
+o |  1   7205e83b5a3f   1970-01-01 00:00 +0000   test
+|/     A->B
+|
+o  0   5d1a6b64f9d0   1970-01-01 00:00 +0000   test
+     origin
+
+Initialized empty Git repository in gitrepo/
+
+pushing to git://localhost/gitrepo
+exporting hg objects to git
+creating and sending data
+importing git objects into hg
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+% expect the same revision ids as above
+@    3:1,2   6c53bc0f062f   1970-01-01 00:00 +0000   test
+|\     merge to C
+| |
+| o  2:0   7205e83b5a3f   1970-01-01 00:00 +0000   test
+| |    A->B
+| |
+o |  1   ea82b67264a1   1970-01-01 00:00 +0000   test
+|/     A->C
+|
+o  0   5d1a6b64f9d0   1970-01-01 00:00 +0000   test
+     origin
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-conflict-2	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,63 @@
+#!/bin/sh
+
+# Fails for some reason, need to investigate
+# "$TESTDIR/hghave" git || exit 80
+
+# bail if the user does not have dulwich
+python -c 'import dulwich, dulwich.repo' || exit 80
+
+# bail early if the user is already running git-daemon
+echo hi | nc localhost 9418 2>/dev/null && exit 80
+
+echo "[extensions]" >> $HGRCPATH
+echo "hggit=$(echo $(dirname $(dirname $0)))/hggit" >> $HGRCPATH
+echo 'hgext.graphlog =' >> $HGRCPATH
+echo 'hgext.bookmarks =' >> $HGRCPATH
+
+hg init hgrepo1
+cd hgrepo1
+echo A > afile
+hg add afile
+hg ci -m "origin"
+
+echo B > afile
+hg ci -m "A->B"
+
+hg up -r0
+echo C > afile
+hg ci -m "A->C"
+
+hg merge -r1 | sed 's/-C ./-C/' | grep -v 'merging afile'
+# resolve using second parent
+echo B > afile
+hg resolve -m afile
+hg ci -m "merge to B"
+
+hg log --graph --style compact | sed 's/\[.*\]//g'
+
+cd ..
+
+mkdir gitrepo
+cd gitrepo
+git init --bare | python -c "import sys; print sys.stdin.read().replace('$(dirname $(pwd))/', '')"
+
+# dulwich does not presently support local git repos, workaround
+cd ..
+git daemon --base-path="$(pwd)"\
+ --listen=localhost\
+ --export-all\
+ --pid-file="$DAEMON_PIDS" \
+ --detach --reuseaddr \
+ --enable=receive-pack
+
+cd hgrepo1
+hg bookmark -r tip master
+hg push -r master git://localhost/gitrepo
+cd ..
+
+hg clone git://localhost/gitrepo hgrepo2 | grep -v '^updating'
+cd hgrepo2
+echo % expect the same revision ids as above
+hg log --graph --style compact | sed 's/\[.*\]//g'
+
+cd ..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-conflict-2.out	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,38 @@
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+created new head
+warning: conflicts during merge.
+merging afile failed!
+0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+use 'hg resolve' to retry unresolved file merges or 'hg update -C' to abandon
+@    3:2,1   120385945d08   1970-01-01 00:00 +0000   test
+|\     merge to B
+| |
+| o  2:0   ea82b67264a1   1970-01-01 00:00 +0000   test
+| |    A->C
+| |
+o |  1   7205e83b5a3f   1970-01-01 00:00 +0000   test
+|/     A->B
+|
+o  0   5d1a6b64f9d0   1970-01-01 00:00 +0000   test
+     origin
+
+Initialized empty Git repository in gitrepo/
+
+pushing to git://localhost/gitrepo
+exporting hg objects to git
+creating and sending data
+importing git objects into hg
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+% expect the same revision ids as above
+@    3:1,2   120385945d08   1970-01-01 00:00 +0000   test
+|\     merge to B
+| |
+| o  2:0   7205e83b5a3f   1970-01-01 00:00 +0000   test
+| |    A->B
+| |
+o |  1   ea82b67264a1   1970-01-01 00:00 +0000   test
+|/     A->C
+|
+o  0   5d1a6b64f9d0   1970-01-01 00:00 +0000   test
+     origin
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-convergedmerge	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,63 @@
+#!/bin/sh
+
+# Fails for some reason, need to investigate
+# "$TESTDIR/hghave" git || exit 80
+
+# bail if the user does not have dulwich
+python -c 'import dulwich, dulwich.repo' || exit 80
+
+# bail early if the user is already running git-daemon
+echo hi | nc localhost 9418 2>/dev/null && exit 80
+
+echo "[extensions]" >> $HGRCPATH
+echo "hggit=$(echo $(dirname $(dirname $0)))/hggit" >> $HGRCPATH
+echo 'hgext.graphlog =' >> $HGRCPATH
+echo 'hgext.bookmarks =' >> $HGRCPATH
+
+hg init hgrepo1
+cd hgrepo1
+echo A > afile
+hg add afile 
+hg ci -m "origin"
+
+echo B > afile
+hg ci -m "A->B"
+
+echo C > afile
+hg ci -m "B->C"
+
+hg up -r0
+echo C > afile
+hg ci -m "A->C"
+
+hg merge -r2
+hg ci -m "merge"
+
+hg log --graph --style compact | sed 's/\[.*\]//g'
+
+cd ..
+
+mkdir gitrepo
+cd gitrepo
+git init --bare | python -c "import sys; print sys.stdin.read().replace('$(dirname $(pwd))/', '')"
+
+# dulwich does not presently support local git repos, workaround
+cd ..
+git daemon --base-path="$(pwd)"\
+ --listen=localhost\
+ --export-all\
+ --pid-file="$DAEMON_PIDS" \
+ --detach --reuseaddr \
+ --enable=receive-pack
+
+cd hgrepo1
+hg bookmark -r4 master
+hg push -r master git://localhost/gitrepo
+cd ..
+
+hg clone git://localhost/gitrepo hgrepo2 | grep -v '^updating'
+cd hgrepo2
+echo % expect the same revision ids as above
+hg log --graph --style compact | sed 's/\[.*\]//g'
+
+cd ..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-convergedmerge.out	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,42 @@
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+created new head
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+(branch merge, don't forget to commit)
+@    4:3,2   eaa21d002113   1970-01-01 00:00 +0000   test
+|\     merge
+| |
+| o  3:0   ea82b67264a1   1970-01-01 00:00 +0000   test
+| |    A->C
+| |
+o |  2   0dbe4ac1a758   1970-01-01 00:00 +0000   test
+| |    B->C
+| |
+o |  1   7205e83b5a3f   1970-01-01 00:00 +0000   test
+|/     A->B
+|
+o  0   5d1a6b64f9d0   1970-01-01 00:00 +0000   test
+     origin
+
+Initialized empty Git repository in gitrepo/
+
+pushing to git://localhost/gitrepo
+exporting hg objects to git
+creating and sending data
+importing git objects into hg
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+% expect the same revision ids as above
+@    4:1,3   eaa21d002113   1970-01-01 00:00 +0000   test
+|\     merge
+| |
+| o  3   0dbe4ac1a758   1970-01-01 00:00 +0000   test
+| |    B->C
+| |
+| o  2:0   7205e83b5a3f   1970-01-01 00:00 +0000   test
+| |    A->B
+| |
+o |  1   ea82b67264a1   1970-01-01 00:00 +0000   test
+|/     A->C
+|
+o  0   5d1a6b64f9d0   1970-01-01 00:00 +0000   test
+     origin
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-empty-working-tree	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,59 @@
+#!/bin/sh
+
+# Fails for some reason, need to investigate
+# "$TESTDIR/hghave" git || exit 80
+
+# bail if the user does not have dulwich
+python -c 'import dulwich, dulwich.repo' || exit 80
+
+# bail early if the user is already running git-daemon
+echo hi | nc localhost 9418 2> /dev/null && exit 80
+
+echo "[extensions]" >> $HGRCPATH
+echo "hggit=$(echo $(dirname $(dirname $0)))/hggit" >> $HGRCPATH
+echo 'hgext.bookmarks =' >> $HGRCPATH
+
+cat >> $HGRCPATH <<EOF
+
+[bookmarks]
+track.current = True
+EOF
+
+GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
+GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
+GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0000"; export GIT_AUTHOR_DATE
+GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME
+GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL
+GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE
+
+mkdir gitrepo
+cd gitrepo
+git init | python -c "import sys; print sys.stdin.read().replace('$(dirname $(pwd))/', '')"
+
+git commit --allow-empty -m empty >/dev/null 2>/dev/null || echo "git commit error"
+
+cd ..
+mkdir gitrepo2
+cd gitrepo2
+git init --bare | python -c "import sys; print sys.stdin.read().replace('$(dirname $(pwd))/', '')"
+
+# dulwich does not presently support local git repos, workaround
+cd ..
+git daemon --base-path="$(pwd)"\
+ --listen=localhost\
+ --export-all\
+ --pid-file="$DAEMON_PIDS" \
+ --detach --reuseaddr \
+ --enable=receive-pack
+
+hg clone git://localhost/gitrepo hgrepo | grep -v '^updating'
+cd hgrepo
+hg log -r tip --template 'files: {files}\n'
+
+hg gclear
+hg push git://localhost/gitrepo2
+
+cd ../gitrepo2
+git log --pretty=medium
+
+cd ..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-empty-working-tree.out	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,16 @@
+Initialized empty Git repository in gitrepo/.git/
+
+Initialized empty Git repository in gitrepo2/
+
+importing git objects into hg
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+files: 
+clearing out the git cache data
+pushing to git://localhost/gitrepo2
+exporting hg objects to git
+creating and sending data
+commit 678256865a8c85ae925bf834369264193c88f8de
+Author: test <test@example.org>
+Date:   Mon Jan 1 00:00:00 2007 +0000
+
+    empty
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-encoding	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,71 @@
+#!/bin/sh
+
+# -*- coding: utf-8 -*-
+
+# Fails for some reason, need to investigate
+# "$TESTDIR/hghave" git || exit 80
+
+# bail if the user does not have dulwich
+python -c 'import dulwich, dulwich.repo' || exit 80
+
+# bail early if the user is already running git-daemon
+echo hi | nc localhost 9418 2>/dev/null && exit 80
+
+echo "[extensions]" >> $HGRCPATH
+echo "hggit=$(echo $(dirname $(dirname $0)))/hggit" >> $HGRCPATH
+echo 'hgext.graphlog =' >> $HGRCPATH
+echo 'hgext.bookmarks =' >> $HGRCPATH
+
+GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
+GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
+GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0000"; export GIT_AUTHOR_DATE
+GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME
+GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL
+GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE
+
+count=10
+commit()
+{
+    GIT_AUTHOR_DATE="2007-01-01 00:00:$count +0000"
+    GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
+    git commit "$@" >/dev/null || echo "git commit error"
+    count=`expr $count + 1`
+}
+
+mkdir gitrepo
+cd gitrepo
+git init | python -c "import sys; print sys.stdin.read().replace('$(dirname $(pwd))/', '')"
+
+# utf-8 encoded commit message
+echo alpha > alpha
+git add alpha
+commit -m 'add älphà'
+
+. $TESTDIR/latin-1-encoding
+
+cd ..
+mkdir gitrepo2
+cd gitrepo2
+git init --bare | python -c "import sys; print sys.stdin.read().replace('$(dirname $(pwd))/', '')"
+
+# dulwich does not presently support local git repos, workaround
+cd ..
+git daemon --base-path="$(pwd)"\
+ --listen=localhost\
+ --export-all\
+ --pid-file="$DAEMON_PIDS" \
+ --detach --reuseaddr \
+ --enable=receive-pack
+
+hg clone git://localhost/gitrepo hgrepo | grep -v '^updating'
+cd hgrepo
+
+HGENCODING=utf-8 hg log --graph --debug | grep -v ': *master'
+
+hg gclear
+hg push git://localhost/gitrepo2
+
+cd ../gitrepo2
+git log --pretty=medium
+
+cd ..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-encoding.out	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,98 @@
+Initialized empty Git repository in gitrepo/.git/
+
+Warning: commit message does not conform to UTF-8.
+You may want to amend it after fixing the message, or set the config
+variable i18n.commitencoding to the encoding your project uses.
+Warning: commit message does not conform to UTF-8.
+You may want to amend it after fixing the message, or set the config
+variable i18n.commitencoding to the encoding your project uses.
+Initialized empty Git repository in gitrepo2/
+
+importing git objects into hg
+4 files updated, 0 files merged, 0 files removed, 0 files unresolved
+@  changeset:   3:8549ee7fe0801b2dafc06047ca6f66d36da709f5
+|  tag:         default/master
+|  tag:         tip
+|  parent:      2:0422fbb4ec39fb69e87b94a3874ac890333de11a
+|  parent:      -1:0000000000000000000000000000000000000000
+|  manifest:    3:ea49f93388380ead5601c8fcbfa187516e7c2ed8
+|  user:        tést èncödîng <test@example.org>
+|  date:        Mon Jan 01 00:00:13 2007 +0000
+|  files+:      delta
+|  extra:       author=$ \x90\x01\x01\xe9\x91\x03\x03\x01\xe8\x91\x08\x02\x01\xf6\x91\x0c\x01\x01\xee\x91\x0f\x15
+|  extra:       branch=default
+|  extra:       committer=test <test@example.org> 1167609613 0
+|  extra:       encoding=latin-1
+|  extra:       message=\x0c\n\x90\x05\x01\xe9\x91\x07\x02\x01\xe0\x91\x0b\x01
+|  description:
+|  add déltà
+|
+|
+o  changeset:   2:0422fbb4ec39fb69e87b94a3874ac890333de11a
+|  parent:      1:9f6268bfc9eb3956c5ab8752d7b983b0ffe57115
+|  parent:      -1:0000000000000000000000000000000000000000
+|  manifest:    2:f580e7da3673c137370da2b931a1dee83590d7b4
+|  user:        tést èncödîng <test@example.org>
+|  date:        Mon Jan 01 00:00:12 2007 +0000
+|  files+:      gamma
+|  extra:       author=$ \x90\x01\x01\xe9\x91\x03\x03\x01\xe8\x91\x08\x02\x01\xf6\x91\x0c\x01\x01\xee\x91\x0f\x15
+|  extra:       branch=default
+|  extra:       committer=test <test@example.org> 1167609612 0
+|  extra:       message=\x0c\n\x90\x05\x01\xe4\x91\x07\x02\x01\xe2\x91\x0b\x01
+|  description:
+|  add gämmâ
+|
+|
+o  changeset:   1:9f6268bfc9eb3956c5ab8752d7b983b0ffe57115
+|  parent:      0:bb7d36568d6188ce0de2392246c43f6f213df954
+|  parent:      -1:0000000000000000000000000000000000000000
+|  manifest:    1:f0bd6fbafbaebe4bb59c35108428f6fce152431d
+|  user:        tést èncödîng <test@example.org>
+|  date:        Mon Jan 01 00:00:11 2007 +0000
+|  files+:      beta
+|  extra:       author=$ \x90\x01\x01\xe9\x91\x03\x03\x01\xe8\x91\x08\x02\x01\xf6\x91\x0c\x01\x01\xee\x91\x0f\x15
+|  extra:       branch=default
+|  extra:       committer=test <test@example.org> 1167609611 0
+|  description:
+|  add beta
+|
+|
+o  changeset:   0:bb7d36568d6188ce0de2392246c43f6f213df954
+   parent:      -1:0000000000000000000000000000000000000000
+   parent:      -1:0000000000000000000000000000000000000000
+   manifest:    0:8b8a0e87dfd7a0706c0524afa8ba67e20544cbf0
+   user:        test <test@example.org>
+   date:        Mon Jan 01 00:00:10 2007 +0000
+   files+:      alpha
+   extra:       branch=default
+   description:
+   add älphà
+
+
+clearing out the git cache data
+pushing to git://localhost/gitrepo2
+exporting hg objects to git
+creating and sending data
+commit da0edb01d4f3d1abf08b1be298379b0b2960e680
+Author: tst ncdng <test@example.org>
+Date:   Mon Jan 1 00:00:13 2007 +0000
+
+    add dlt
+
+commit 2372b6c8f1b91f2db8ae5eb0f9e0427c318b449c
+Author: tst ncdng <test@example.org>
+Date:   Mon Jan 1 00:00:12 2007 +0000
+
+    add gmm
+
+commit 9ef7f6dcffe643b89ba63f3323621b9a923e4802
+Author: tst ncdng <test@example.org>
+Date:   Mon Jan 1 00:00:11 2007 +0000
+
+    add beta
+
+commit 0530b75d8c203e10dc934292a6a4032c6e958a83
+Author: test <test@example.org>
+Date:   Mon Jan 1 00:00:10 2007 +0000
+
+    add älphà
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-file-removal	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,85 @@
+#!/bin/sh
+
+# Fails for some reason, need to investigate
+# "$TESTDIR/hghave" git || exit 80
+
+# bail if the user does not have dulwich
+python -c 'import dulwich, dulwich.repo' || exit 80
+
+# bail early if the user is already running git-daemon
+echo hi | nc localhost 9418 2>/dev/null && exit 80
+
+echo "[extensions]" >> $HGRCPATH
+echo "hggit=$(echo $(dirname $(dirname $0)))/hggit" >> $HGRCPATH
+echo 'hgext.graphlog =' >> $HGRCPATH
+echo 'hgext.bookmarks =' >> $HGRCPATH
+
+GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
+GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
+GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0000"; export GIT_AUTHOR_DATE
+GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME
+GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL
+GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE
+
+count=10
+commit()
+{
+    GIT_AUTHOR_DATE="2007-01-01 00:00:$count +0000"
+    GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
+    git commit "$@" >/dev/null 2>/dev/null || echo "git commit error"
+    count=`expr $count + 1`
+}
+
+mkdir gitrepo
+cd gitrepo
+git init | python -c "import sys; print sys.stdin.read().replace('$(dirname $(pwd))/', '')"
+echo alpha > alpha
+git add alpha
+commit -m 'add alpha'
+echo beta > beta
+git add beta
+commit -m 'add beta'
+mkdir foo
+echo blah > foo/bar
+git add foo
+commit -m 'add foo'
+git rm alpha
+commit -m 'remove alpha'
+git rm foo/bar
+commit -m 'remove foo/bar'
+echo % final manifest in git is just beta
+git ls-files
+
+cd ..
+mkdir gitrepo2
+cd gitrepo2
+git init --bare | python -c "import sys; print sys.stdin.read().replace('$(dirname $(pwd))/', '')"
+
+# dulwich does not presently support local git repos, workaround
+cd ..
+git daemon --base-path="$(pwd)"\
+ --listen=localhost\
+ --export-all\
+ --pid-file="$DAEMON_PIDS" \
+ --detach --reuseaddr \
+ --enable=receive-pack
+
+hg clone git://localhost/gitrepo hgrepo | grep -v '^updating'
+cd hgrepo
+hg log --graph | grep -v ': *master'
+
+echo
+echo % make sure alpha is not in this manifest
+hg manifest -r 3
+
+echo
+echo % make sure that only beta is in the manifest
+hg manifest
+
+hg gclear
+hg push git://localhost/gitrepo2
+
+cd ../gitrepo2
+git log --pretty=medium
+
+cd ..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-file-removal.out	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,77 @@
+Initialized empty Git repository in gitrepo/.git/
+
+rm 'alpha'
+rm 'foo/bar'
+% final manifest in git is just beta
+beta
+Initialized empty Git repository in gitrepo2/
+
+importing git objects into hg
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+@  changeset:   4:ea41a3f0ed10
+|  tag:         default/master
+|  tag:         tip
+|  user:        test <test@example.org>
+|  date:        Mon Jan 01 00:00:14 2007 +0000
+|  summary:     remove foo/bar
+|
+o  changeset:   3:c84537f94bcc
+|  user:        test <test@example.org>
+|  date:        Mon Jan 01 00:00:13 2007 +0000
+|  summary:     remove alpha
+|
+o  changeset:   2:e25450e1354f
+|  user:        test <test@example.org>
+|  date:        Mon Jan 01 00:00:12 2007 +0000
+|  summary:     add foo
+|
+o  changeset:   1:7bcd915dc873
+|  user:        test <test@example.org>
+|  date:        Mon Jan 01 00:00:11 2007 +0000
+|  summary:     add beta
+|
+o  changeset:   0:3442585be8a6
+   user:        test <test@example.org>
+   date:        Mon Jan 01 00:00:10 2007 +0000
+   summary:     add alpha
+
+
+% make sure alpha is not in this manifest
+beta
+foo/bar
+
+% make sure that only beta is in the manifest
+beta
+clearing out the git cache data
+pushing to git://localhost/gitrepo2
+exporting hg objects to git
+creating and sending data
+commit b991de8952c482a7cd51162674ffff8474862218
+Author: test <test@example.org>
+Date:   Mon Jan 1 00:00:14 2007 +0000
+
+    remove foo/bar
+
+commit b0edaf0adac19392cf2867498b983bc5192b41dd
+Author: test <test@example.org>
+Date:   Mon Jan 1 00:00:13 2007 +0000
+
+    remove alpha
+
+commit f2d0d5bfa905e12dee728b509b96cf265bb6ee43
+Author: test <test@example.org>
+Date:   Mon Jan 1 00:00:12 2007 +0000
+
+    add foo
+
+commit 9497a4ee62e16ee641860d7677cdb2589ea15554
+Author: test <test@example.org>
+Date:   Mon Jan 1 00:00:11 2007 +0000
+
+    add beta
+
+commit 7eeab2ea75ec1ac0ff3d500b5b6f8a3447dd7c03
+Author: test <test@example.org>
+Date:   Mon Jan 1 00:00:10 2007 +0000
+
+    add alpha
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-git-clone	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,50 @@
+#!/bin/sh
+
+# Fails for some reason, need to investigate
+# "$TESTDIR/hghave" git || exit 80
+
+# bail if the user does not have dulwich
+python -c 'import dulwich, dulwich.repo' || exit 80
+
+# bail early if the user is already running git-daemon
+echo hi | nc localhost 9418 2>/dev/null && exit 80
+
+echo "[extensions]" >> $HGRCPATH
+echo "hggit=$(echo $(dirname $(dirname $0)))/hggit" >> $HGRCPATH
+echo 'hgext.graphlog =' >> $HGRCPATH
+echo 'hgext.bookmarks =' >> $HGRCPATH
+
+GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
+GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
+GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0000"; export GIT_AUTHOR_DATE
+GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME
+GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL
+GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE
+
+count=10
+commit()
+{
+    GIT_AUTHOR_DATE="2007-01-01 00:00:$count +0000"
+    GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
+    git commit "$@" >/dev/null 2>/dev/null || echo "git commit error"
+    count=`expr $count + 1`
+}
+
+mkdir gitrepo
+cd gitrepo
+git init | python -c "import sys; print sys.stdin.read().replace('$(dirname $(pwd))/', '')"
+echo alpha > alpha
+git add alpha
+commit -m 'add alpha'
+echo beta > beta
+git add beta
+commit -m 'add beta'
+
+cd ..
+
+hg clone gitrepo hgrepo | grep -v '^updating'
+cd hgrepo
+hg log --graph  | grep -v ': *master'
+
+echo % we should have some bookmarks
+hg book
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-git-clone.out	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,18 @@
+Initialized empty Git repository in gitrepo/.git/
+
+importing git objects into hg
+2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+@  changeset:   1:7bcd915dc873
+|  tag:         default/master
+|  tag:         tip
+|  user:        test <test@example.org>
+|  date:        Mon Jan 01 00:00:11 2007 +0000
+|  summary:     add beta
+|
+o  changeset:   0:3442585be8a6
+   user:        test <test@example.org>
+   date:        Mon Jan 01 00:00:10 2007 +0000
+   summary:     add alpha
+
+% we should have some bookmarks
+ * master                    1:7bcd915dc873
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-git-submodules	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,72 @@
+#!/bin/sh
+
+# Fails for some reason, need to investigate
+# "$TESTDIR/hghave" git || exit 80
+
+# bail if the user does not have dulwich
+python -c 'import dulwich, dulwich.repo' || exit 80
+
+# bail early if the user is already running git-daemon
+echo hi | nc localhost 9418 2>/dev/null && exit 80
+
+echo "[extensions]" >> $HGRCPATH
+echo "hggit=$(echo $(dirname $(dirname $0)))/hggit" >> $HGRCPATH
+echo 'hgext.graphlog =' >> $HGRCPATH
+echo 'hgext.bookmarks =' >> $HGRCPATH
+
+GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
+GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
+GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0000"; export GIT_AUTHOR_DATE
+GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME
+GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL
+GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE
+
+count=10
+commit()
+{
+    GIT_AUTHOR_DATE="2007-01-01 00:00:$count +0000"
+    GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
+    git commit "$@" >/dev/null 2>/dev/null || echo "git commit error"
+    count=`expr $count + 1`
+}
+
+mkdir gitrepo1
+cd gitrepo1
+git init | python -c "import sys; print sys.stdin.read().replace('$(dirname $(pwd))/', '')"
+echo alpha > alpha
+git add alpha
+commit -m 'add alpha'
+cd ..
+
+mkdir gitsubrepo
+cd gitsubrepo
+git init | python -c "import sys; print sys.stdin.read().replace('$(dirname $(pwd))/', '')"
+echo beta > beta
+git add beta
+commit -m 'add beta'
+cd ..
+
+mkdir gitrepo2
+cd gitrepo2
+
+rmpwd="import sys; print sys.stdin.read().replace('$(dirname $(pwd))/', '')"
+# different versions of git spell the dir differently. Older versions
+# use the full path to the directory all the time, whereas newer
+# version spell it sanely as it was given (eg . in a newer version,
+# while older git will use the full normalized path for .)
+clonefilt='s/Cloning into/Initialized empty Git repository in/;s/in .*/in .../'
+
+git clone ../gitrepo1 . | python -c "$rmpwd" | sed "$clonefilt" | egrep -v '^done\.$'
+git submodule add ../gitsubrepo subrepo | python -c "$rmpwd" | sed "$clonefilt" | egrep -v '^done\.$'
+git commit -m 'add subrepo'
+git rm --cached subrepo
+git rm .gitmodules
+git commit -m 'rm subrepo'
+cd ..
+
+hg clone gitrepo2 hgrepo | grep -v '^updating'
+cd hgrepo
+hg log --graph  | grep -v ': *master'
+
+echo % we should have some bookmarks
+hg book
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-git-submodules.out	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,39 @@
+Initialized empty Git repository in gitrepo1/.git/
+
+Initialized empty Git repository in gitsubrepo/.git/
+
+Initialized empty Git repository in ...
+
+Initialized empty Git repository in ...
+
+[master e42b08b] add subrepo
+ 2 files changed, 4 insertions(+), 0 deletions(-)
+ create mode 100644 .gitmodules
+ create mode 160000 subrepo
+rm 'subrepo'
+rm '.gitmodules'
+[master 7e4c934] rm subrepo
+ 2 files changed, 0 insertions(+), 4 deletions(-)
+ delete mode 100644 .gitmodules
+ delete mode 160000 subrepo
+importing git objects into hg
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+@  changeset:   2:954cdf1c8c82
+|  tag:         default/master
+|  tag:         tip
+|  user:        test <test@example.org>
+|  date:        Mon Jan 01 00:00:11 2007 +0000
+|  summary:     rm subrepo
+|
+o  changeset:   1:145121c71064
+|  user:        test <test@example.org>
+|  date:        Mon Jan 01 00:00:11 2007 +0000
+|  summary:     add subrepo
+|
+o  changeset:   0:3442585be8a6
+   user:        test <test@example.org>
+   date:        Mon Jan 01 00:00:10 2007 +0000
+   summary:     add alpha
+
+% we should have some bookmarks
+ * master                    2:954cdf1c8c82
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-git-tags	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,71 @@
+#!/bin/sh
+
+# Fails for some reason, need to investigate
+# "$TESTDIR/hghave" git || exit 80
+
+# bail if the user does not have dulwich
+python -c 'import dulwich, dulwich.repo' || exit 80
+
+# bail early if the user is already running git-daemon
+echo hi | nc localhost 9418 2>/dev/null && exit 80
+
+echo "[extensions]" >> $HGRCPATH
+echo "hggit=$(echo $(dirname $(dirname $0)))/hggit" >> $HGRCPATH
+echo 'hgext.graphlog =' >> $HGRCPATH
+echo 'hgext.bookmarks =' >> $HGRCPATH
+
+GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
+GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
+GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0000"; export GIT_AUTHOR_DATE
+GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME
+GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL
+GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE
+
+count=10
+commit()
+{
+    GIT_AUTHOR_DATE="2007-01-01 00:00:$count +0000"
+    GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
+    git commit "$@" >/dev/null 2>/dev/null || echo "git commit error"
+    count=`expr $count + 1`
+}
+tag()
+{
+    GIT_AUTHOR_DATE="2007-01-01 00:00:$count +0000"
+    GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
+    git tag "$@" >/dev/null 2>/dev/null || echo "git commit error"
+    count=`expr $count + 1`
+}
+
+mkdir gitrepo
+cd gitrepo
+git init | python -c "import sys; print sys.stdin.read().replace('$(dirname $(pwd))/', '')"
+git config receive.denyCurrentBranch ignore
+echo alpha > alpha
+git add alpha
+commit -m 'add alpha'
+tag alpha
+
+echo beta > beta
+git add beta
+commit -m 'add beta'
+tag -a -m 'added tag beta' beta
+
+# dulwich does not presently support local git repos, workaround
+cd ..
+git daemon --base-path="$(pwd)"\
+ --listen=localhost\
+ --export-all\
+ --pid-file="$DAEMON_PIDS" \
+ --detach --reuseaddr \
+ --enable=receive-pack
+
+hg clone git://localhost/gitrepo hgrepo | grep -v '^updating'
+
+cd hgrepo
+hg log --graph  | grep -v ': *master'
+echo beta-fix >> beta
+hg commit -m 'fix for beta'
+hg push
+
+cd ..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-git-tags.out	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,24 @@
+Initialized empty Git repository in gitrepo/.git/
+
+importing git objects into hg
+2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+@  changeset:   1:99dcc15b7b07
+|  tag:         beta
+|  tag:         default/master
+|  tag:         tip
+|  user:        test <test@example.org>
+|  date:        Mon Jan 01 00:00:12 2007 +0000
+|  summary:     add beta
+|
+o  changeset:   0:3442585be8a6
+   tag:         alpha
+   user:        test <test@example.org>
+   date:        Mon Jan 01 00:00:10 2007 +0000
+   summary:     add alpha
+
+pushing to git://localhost/gitrepo
+exporting hg objects to git
+creating and sending data
+    default::refs/tags/beta => GIT:e6f255c6
+    default::refs/tags/alpha => GIT:7eeab2ea
+    default::refs/heads/master => GIT:3b7fd1b3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-git-workflow	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,69 @@
+#!/bin/sh
+
+# Fails for some reason, need to investigate
+# "$TESTDIR/hghave" git || exit 80
+
+# bail if the user does not have dulwich
+python -c 'import dulwich, dulwich.repo' || exit 80
+
+# bail early if the user is already running git-daemon
+echo hi | nc localhost 9418 2>/dev/null && exit 80
+
+echo "[extensions]" >> $HGRCPATH
+echo "hggit=$(echo $(dirname $(dirname $0)))/hggit" >> $HGRCPATH
+echo 'hgext.graphlog =' >> $HGRCPATH
+echo 'hgext.bookmarks =' >> $HGRCPATH
+
+GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
+GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
+GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0000"; export GIT_AUTHOR_DATE
+GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME
+GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL
+GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE
+
+count=10
+commit()
+{
+    GIT_AUTHOR_DATE="2007-01-01 00:00:$count +0000"
+    GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
+    git commit "$@" >/dev/null 2>/dev/null || echo "git commit error"
+    count=`expr $count + 1`
+}
+hgcommit()
+{
+    HGDATE="2007-01-01 00:00:$count +0000"
+    hg commit -d "$HGDATE" "$@" >/dev/null 2>/dev/null || echo "hg commit error"
+    count=`expr $count + 1`
+}
+
+mkdir hgrepo
+cd hgrepo
+hg init
+
+echo alpha > alpha
+hg add alpha
+hgcommit -m "add alpha"
+hg log --graph --debug
+
+cd ..
+
+echo % configure for use from git
+hg clone hgrepo gitrepo
+cd gitrepo
+hg book master
+hg up null
+echo "[git]" >> .hg/hgrc
+echo "intree = True" >> .hg/hgrc
+hg gexport
+
+echo % do some work
+git config core.bare false
+git checkout master 2>&1 | sed s/\'/\"/g
+echo beta > beta
+git add beta
+commit -m 'add beta'
+
+echo % get things back to hg
+hg gimport
+hg log --graph --debug | grep -v ': *master'
+hg bookmarks
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-git-workflow.out	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,48 @@
+@  changeset:   0:0221c246a56712c6aa64e5ee382244d8a471b1e2
+   tag:         tip
+   parent:      -1:0000000000000000000000000000000000000000
+   parent:      -1:0000000000000000000000000000000000000000
+   manifest:    0:8b8a0e87dfd7a0706c0524afa8ba67e20544cbf0
+   user:        test
+   date:        Mon Jan 01 00:00:10 2007 +0000
+   files+:      alpha
+   extra:       branch=default
+   description:
+   add alpha
+
+
+% configure for use from git
+updating to branch default
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+exporting hg objects to git
+% do some work
+Already on "master"
+% get things back to hg
+importing git objects into hg
+o  changeset:   1:7108ae7bd184226a29b8203619a8253d314643bf
+|  tag:         tip
+|  parent:      0:0221c246a56712c6aa64e5ee382244d8a471b1e2
+|  parent:      -1:0000000000000000000000000000000000000000
+|  manifest:    1:f0bd6fbafbaebe4bb59c35108428f6fce152431d
+|  user:        test <test@example.org>
+|  date:        Mon Jan 01 00:00:11 2007 +0000
+|  files+:      beta
+|  extra:       branch=default
+|  description:
+|  add beta
+|
+|
+o  changeset:   0:0221c246a56712c6aa64e5ee382244d8a471b1e2
+   parent:      -1:0000000000000000000000000000000000000000
+   parent:      -1:0000000000000000000000000000000000000000
+   manifest:    0:8b8a0e87dfd7a0706c0524afa8ba67e20544cbf0
+   user:        test
+   date:        Mon Jan 01 00:00:10 2007 +0000
+   files+:      alpha
+   extra:       branch=default
+   description:
+   add alpha
+
+
+   master                    1:7108ae7bd184
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-hg-author	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,84 @@
+#!/bin/sh
+
+# Fails for some reason, need to investigate
+# "$TESTDIR/hghave" git || exit 80
+
+# bail if the user does not have dulwich
+python -c 'import dulwich, dulwich.repo' || exit 80
+
+# bail early if the user is already running git-daemon
+echo hi | nc localhost 9418 2>/dev/null && exit 80
+
+echo "[extensions]" >> $HGRCPATH
+echo "hggit=$(echo $(dirname $(dirname $0)))/hggit" >> $HGRCPATH
+echo 'hgext.graphlog =' >> $HGRCPATH
+echo 'hgext.bookmarks =' >> $HGRCPATH
+
+cat >> $HGRCPATH <<EOF
+
+[bookmarks]
+track.current = True
+EOF
+
+
+GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
+GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
+GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0000"; export GIT_AUTHOR_DATE
+GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME
+GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL
+GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE
+
+count=10
+commit()
+{
+    GIT_AUTHOR_DATE="2007-01-01 00:00:$count +0000"
+    GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
+    git commit "$@" >/dev/null 2>/dev/null || echo "git commit error"
+    count=`expr $count + 1`
+}
+hgcommit()
+{
+    HGDATE="2007-01-01 00:00:$count +0000"
+    hg commit -d "$HGDATE" "$@" >/dev/null 2>/dev/null || echo "hg commit error"
+    count=`expr $count + 1`
+}
+
+mkdir gitrepo
+cd gitrepo
+git init | python -c "import sys; print sys.stdin.read().replace('$(dirname $(pwd))/', '')"
+
+echo alpha > alpha
+git add alpha
+commit -m "add alpha"
+git checkout -b not-master
+
+# dulwich does not presently support local git repos, workaround
+cd ..
+git daemon --base-path="$(pwd)"\
+ --listen=localhost\
+ --export-all\
+ --pid-file="$DAEMON_PIDS" \
+ --detach --reuseaddr \
+ --enable=receive-pack
+
+hg clone git://localhost/gitrepo hgrepo | grep -v '^updating'
+
+cd hgrepo
+hg co master
+echo beta > beta
+hg add beta
+hgcommit -u "test" -m 'add beta'
+hg push
+
+echo gamma >> beta
+hgcommit -u "test <test@example.com> (comment)" -m 'modify beta'
+hg push
+
+hg log --graph | egrep -v ': *(not-master|master)'
+
+cd ..
+hg clone git://localhost/gitrepo hgrepo2 | grep -v '^updating'
+cd hgrepo2
+hg log --graph | egrep -v ': *(not-master|master)'
+
+cd ..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-hg-author.out	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,54 @@
+Initialized empty Git repository in gitrepo/.git/
+
+Switched to a new branch 'not-master'
+importing git objects into hg
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+pushing to git://localhost/gitrepo
+exporting hg objects to git
+creating and sending data
+    default::refs/heads/not-master => GIT:7eeab2ea
+    default::refs/heads/master => GIT:cffa0e8d
+pushing to git://localhost/gitrepo
+exporting hg objects to git
+creating and sending data
+    default::refs/heads/not-master => GIT:7eeab2ea
+    default::refs/heads/master => GIT:2b9ec6a4
+@  changeset:   2:92d33c0dd6e1
+|  tag:         default/master
+|  tag:         tip
+|  user:        test <test@example.com> (comment)
+|  date:        Mon Jan 01 00:00:12 2007 +0000
+|  summary:     modify beta
+|
+o  changeset:   1:0564f526fb0f
+|  user:        test
+|  date:        Mon Jan 01 00:00:11 2007 +0000
+|  summary:     add beta
+|
+o  changeset:   0:3442585be8a6
+   tag:         default/not-master
+   user:        test <test@example.org>
+   date:        Mon Jan 01 00:00:10 2007 +0000
+   summary:     add alpha
+
+importing git objects into hg
+2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+@  changeset:   2:92d33c0dd6e1
+|  tag:         default/master
+|  tag:         tip
+|  user:        test <test@example.com> (comment)
+|  date:        Mon Jan 01 00:00:12 2007 +0000
+|  summary:     modify beta
+|
+o  changeset:   1:0564f526fb0f
+|  user:        test
+|  date:        Mon Jan 01 00:00:11 2007 +0000
+|  summary:     add beta
+|
+o  changeset:   0:3442585be8a6
+   tag:         default/not-master
+   user:        test <test@example.org>
+   date:        Mon Jan 01 00:00:10 2007 +0000
+   summary:     add alpha
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-hg-branch	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,85 @@
+#!/bin/sh
+
+# Fails for some reason, need to investigate
+# "$TESTDIR/hghave" git || exit 80
+
+# bail if the user does not have dulwich
+python -c 'import dulwich, dulwich.repo' || exit 80
+
+# bail early if the user is already running git-daemon
+echo hi | nc localhost 9418 2>/dev/null && exit 80
+
+echo "[extensions]" >> $HGRCPATH
+echo "hggit=$(echo $(dirname $(dirname $0)))/hggit" >> $HGRCPATH
+echo 'hgext.graphlog =' >> $HGRCPATH
+echo 'hgext.bookmarks =' >> $HGRCPATH
+cat >> $HGRCPATH <<EOF
+
+[bookmarks]
+track.current = True
+EOF
+
+GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
+GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
+GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0000"; export GIT_AUTHOR_DATE
+GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME
+GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL
+GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE
+
+# TODO stop using this when we're 1.5 only
+filterhash="sed s/71414c4e3c6f/a31e374801c9/;s/698615204564/d93a72262a83/"
+filterhash="$filterhash;s/d93a72262a83/05aed681ccb3/"
+
+count=10
+commit()
+{
+    GIT_AUTHOR_DATE="2007-01-01 00:00:$count +0000"
+    GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
+    git commit "$@" >/dev/null 2>/dev/null || echo "git commit error"
+    count=`expr $count + 1`
+}
+hgcommit()
+{
+    HGDATE="2007-01-01 00:00:$count +0000"
+    hg commit -d "$HGDATE" "$@" >/dev/null 2>/dev/null || echo "hg commit error"
+    count=`expr $count + 1`
+}
+
+mkdir gitrepo
+cd gitrepo
+git init | python -c "import sys; print sys.stdin.read().replace('$(dirname $(pwd))/', '')"
+
+echo alpha > alpha
+git add alpha
+commit -m "add alpha"
+git checkout -b not-master
+
+# dulwich does not presently support local git repos, workaround
+cd ..
+git daemon --base-path="$(pwd)"\
+ --listen=localhost\
+ --export-all\
+ --pid-file="$DAEMON_PIDS" \
+ --detach --reuseaddr \
+ --enable=receive-pack
+
+hg clone git://localhost/gitrepo hgrepo | grep -v '^updating'
+
+cd hgrepo
+hg co master
+hg mv alpha beta
+hgcommit -m 'rename alpha to beta'
+hg push
+
+hg branch gamma
+hgcommit -m 'started branch gamma'
+hg push
+
+hg log --graph | $filterhash | egrep -v ': *(not-master|master)'
+
+cd ..
+hg clone git://localhost/gitrepo hgrepo2 | grep -v '^updating'
+cd hgrepo2
+hg log --graph | $filterhash | egrep -v ': *(not-master|master)'
+
+cd ..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-hg-branch.out	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,57 @@
+Initialized empty Git repository in gitrepo/.git/
+
+Switched to a new branch 'not-master'
+importing git objects into hg
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+pushing to git://localhost/gitrepo
+exporting hg objects to git
+creating and sending data
+    default::refs/heads/not-master => GIT:7eeab2ea
+    default::refs/heads/master => GIT:05c2bcbe
+marked working directory as branch gamma
+pushing to git://localhost/gitrepo
+exporting hg objects to git
+creating and sending data
+    default::refs/heads/not-master => GIT:7eeab2ea
+    default::refs/heads/master => GIT:296802ef
+@  changeset:   2:05aed681ccb3
+|  branch:      gamma
+|  tag:         default/master
+|  tag:         tip
+|  user:        test
+|  date:        Mon Jan 01 00:00:12 2007 +0000
+|  summary:     started branch gamma
+|
+o  changeset:   1:a31e374801c9
+|  user:        test
+|  date:        Mon Jan 01 00:00:11 2007 +0000
+|  summary:     rename alpha to beta
+|
+o  changeset:   0:3442585be8a6
+   tag:         default/not-master
+   user:        test <test@example.org>
+   date:        Mon Jan 01 00:00:10 2007 +0000
+   summary:     add alpha
+
+importing git objects into hg
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+o  changeset:   2:05aed681ccb3
+|  branch:      gamma
+|  tag:         default/master
+|  tag:         tip
+|  user:        test
+|  date:        Mon Jan 01 00:00:12 2007 +0000
+|  summary:     started branch gamma
+|
+@  changeset:   1:a31e374801c9
+|  user:        test
+|  date:        Mon Jan 01 00:00:11 2007 +0000
+|  summary:     rename alpha to beta
+|
+o  changeset:   0:3442585be8a6
+   tag:         default/not-master
+   user:        test <test@example.org>
+   date:        Mon Jan 01 00:00:10 2007 +0000
+   summary:     add alpha
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-hg-tags	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,85 @@
+#!/bin/sh
+
+# Fails for some reason, need to investigate
+# "$TESTDIR/hghave" git || exit 80
+
+# bail if the user does not have dulwich
+python -c 'import dulwich, dulwich.repo' || exit 80
+
+# bail early if the user is already running git-daemon
+echo hi | nc localhost 9418 2>/dev/null && exit 80
+
+echo "[extensions]" >> $HGRCPATH
+echo "hggit=$(echo $(dirname $(dirname $0)))/hggit" >> $HGRCPATH
+echo 'hgext.graphlog =' >> $HGRCPATH
+echo 'hgext.bookmarks =' >> $HGRCPATH
+
+cat >> $HGRCPATH <<EOF
+
+[bookmarks]
+track.current = True
+EOF
+
+GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
+GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
+GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0000"; export GIT_AUTHOR_DATE
+GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME
+GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL
+GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE
+
+count=10
+commit()
+{
+    GIT_AUTHOR_DATE="2007-01-01 00:00:$count +0000"
+    GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
+    git commit "$@" >/dev/null 2>/dev/null || echo "git commit error"
+    count=`expr $count + 1`
+}
+hgtag()
+{
+    HGDATE="2007-01-01 00:00:$count +0000"
+    hg tag -d "$HGDATE" "$@" >/dev/null 2>/dev/null || echo "hg commit error"
+    count=`expr $count + 1`
+}
+
+mkdir gitrepo
+cd gitrepo
+git init | python -c "import sys; print sys.stdin.read().replace('$(dirname $(pwd))/', '')"
+
+echo alpha > alpha
+git add alpha
+commit -m "add alpha"
+git checkout -b not-master
+
+# dulwich does not presently support local git repos, workaround
+cd ..
+git daemon --base-path="$(pwd)"\
+ --listen=localhost\
+ --export-all\
+ --pid-file="$DAEMON_PIDS" \
+ --detach --reuseaddr \
+ --enable=receive-pack
+
+hg clone git://localhost/gitrepo hgrepo | grep -v '^updating'
+
+cd hgrepo
+hg co master
+hgtag alpha
+hg push
+
+hg log --graph | egrep -v ': *(not-master|master)'
+
+cd ..
+cd gitrepo
+echo % git should have the tag alpha
+git tag -l
+
+cd ..
+hg clone git://localhost/gitrepo hgrepo2 | grep -v '^updating'
+cd hgrepo2
+hg log --graph | egrep -v ': *(not-master|master)'
+
+echo % the tag should be in .hgtags
+cat .hgtags
+
+cd ..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-hg-tags.out	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,46 @@
+Initialized empty Git repository in gitrepo/.git/
+
+Switched to a new branch 'not-master'
+importing git objects into hg
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+0 files updated, 0 files merged, 0 files removed, 0 files unresolved
+pushing to git://localhost/gitrepo
+exporting hg objects to git
+creating and sending data
+    default::refs/heads/not-master => GIT:7eeab2ea
+    default::refs/tags/alpha => GIT:7eeab2ea
+    default::refs/heads/master => GIT:9a2616b9
+@  changeset:   1:d529e9229f6d
+|  tag:         default/master
+|  tag:         tip
+|  user:        test
+|  date:        Mon Jan 01 00:00:11 2007 +0000
+|  summary:     Added tag alpha for changeset 3442585be8a6
+|
+o  changeset:   0:3442585be8a6
+   tag:         alpha
+   tag:         default/not-master
+   user:        test <test@example.org>
+   date:        Mon Jan 01 00:00:10 2007 +0000
+   summary:     add alpha
+
+% git should have the tag alpha
+alpha
+importing git objects into hg
+2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+@  changeset:   1:d529e9229f6d
+|  tag:         default/master
+|  tag:         tip
+|  user:        test
+|  date:        Mon Jan 01 00:00:11 2007 +0000
+|  summary:     Added tag alpha for changeset 3442585be8a6
+|
+o  changeset:   0:3442585be8a6
+   tag:         alpha
+   tag:         default/not-master
+   user:        test <test@example.org>
+   date:        Mon Jan 01 00:00:10 2007 +0000
+   summary:     add alpha
+
+% the tag should be in .hgtags
+3442585be8a60c6cd476bbc4e45755339f2a23ef alpha
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-incoming	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,96 @@
+#!/bin/sh
+
+# Fails for some reason, need to investigate
+# "$TESTDIR/hghave" git || exit 80
+
+# bail if the user does not have dulwich
+python -c 'import dulwich, dulwich.repo' || exit 80
+
+# This test only works on hg 1.7 and later
+python -c 'from mercurial import util ; assert util.version() > "1.7"' || exit 80
+
+# bail early if the user is already running git-daemon
+echo hi | nc localhost 9418 2>/dev/null && exit 80
+
+echo "[extensions]" >> $HGRCPATH
+echo "hggit=$(echo $(dirname $(dirname $0)))/hggit" >> $HGRCPATH
+echo 'hgext.graphlog =' >> $HGRCPATH
+echo 'hgext.bookmarks =' >> $HGRCPATH
+
+GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
+GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
+GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0000"; export GIT_AUTHOR_DATE
+GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME
+GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL
+GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE
+
+count=10
+commit()
+{
+    GIT_AUTHOR_DATE="2007-01-01 00:00:$count +0000"
+    GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
+    git commit "$@" >/dev/null 2>/dev/null || echo "git commit error"
+    count=`expr $count + 1`
+}
+hgcommit()
+{
+    HGDATE="2007-01-01 00:00:$count +0000"
+    hg commit -d "$HGDATE" "$@" >/dev/null 2>/dev/null || echo "hg commit error"
+    count=`expr $count + 1`
+}
+
+mkdir gitrepo
+cd gitrepo
+git init | python -c "import sys; print sys.stdin.read().replace('$(dirname $(pwd))/', '')"
+
+echo alpha > alpha
+git add alpha
+commit -m "add alpha"
+
+# dulwich does not presently support local git repos, workaround
+cd ..
+git daemon --base-path="$(pwd)"\
+ --listen=localhost\
+ --export-all\
+ --pid-file="$DAEMON_PIDS" \
+ --detach --reuseaddr \
+ --enable=receive-pack
+
+hg clone git://localhost/gitrepo hgrepo | grep -v '^updating'
+
+cd hgrepo
+hg incoming
+
+cd ../gitrepo
+echo beta > beta
+git add beta
+commit -m 'add beta'
+
+cd ../hgrepo
+hg incoming
+
+cd ../gitrepo
+git checkout -b b1 HEAD^
+mkdir d
+echo gamma > d/gamma
+git add d/gamma
+commit -m'add d/gamma'
+git tag t1
+
+echo gamma 2 >> d/gamma
+git add d/gamma
+commit -m'add d/gamma line 2'
+
+cd ../hgrepo
+hg incoming -p
+
+echo % incoming -r
+hg incoming -r master
+hg incoming -r b1
+hg incoming -r t1
+
+echo % nothing incoming after pull
+hg pull
+hg incoming
+
+echo 'done'
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-incoming.out	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,96 @@
+Initialized empty Git repository in gitrepo/.git/
+
+Counting objects: 3, done.
+Total 3 (delta 0), reused 0 (delta 0)
+importing git objects into hg
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+comparing with git://localhost/gitrepo
+no changes found
+comparing with git://localhost/gitrepo
+Counting objects: 3, done.
+Compressing objects:  50% (1/2)   
Compressing objects: 100% (2/2)   
Compressing objects: 100% (2/2), done.
+Total 3 (delta 0), reused 0 (delta 0)
+changeset:   1:9497a4ee62e1
+bookmark:    master
+user:        test <test@example.org>
+date:        Mon Jan 01 00:00:11 2007 +0000
+summary:     add beta
+
+Switched to a new branch 'b1'
+comparing with git://localhost/gitrepo
+Counting objects: 8, done.
+Compressing objects:  25% (1/4)   
Compressing objects:  50% (2/4)   
Compressing objects:  75% (3/4)   
Compressing objects: 100% (4/4)   
Compressing objects: 100% (4/4), done.
+Total 8 (delta 0), reused 0 (delta 0)
+changeset:   1:9497a4ee62e1
+bookmark:    master
+user:        test <test@example.org>
+date:        Mon Jan 01 00:00:11 2007 +0000
+summary:     add beta
+
+diff -r 3442585be8a6 -r 9497a4ee62e1 beta
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/beta	Mon Jan 01 00:00:11 2007 +0000
+@@ -0,0 +1,1 @@
++beta
+
+changeset:   2:9865e289be73
+tag:         t1
+parent:      0:3442585be8a6
+user:        test <test@example.org>
+date:        Mon Jan 01 00:00:12 2007 +0000
+summary:     add d/gamma
+
+diff -r 3442585be8a6 -r 9865e289be73 d/gamma
+--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
++++ b/d/gamma	Mon Jan 01 00:00:12 2007 +0000
+@@ -0,0 +1,1 @@
++gamma
+
+changeset:   3:5202f48c20c9
+bookmark:    b1
+user:        test <test@example.org>
+date:        Mon Jan 01 00:00:13 2007 +0000
+summary:     add d/gamma line 2
+
+diff -r 9865e289be73 -r 5202f48c20c9 d/gamma
+--- a/d/gamma	Mon Jan 01 00:00:12 2007 +0000
++++ b/d/gamma	Mon Jan 01 00:00:13 2007 +0000
+@@ -1,1 +1,2 @@
+ gamma
++gamma 2
+
+% incoming -r
+comparing with git://localhost/gitrepo
+changeset:   1:9497a4ee62e1
+bookmark:    master
+user:        test <test@example.org>
+date:        Mon Jan 01 00:00:11 2007 +0000
+summary:     add beta
+
+comparing with git://localhost/gitrepo
+changeset:   1:9865e289be73
+tag:         t1
+user:        test <test@example.org>
+date:        Mon Jan 01 00:00:12 2007 +0000
+summary:     add d/gamma
+
+changeset:   2:5202f48c20c9
+bookmark:    b1
+user:        test <test@example.org>
+date:        Mon Jan 01 00:00:13 2007 +0000
+summary:     add d/gamma line 2
+
+comparing with git://localhost/gitrepo
+changeset:   1:9865e289be73
+tag:         t1
+user:        test <test@example.org>
+date:        Mon Jan 01 00:00:12 2007 +0000
+summary:     add d/gamma
+
+% nothing incoming after pull
+pulling from git://localhost/gitrepo
+importing git objects into hg
+(run 'hg heads' to see heads, 'hg merge' to merge)
+comparing with git://localhost/gitrepo
+no changes found
+done
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-merge	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,80 @@
+#!/bin/sh
+
+# Fails for some reason, need to investigate
+# "$TESTDIR/hghave" git || exit 80
+
+# bail if the user does not have dulwich
+python -c 'import dulwich, dulwich.repo' || exit 80
+
+# bail early if the user is already running git-daemon
+echo hi | nc localhost 9418 2>/dev/null && exit 80
+
+echo "[extensions]" >> $HGRCPATH
+echo "hggit=$(echo $(dirname $(dirname $0)))/hggit" >> $HGRCPATH
+echo 'hgext.graphlog =' >> $HGRCPATH
+echo 'hgext.bookmarks =' >> $HGRCPATH
+
+GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
+GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
+GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0000"; export GIT_AUTHOR_DATE
+GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME
+GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL
+GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE
+
+count=10
+commit()
+{
+    GIT_AUTHOR_DATE="2007-01-01 00:00:$count +0000"
+    GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
+    git commit "$@" >/dev/null 2>/dev/null || echo "git commit error"
+    count=`expr $count + 1`
+}
+
+mkdir gitrepo
+cd gitrepo
+git init | python -c "import sys; print sys.stdin.read().replace('$(dirname $(pwd))/', '')"
+echo alpha > alpha
+git add alpha
+commit -m 'add alpha'
+
+git checkout -b beta 2>&1 | sed s/\'/\"/g
+echo beta > beta
+git add beta
+commit -m 'add beta'
+
+git checkout master 2>&1 | sed s/\'/\"/g
+echo gamma > gamma
+git add gamma
+commit -m 'add gamma'
+
+# clean merge
+git merge beta
+
+cd ..
+mkdir gitrepo2
+cd gitrepo2
+git init --bare | python -c "import sys; print sys.stdin.read().replace('$(dirname $(pwd))/', '')"
+
+# dulwich does not presently support local git repos, workaround
+cd ..
+git daemon --base-path="$(pwd)"\
+ --listen=localhost\
+ --export-all \
+ --pid-file="$DAEMON_PIDS" \
+ --detach --reuseaddr \
+ --enable=receive-pack
+
+hg clone git://localhost/gitrepo hgrepo | grep -v '^updating'
+cd hgrepo
+
+echo % clear the cache to be sure it is regenerated correctly
+hg gclear
+hg push git://localhost/gitrepo2
+
+cd ..
+cd gitrepo2
+echo % git log in repo pushed from hg
+git log --pretty=medium master | sed 's/\.\.\.//g'
+git log --pretty=medium beta | sed 's/\.\.\.//g'
+
+cd ..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-merge.out	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,53 @@
+Initialized empty Git repository in gitrepo/.git/
+
+Switched to a new branch "beta"
+Switched to branch "master"
+Merge made by recursive.
+ beta |    1 +
+ 1 files changed, 1 insertions(+), 0 deletions(-)
+ create mode 100644 beta
+Initialized empty Git repository in gitrepo2/
+
+importing git objects into hg
+3 files updated, 0 files merged, 0 files removed, 0 files unresolved
+% clear the cache to be sure it is regenerated correctly
+clearing out the git cache data
+pushing to git://localhost/gitrepo2
+exporting hg objects to git
+creating and sending data
+% git log in repo pushed from hg
+commit 5806851511aaf3bfe813ae3a86c5027165fa9b96
+Merge: e5023f9 9497a4e
+Author: test <test@example.org>
+Date:   Mon Jan 1 00:00:12 2007 +0000
+
+    Merge branch 'beta'
+
+commit e5023f9e5cb24fdcec7b6c127cec45d8888e35a9
+Author: test <test@example.org>
+Date:   Mon Jan 1 00:00:12 2007 +0000
+
+    add gamma
+
+commit 9497a4ee62e16ee641860d7677cdb2589ea15554
+Author: test <test@example.org>
+Date:   Mon Jan 1 00:00:11 2007 +0000
+
+    add beta
+
+commit 7eeab2ea75ec1ac0ff3d500b5b6f8a3447dd7c03
+Author: test <test@example.org>
+Date:   Mon Jan 1 00:00:10 2007 +0000
+
+    add alpha
+commit 9497a4ee62e16ee641860d7677cdb2589ea15554
+Author: test <test@example.org>
+Date:   Mon Jan 1 00:00:11 2007 +0000
+
+    add beta
+
+commit 7eeab2ea75ec1ac0ff3d500b5b6f8a3447dd7c03
+Author: test <test@example.org>
+Date:   Mon Jan 1 00:00:10 2007 +0000
+
+    add alpha
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-octopus	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,82 @@
+#!/bin/sh
+
+# Fails for some reason, need to investigate
+# "$TESTDIR/hghave" git || exit 80
+
+# bail if the user does not have dulwich
+python -c 'import dulwich, dulwich.repo' || exit 80
+
+# bail early if the user is already running git-daemon
+echo hi | nc localhost 9418 2>/dev/null && exit 80
+
+echo "[extensions]" >> $HGRCPATH
+echo "hggit=$(echo $(dirname $(dirname $0)))/hggit" >> $HGRCPATH
+echo 'hgext.graphlog =' >> $HGRCPATH
+echo 'hgext.bookmarks =' >> $HGRCPATH
+
+GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
+GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
+GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0000"; export GIT_AUTHOR_DATE
+GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME
+GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL
+GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE
+
+count=10
+commit()
+{
+    GIT_AUTHOR_DATE="2007-01-01 00:00:$count +0000"
+    GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
+    git commit "$@" >/dev/null 2>/dev/null || echo "git commit error"
+    count=`expr $count + 1`
+}
+
+mkdir gitrepo
+cd gitrepo
+git init | python -c "import sys; print sys.stdin.read().replace('$(dirname $(pwd))/', '')"
+
+echo alpha > alpha
+git add alpha
+commit -m 'add alpha'
+
+git checkout -b branch1 2>&1 | sed s/\'/\"/g
+echo beta > beta
+git add beta
+commit -m 'add beta'
+
+git checkout -b branch2 master 2>&1 | sed s/\'/\"/g
+echo gamma > gamma
+git add gamma
+commit -m 'add gamma'
+
+git checkout master 2>&1 | sed s/\'/\"/g
+echo delta > delta
+git add delta
+commit -m 'add delta'
+
+git merge branch1 branch2
+
+cd ..
+mkdir gitrepo2
+cd gitrepo2
+git init --bare | python -c "import sys; print sys.stdin.read().replace('$(dirname $(pwd))/', '')"
+
+# dulwich does not presently support local git repos, workaround
+cd ..
+git daemon --base-path="$(pwd)"\
+ --listen=localhost\
+ --export-all\
+ --pid-file="$DAEMON_PIDS" \
+ --detach --reuseaddr \
+ --enable=receive-pack
+
+hg clone git://localhost/gitrepo hgrepo | grep -v '^updating'
+cd hgrepo
+hg log --graph --style compact | sed 's/\[.*\]//g'
+
+hg gclear
+hg push git://localhost/gitrepo2
+
+cd ../gitrepo2
+git log --pretty=medium | sed s/\\.\\.\\.//g
+
+cd ..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-octopus.out	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,69 @@
+Initialized empty Git repository in gitrepo/.git/
+
+Switched to a new branch "branch1"
+Switched to a new branch "branch2"
+Switched to branch "master"
+Trying simple merge with branch1
+Trying simple merge with branch2
+Merge made by octopus.
+ beta  |    1 +
+ gamma |    1 +
+ 2 files changed, 2 insertions(+), 0 deletions(-)
+ create mode 100644 beta
+ create mode 100644 gamma
+Initialized empty Git repository in gitrepo2/
+
+importing git objects into hg
+4 files updated, 0 files merged, 0 files removed, 0 files unresolved
+@    5:3,4   6523aa9f4775   2007-01-01 00:00 +0000   test
+|\     Merge branches 'branch1' and 'branch2'
+| |
+| o    4:1,2   7f6c791a169f   2007-01-01 00:00 +0000   test
+| |\     Merge branches 'branch1' and 'branch2'
+| | |
+o | |  3:0   1436150b86c2   2007-01-01 00:00 +0000   test
+| | |    add delta
+| | |
++---o  2:0   37c124f2d0a0   2007-01-01 00:00 +0000   test
+| |      add gamma
+| |
+| o  1   7bcd915dc873   2007-01-01 00:00 +0000   test
+|/     add beta
+|
+o  0   3442585be8a6   2007-01-01 00:00 +0000   test
+     add alpha
+
+clearing out the git cache data
+pushing to git://localhost/gitrepo2
+exporting hg objects to git
+creating and sending data
+commit f0c7ec180419a130636d0c333fc34c1462cab4b5
+Merge: d8e22dd 9497a4e e5023f9
+Author: test <test@example.org>
+Date:   Mon Jan 1 00:00:13 2007 +0000
+
+    Merge branches 'branch1' and 'branch2'
+
+commit d8e22ddb015d06460ccbb4508d2184c12c8a7c4c
+Author: test <test@example.org>
+Date:   Mon Jan 1 00:00:13 2007 +0000
+
+    add delta
+
+commit e5023f9e5cb24fdcec7b6c127cec45d8888e35a9
+Author: test <test@example.org>
+Date:   Mon Jan 1 00:00:12 2007 +0000
+
+    add gamma
+
+commit 9497a4ee62e16ee641860d7677cdb2589ea15554
+Author: test <test@example.org>
+Date:   Mon Jan 1 00:00:11 2007 +0000
+
+    add beta
+
+commit 7eeab2ea75ec1ac0ff3d500b5b6f8a3447dd7c03
+Author: test <test@example.org>
+Date:   Mon Jan 1 00:00:10 2007 +0000
+
+    add alpha
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-outgoing	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,96 @@
+#!/bin/sh
+
+# Fails for some reason, need to investigate
+# "$TESTDIR/hghave" git || exit 80
+
+# bail if the user does not have dulwich
+python -c 'import dulwich, dulwich.repo' || exit 80
+
+# bail early if the user is already running git-daemon
+echo hi | nc localhost 9418 2>/dev/null && exit 80
+
+echo "[extensions]" >> $HGRCPATH
+echo "hggit=$(echo $(dirname $(dirname $0)))/hggit" >> $HGRCPATH
+echo 'hgext.graphlog =' >> $HGRCPATH
+echo 'hgext.bookmarks =' >> $HGRCPATH
+
+GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
+GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
+GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0000"; export GIT_AUTHOR_DATE
+GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME
+GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL
+GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE
+
+count=10
+commit()
+{
+    GIT_AUTHOR_DATE="2007-01-01 00:00:$count +0000"
+    GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
+    git commit "$@" >/dev/null 2>/dev/null || echo "git commit error"
+    count=`expr $count + 1`
+}
+hgcommit()
+{
+    HGDATE="2007-01-01 00:00:$count +0000"
+    hg commit -d "$HGDATE" "$@" >/dev/null 2>/dev/null || echo "hg commit error"
+    count=`expr $count + 1`
+}
+
+mkdir gitrepo
+cd gitrepo
+git init | python -c "import sys; print sys.stdin.read().replace('$(dirname $(pwd))/', '')"
+
+echo alpha > alpha
+git add alpha
+commit -m "add alpha"
+
+# dulwich does not presently support local git repos, workaround
+cd ..
+git daemon --base-path="$(pwd)"\
+ --listen=localhost\
+ --export-all\
+ --pid-file="$DAEMON_PIDS" \
+ --detach --reuseaddr \
+ --enable=receive-pack
+
+hg clone git://localhost/gitrepo hgrepo | grep -v '^updating'
+
+cd hgrepo
+echo beta > beta
+hg add beta
+hgcommit -m 'add beta'
+
+
+echo gamma > gamma
+hg add gamma
+hgcommit -m 'add gamma'
+
+hg book -r 1 beta
+
+hg outgoing
+hg outgoing -r beta
+hg outgoing -r master
+
+cd ..
+
+echo % some more work on master from git
+cd gitrepo
+
+git checkout master 2>&1 | sed s/\'/\"/g
+echo delta > delta
+git add delta
+commit -m "add delta"
+
+cd ..
+
+cd hgrepo
+echo % this will fail # maybe we should try to make it work
+hg outgoing
+echo % let\'s pull and try again
+hg pull
+hg outgoing
+hg outgoing -r beta
+hg outgoing -r master
+
+
+cd ..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-outgoing.out	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,82 @@
+Initialized empty Git repository in gitrepo/.git/
+
+importing git objects into hg
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+comparing with git://localhost/gitrepo
+exporting hg objects to git
+changeset:   1:0564f526fb0f
+tag:         beta
+user:        test
+date:        Mon Jan 01 00:00:11 2007 +0000
+summary:     add beta
+
+changeset:   2:72f56395749d
+tag:         master
+tag:         tip
+user:        test
+date:        Mon Jan 01 00:00:12 2007 +0000
+summary:     add gamma
+
+comparing with git://localhost/gitrepo
+changeset:   1:0564f526fb0f
+tag:         beta
+user:        test
+date:        Mon Jan 01 00:00:11 2007 +0000
+summary:     add beta
+
+comparing with git://localhost/gitrepo
+changeset:   1:0564f526fb0f
+tag:         beta
+user:        test
+date:        Mon Jan 01 00:00:11 2007 +0000
+summary:     add beta
+
+changeset:   2:72f56395749d
+tag:         master
+tag:         tip
+user:        test
+date:        Mon Jan 01 00:00:12 2007 +0000
+summary:     add gamma
+
+% some more work on master from git
+Already on "master"
+% this will fail
+comparing with git://localhost/gitrepo
+abort: refs/heads/master changed on the server, please pull and merge before pushing
+% let's pull and try again
+pulling from git://localhost/gitrepo
+importing git objects into hg
+(run 'hg update' to get a working copy)
+comparing with git://localhost/gitrepo
+changeset:   1:0564f526fb0f
+tag:         beta
+user:        test
+date:        Mon Jan 01 00:00:11 2007 +0000
+summary:     add beta
+
+changeset:   2:72f56395749d
+tag:         master
+user:        test
+date:        Mon Jan 01 00:00:12 2007 +0000
+summary:     add gamma
+
+comparing with git://localhost/gitrepo
+changeset:   1:0564f526fb0f
+tag:         beta
+user:        test
+date:        Mon Jan 01 00:00:11 2007 +0000
+summary:     add beta
+
+comparing with git://localhost/gitrepo
+changeset:   1:0564f526fb0f
+tag:         beta
+user:        test
+date:        Mon Jan 01 00:00:11 2007 +0000
+summary:     add beta
+
+changeset:   2:72f56395749d
+tag:         master
+user:        test
+date:        Mon Jan 01 00:00:12 2007 +0000
+summary:     add gamma
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-pull	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,67 @@
+#!/bin/sh
+
+# Fails for some reason, need to investigate
+# "$TESTDIR/hghave" git || exit 80
+
+# bail if the user does not have dulwich
+python -c 'import dulwich, dulwich.repo' || exit 80
+
+# bail early if the user is already running git-daemon
+echo hi | nc localhost 9418 2>/dev/null && exit 80
+
+echo "[extensions]" >> $HGRCPATH
+echo "hggit=$(echo $(dirname $(dirname $0)))/hggit" >> $HGRCPATH
+echo 'hgext.graphlog =' >> $HGRCPATH
+echo 'hgext.bookmarks =' >> $HGRCPATH
+
+GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
+GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
+GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0000"; export GIT_AUTHOR_DATE
+GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME
+GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL
+GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE
+
+count=10
+commit()
+{
+    GIT_AUTHOR_DATE="2007-01-01 00:00:$count +0000"
+    GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
+    git commit "$@" >/dev/null 2>/dev/null || echo "git commit error"
+    count=`expr $count + 1`
+}
+
+mkdir gitrepo
+cd gitrepo
+git init | python -c "import sys; print sys.stdin.read().replace('$(dirname $(pwd))/', '')"
+echo alpha > alpha
+git add alpha
+commit -m 'add alpha'
+
+git tag alpha
+
+git checkout -b beta 2>&1 | sed s/\'/\"/g
+echo beta > beta
+git add beta
+commit -m 'add beta'
+
+
+cd ..
+git daemon --base-path="$(pwd)"\
+ --listen=localhost\
+ --export-all\
+ --pid-file="$DAEMON_PIDS" \
+ --detach --reuseaddr
+
+echo % clone a tag
+hg clone -r alpha git://localhost/gitrepo hgrepo-a | grep -v '^updating'
+cd hgrepo-a
+hg log --graph | egrep -v ': *(beta|master)'
+
+cd ..
+echo % clone a branch
+hg clone -r beta git://localhost/gitrepo hgrepo-b | grep -v '^updating'
+cd hgrepo-b
+hg log --graph | egrep -v ': *(beta|master)'
+
+
+cd ..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-pull-after-strip	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,96 @@
+#!/bin/sh
+
+# Fails for some reason, need to investigate
+# "$TESTDIR/hghave" git || exit 80
+
+# this test is busted on hg < 1.5. I'm not sure how to fix it.
+cat > tmp.py <<EOF
+import sys
+v = sys.stdin.read().strip()[:-1]
+if v[1] == '.' and int(v[2]) > 4:
+  sys.exit(0)
+sys.exit(1)
+EOF
+
+hg version | grep version | sed 's/.*(version //' | python tmp.py || exit 80
+
+# bail if the user does not have dulwich
+python -c 'import dulwich, dulwich.repo' || exit 80
+
+# bail early if the user is already running git-daemon
+echo hi | nc localhost 9418 2>/dev/null && exit 80
+
+
+cat >> $HGRCPATH <<EOF
+[extensions]
+graphlog=
+bookmarks=
+mq=
+EOF
+echo "hggit=$(echo $(dirname $(dirname $0)))/hggit" >> $HGRCPATH
+
+GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
+GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
+GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0000"; export GIT_AUTHOR_DATE
+GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME
+GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL
+GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE
+
+count=10
+commit()
+{
+    GIT_AUTHOR_DATE="2007-01-01 00:00:$count +0000"
+    GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
+    git commit "$@" >/dev/null 2>/dev/null || echo "git commit error"
+    count=`expr $count + 1`
+}
+
+mkdir gitrepo
+cd gitrepo
+git init | python -c "import sys; print sys.stdin.read().replace('$(dirname $(pwd))/', '')"
+echo alpha > alpha
+git add alpha
+commit -m 'add alpha'
+
+git tag alpha
+
+git checkout -b beta 2>&1 | sed s/\'/\"/g
+echo beta > beta
+git add beta
+commit -m 'add beta'
+
+
+cd ..
+git daemon --base-path="$(pwd)"\
+ --listen=localhost\
+ --export-all\
+ --pid-file="$DAEMON_PIDS" \
+ --detach --reuseaddr
+
+echo % clone a tag
+hg clone -r alpha git://localhost/gitrepo hgrepo-a | grep -v '^updating'
+cd hgrepo-a
+hg log --graph | egrep -v ': *(beta|master)'
+
+cd ..
+echo % clone a branch
+hg clone -r beta git://localhost/gitrepo hgrepo-b | grep -v '^updating'
+cd hgrepo-b
+hg log --graph | egrep -v ': *(beta|master)'
+cd ..
+
+cd gitrepo
+echo beta line 2 >> beta
+git add beta
+commit -m 'add to beta'
+
+cd ..
+cd hgrepo-b
+hg strip tip 2>&1 | grep -v saving | grep -v backup
+hg pull -r beta
+hg git-cleanup
+echo % pull works after \'hg git-cleanup\'
+hg pull -r beta
+hg log --graph | egrep -v ': *(beta|master)'
+
+cd ..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-pull-after-strip.out	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,59 @@
+Initialized empty Git repository in gitrepo/.git/
+
+Switched to a new branch "beta"
+% clone a tag
+importing git objects into hg
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+@  changeset:   0:3442585be8a6
+   tag:         alpha
+   tag:         default/master
+   tag:         tip
+   user:        test <test@example.org>
+   date:        Mon Jan 01 00:00:10 2007 +0000
+   summary:     add alpha
+
+% clone a branch
+importing git objects into hg
+2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+@  changeset:   1:7bcd915dc873
+|  tag:         default/beta
+|  tag:         tip
+|  user:        test <test@example.org>
+|  date:        Mon Jan 01 00:00:11 2007 +0000
+|  summary:     add beta
+|
+o  changeset:   0:3442585be8a6
+   tag:         alpha
+   tag:         default/master
+   user:        test <test@example.org>
+   date:        Mon Jan 01 00:00:10 2007 +0000
+   summary:     add alpha
+
+0 files updated, 0 files merged, 1 files removed, 0 files unresolved
+pulling from git://localhost/gitrepo
+importing git objects into hg
+abort: you appear to have run strip - please run hg git-cleanup
+git commit map cleaned
+% pull works after 'hg git-cleanup'
+pulling from git://localhost/gitrepo
+importing git objects into hg
+(run 'hg update' to get a working copy)
+o  changeset:   2:611948b1ec6a
+|  tag:         default/beta
+|  tag:         tip
+|  user:        test <test@example.org>
+|  date:        Mon Jan 01 00:00:12 2007 +0000
+|  summary:     add to beta
+|
+o  changeset:   1:7bcd915dc873
+|  user:        test <test@example.org>
+|  date:        Mon Jan 01 00:00:11 2007 +0000
+|  summary:     add beta
+|
+@  changeset:   0:3442585be8a6
+   tag:         alpha
+   tag:         default/master
+   user:        test <test@example.org>
+   date:        Mon Jan 01 00:00:10 2007 +0000
+   summary:     add alpha
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-pull.out	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,31 @@
+Initialized empty Git repository in gitrepo/.git/
+
+Switched to a new branch "beta"
+% clone a tag
+importing git objects into hg
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+@  changeset:   0:3442585be8a6
+   tag:         alpha
+   tag:         default/master
+   tag:         tip
+   user:        test <test@example.org>
+   date:        Mon Jan 01 00:00:10 2007 +0000
+   summary:     add alpha
+
+% clone a branch
+importing git objects into hg
+2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+@  changeset:   1:7bcd915dc873
+|  tag:         default/beta
+|  tag:         tip
+|  user:        test <test@example.org>
+|  date:        Mon Jan 01 00:00:11 2007 +0000
+|  summary:     add beta
+|
+o  changeset:   0:3442585be8a6
+   tag:         alpha
+   tag:         default/master
+   user:        test <test@example.org>
+   date:        Mon Jan 01 00:00:10 2007 +0000
+   summary:     add alpha
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-push	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,109 @@
+#!/bin/sh
+
+# Fails for some reason, need to investigate
+# "$TESTDIR/hghave" git || exit 80
+
+# bail if the user does not have dulwich
+python -c 'import dulwich, dulwich.repo' || exit 80
+
+# bail early if the user is already running git-daemon
+echo hi | nc localhost 9418 2>/dev/null && exit 80
+
+echo "[extensions]" >> $HGRCPATH
+echo "hggit=$(echo $(dirname $(dirname $0)))/hggit" >> $HGRCPATH
+echo 'hgext.graphlog =' >> $HGRCPATH
+echo 'hgext.bookmarks =' >> $HGRCPATH
+
+
+GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
+GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
+GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0000"; export GIT_AUTHOR_DATE
+GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME
+GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL
+GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE
+
+count=10
+commit()
+{
+    GIT_AUTHOR_DATE="2007-01-01 00:00:$count +0000"
+    GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
+    git commit "$@" >/dev/null 2>/dev/null || echo "git commit error"
+    count=`expr $count + 1`
+}
+hgcommit()
+{
+    HGDATE="2007-01-01 00:00:$count +0000"
+    hg commit -d "$HGDATE" "$@" >/dev/null 2>/dev/null || echo "hg commit error"
+    count=`expr $count + 1`
+}
+
+mkdir gitrepo
+cd gitrepo
+git init | python -c "import sys; print sys.stdin.read().replace('$(dirname $(pwd))/', '')"
+
+echo alpha > alpha
+git add alpha
+commit -m "add alpha"
+git checkout -b not-master 2>&1 | sed s/\'/\"/g
+
+# dulwich does not presently support local git repos, workaround
+cd ..
+git daemon --base-path="$(pwd)"\
+ --listen=localhost\
+ --export-all\
+ --pid-file="$DAEMON_PIDS" \
+ --detach --reuseaddr \
+ --enable=receive-pack
+
+hg clone git://localhost/gitrepo hgrepo | grep -v '^updating'
+
+cd hgrepo
+echo beta > beta
+hg add beta
+hgcommit -m 'add beta'
+
+
+echo gamma > gamma
+hg add gamma
+hgcommit -m 'add gamma'
+
+hg book -r 1 beta
+hg push -r beta
+
+cd ..
+
+echo % should have two different branches
+cd gitrepo
+git branch -v
+
+echo % some more work on master from git
+git checkout master 2>&1 | sed s/\'/\"/g
+echo delta > delta
+git add delta
+commit -m "add delta"
+git checkout not-master 2>&1 | sed s/\'/\"/g
+
+cd ..
+
+cd hgrepo
+echo % this should fail
+hg push -r master
+
+echo % ... even with -f
+hg push -fr master
+
+hg pull
+# TODO shouldn't need to do this since we're (in theory) pushing master explicitly,
+# which should not implicitly also push the not-master ref.
+hg book not-master -r default/not-master --force
+echo % master and default/master should be diferent
+hg log -r master | grep -v ': *master'
+hg log -r default/master
+
+echo % this should also fail
+hg push -r master
+
+echo % ... but succeed with -f
+hg push -fr master
+
+cd ..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-push-r	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,63 @@
+#!/bin/sh
+
+# bail if the user does not have dulwich
+python -c 'import dulwich, dulwich.repo' || exit 80
+
+echo "[extensions]" >> $HGRCPATH
+echo "hggit=$(echo $(dirname $(dirname $0)))/hggit" >> $HGRCPATH
+echo 'hgext.graphlog =' >> $HGRCPATH
+echo 'hgext.bookmarks =' >> $HGRCPATH
+
+hg init test
+cd test
+cat >>afile <<EOF
+0
+EOF
+hg add afile
+hg commit -m "0.0"
+cat >>afile <<EOF
+1
+EOF
+hg commit -m "0.1"
+cat >>afile <<EOF
+2
+EOF
+hg commit -m "0.2"
+cat >>afile <<EOF
+3
+EOF
+hg commit -m "0.3"
+hg update -C 0
+cat >>afile <<EOF
+1
+EOF
+hg commit -m "1.1"
+cat >>afile <<EOF
+2
+EOF
+hg commit -m "1.2"
+cat >fred <<EOF
+a line
+EOF
+cat >>afile <<EOF
+3
+EOF
+hg add fred
+hg commit -m "1.3"
+hg mv afile adifferentfile
+hg commit -m "1.3m"
+hg update -C 3
+hg mv afile anotherfile
+hg commit -m "0.3m"
+cd ..
+for i in 0 1 2 3 4 5 6 7 8; do
+   mkdir test-"$i"
+   hg --cwd test-"$i" init
+   hg -R test push -r "$i" test-"$i"
+   cd test-"$i"
+   hg verify
+   cd ..
+done
+cd test-8
+hg pull ../test-7
+hg verify
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-push-r.out	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,114 @@
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+created new head
+1 files updated, 0 files merged, 2 files removed, 0 files unresolved
+pushing to test-0
+searching for changes
+adding changesets
+adding manifests
+adding file changes
+added 1 changesets with 1 changes to 1 files
+checking changesets
+checking manifests
+crosschecking files in changesets and manifests
+checking files
+1 files, 1 changesets, 1 total revisions
+pushing to test-1
+searching for changes
+adding changesets
+adding manifests
+adding file changes
+added 2 changesets with 2 changes to 1 files
+checking changesets
+checking manifests
+crosschecking files in changesets and manifests
+checking files
+1 files, 2 changesets, 2 total revisions
+pushing to test-2
+searching for changes
+adding changesets
+adding manifests
+adding file changes
+added 3 changesets with 3 changes to 1 files
+checking changesets
+checking manifests
+crosschecking files in changesets and manifests
+checking files
+1 files, 3 changesets, 3 total revisions
+pushing to test-3
+searching for changes
+adding changesets
+adding manifests
+adding file changes
+added 4 changesets with 4 changes to 1 files
+checking changesets
+checking manifests
+crosschecking files in changesets and manifests
+checking files
+1 files, 4 changesets, 4 total revisions
+pushing to test-4
+searching for changes
+adding changesets
+adding manifests
+adding file changes
+added 2 changesets with 2 changes to 1 files
+checking changesets
+checking manifests
+crosschecking files in changesets and manifests
+checking files
+1 files, 2 changesets, 2 total revisions
+pushing to test-5
+searching for changes
+adding changesets
+adding manifests
+adding file changes
+added 3 changesets with 3 changes to 1 files
+checking changesets
+checking manifests
+crosschecking files in changesets and manifests
+checking files
+1 files, 3 changesets, 3 total revisions
+pushing to test-6
+searching for changes
+adding changesets
+adding manifests
+adding file changes
+added 4 changesets with 5 changes to 2 files
+checking changesets
+checking manifests
+crosschecking files in changesets and manifests
+checking files
+2 files, 4 changesets, 5 total revisions
+pushing to test-7
+searching for changes
+adding changesets
+adding manifests
+adding file changes
+added 5 changesets with 6 changes to 3 files
+checking changesets
+checking manifests
+crosschecking files in changesets and manifests
+checking files
+3 files, 5 changesets, 6 total revisions
+pushing to test-8
+searching for changes
+adding changesets
+adding manifests
+adding file changes
+added 5 changesets with 5 changes to 2 files
+checking changesets
+checking manifests
+crosschecking files in changesets and manifests
+checking files
+2 files, 5 changesets, 5 total revisions
+pulling from ../test-7
+searching for changes
+adding changesets
+adding manifests
+adding file changes
+added 4 changesets with 2 changes to 3 files (+1 heads)
+(run 'hg heads' to see heads, 'hg merge' to merge)
+checking changesets
+checking manifests
+crosschecking files in changesets and manifests
+checking files
+4 files, 9 changesets, 7 total revisions
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-push.out	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,53 @@
+Initialized empty Git repository in gitrepo/.git/
+
+Switched to a new branch "not-master"
+importing git objects into hg
+1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+pushing to git://localhost/gitrepo
+exporting hg objects to git
+creating and sending data
+    default::refs/heads/beta => GIT:cffa0e8d
+    default::refs/heads/not-master => GIT:7eeab2ea
+    default::refs/heads/master => GIT:7eeab2ea
+% should have two different branches
+  beta       cffa0e8 add beta
+  master     7eeab2e add alpha
+* not-master 7eeab2e add alpha
+% some more work on master from git
+Switched to branch "master"
+Switched to branch "not-master"
+% this should fail
+pushing to git://localhost/gitrepo
+creating and sending data
+abort: refs/heads/master changed on the server, please pull and merge before pushing
+% ... even with -f
+pushing to git://localhost/gitrepo
+creating and sending data
+abort: refs/heads/master changed on the server, please pull and merge before pushing
+pulling from git://localhost/gitrepo
+importing git objects into hg
+(run 'hg update' to get a working copy)
+% master and default/master should be diferent
+changeset:   2:72f56395749d
+user:        test
+date:        Mon Jan 01 00:00:12 2007 +0000
+summary:     add gamma
+
+changeset:   3:1436150b86c2
+tag:         default/master
+tag:         tip
+parent:      0:3442585be8a6
+user:        test <test@example.org>
+date:        Mon Jan 01 00:00:13 2007 +0000
+summary:     add delta
+
+% this should also fail
+pushing to git://localhost/gitrepo
+creating and sending data
+abort: pushing refs/heads/master overwrites 72f56395749d
+% ... but succeed with -f
+pushing to git://localhost/gitrepo
+creating and sending data
+    default::refs/heads/beta => GIT:cffa0e8d
+    default::refs/heads/not-master => GIT:7eeab2ea
+    default::refs/heads/master => GIT:cc119202
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-sane-without-bookmarks	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,57 @@
+#!/bin/sh
+
+# Fails for some reason, need to investigate
+# "$TESTDIR/hghave" git || exit 80
+
+# bail if the user does not have dulwich
+python -c 'import dulwich, dulwich.repo' || exit 80
+
+# bail if hgext.bookmarks does not exist, which means hg >= 1.8
+python -c 'import hgext.bookmarks' || exit 80
+
+# bail early if the user is already running git-daemon
+echo hi | nc localhost 9418 2>/dev/null && exit 80
+
+echo "[extensions]" >> $HGRCPATH
+echo "hggit=$(echo $(dirname $(dirname $0)))/hggit" >> $HGRCPATH
+echo 'hgext.graphlog =' >> $HGRCPATH
+
+GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
+GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
+GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0000"; export GIT_AUTHOR_DATE
+GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME
+GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL
+GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE
+
+count=10
+commit()
+{
+    GIT_AUTHOR_DATE="2007-01-01 00:00:$count +0000"
+    GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
+    git commit "$@" >/dev/null 2>/dev/null || echo "git commit error"
+    count=`expr $count + 1`
+}
+
+mkdir gitrepo
+cd gitrepo
+git init | python -c "import sys; print sys.stdin.read().replace('$(dirname $(pwd))/', '')"
+echo alpha > alpha
+git add alpha
+commit -m 'add alpha'
+echo beta > beta
+git add beta
+commit -m 'add beta'
+
+# dulwich does not presently support local git repos, workaround
+cd ..
+git daemon --base-path="$(pwd)"\
+ --listen=localhost\
+ --export-all\
+  --pid-file="$DAEMON_PIDS" \
+ --detach --reuseaddr
+
+hg clone git://localhost/gitrepo hgrepo | grep -v '^updating'
+cd hgrepo
+hg log --graph | grep -v ': *master'
+
+cd ..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-sane-without-bookmarks.out	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,17 @@
+Initialized empty Git repository in gitrepo/.git/
+
+creating bookmarks failed, do you have bookmarks enabled?
+importing git objects into hg
+2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+@  changeset:   1:7bcd915dc873
+|  tag:         default/master
+|  tag:         tip
+|  user:        test <test@example.org>
+|  date:        Mon Jan 01 00:00:11 2007 +0000
+|  summary:     add beta
+|
+o  changeset:   0:3442585be8a6
+   user:        test <test@example.org>
+   date:        Mon Jan 01 00:00:10 2007 +0000
+   summary:     add alpha
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-tree-decomposition	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,76 @@
+#!/bin/sh
+
+# Fails for some reason, need to investigate
+# "$TESTDIR/hghave" git || exit 80
+
+# bail if the user does not have dulwich
+python -c 'import dulwich, dulwich.repo' || exit 80
+
+# bail early if the user is already running git-daemon
+echo hi | nc localhost 9418 2> /dev/null && exit 80
+
+echo "[extensions]" >> $HGRCPATH
+echo "hggit=$(echo $(dirname $(dirname $0)))/hggit" >> $HGRCPATH
+echo 'hgext.bookmarks =' >> $HGRCPATH
+
+GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
+GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
+GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0000"; export GIT_AUTHOR_DATE
+GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME
+GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL
+GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE
+
+count=10
+commit()
+{
+    GIT_AUTHOR_DATE="2007-01-01 00:00:$count +0000"
+    GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
+    git commit "$@" >/dev/null 2>/dev/null || echo "git commit error"
+    count=`expr $count + 1`
+}
+
+mkdir gitrepo
+cd gitrepo
+git init | python -c "import sys; print sys.stdin.read().replace('$(dirname $(pwd))/', '')"
+
+mkdir d1
+echo a > d1/f1
+echo b > d1/f2
+git add d1/f1 d1/f2
+commit -m initial
+
+mkdir d2
+git mv d1/f2 d2/f2
+commit -m 'rename'
+
+rm -r d1
+echo c > d1
+git add d1
+commit -m 'replace a dir with a file'
+
+
+cd ..
+mkdir gitrepo2
+cd gitrepo2
+git init --bare | python -c "import sys; print sys.stdin.read().replace('$(dirname $(pwd))/', '')"
+
+# dulwich does not presently support local git repos, workaround
+cd ..
+git daemon --base-path="$(pwd)"\
+ --listen=localhost\
+ --export-all\
+ --pid-file="$DAEMON_PIDS" \
+ --detach --reuseaddr \
+ --enable=receive-pack
+
+hg clone git://localhost/gitrepo hgrepo | grep -v '^updating'
+cd hgrepo
+hg log --template 'adds: {file_adds}\ndels: {file_dels}\n'
+
+hg gclear
+hg push git://localhost/gitrepo2
+
+cd ../gitrepo2
+git log --pretty=medium
+
+cd ..
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-tree-decomposition.out	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,33 @@
+Initialized empty Git repository in gitrepo/.git/
+
+Initialized empty Git repository in gitrepo2/
+
+importing git objects into hg
+2 files updated, 0 files merged, 0 files removed, 0 files unresolved
+adds: d1
+dels: d1/f1
+adds: d2/f2
+dels: d1/f2
+adds: d1/f1 d1/f2
+dels: 
+clearing out the git cache data
+pushing to git://localhost/gitrepo2
+exporting hg objects to git
+creating and sending data
+commit 6e0dbd8cd92ed4823c69cb48d8a2b81f904e6e69
+Author: test <test@example.org>
+Date:   Mon Jan 1 00:00:12 2007 +0000
+
+    replace a dir with a file
+
+commit a1874d5cd0b1549ed729e36f0da4a93ed36259ee
+Author: test <test@example.org>
+Date:   Mon Jan 1 00:00:11 2007 +0000
+
+    rename
+
+commit 102c17a5deda49db3f10ec5573f9378867098b7c
+Author: test <test@example.org>
+Date:   Mon Jan 1 00:00:10 2007 +0000
+
+    initial
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-url-parsing.py	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,80 @@
+import os, sys, tempfile, unittest, shutil
+from mercurial import ui, hg, commands
+
+sys.path.append(os.path.join(os.path.dirname(__file__), os.path.pardir))
+
+from hggit.git_handler import GitHandler
+
+
+class TestUrlParsing(object):
+    def setUp(self):
+        # create a test repo location.
+        self.tmpdir = tempfile.mkdtemp('hg-git_url-test')
+        commands.init(ui.ui(), self.tmpdir)
+        repo = hg.repository(ui.ui(), self.tmpdir)
+        self.handler = GitHandler(repo, ui.ui())
+
+    def tearDown(self):
+        # remove the temp repo
+        shutil.rmtree(self.tmpdir)
+
+    def assertEquals(self, l, r):
+        print '%% expect %r' % (r, )
+        print l
+        assert l == r
+
+    def test_ssh_github_style_slash(self):
+        url = "git+ssh://git@github.com/webjam/webjam.git"
+        client, path = self.handler.get_transport_and_path(url)
+        self.assertEquals(path, '/webjam/webjam.git')
+        self.assertEquals(client.host, 'git@github.com')
+
+    def test_ssh_github_style_colon(self):
+        url = "git+ssh://git@github.com:webjam/webjam.git"
+        client, path = self.handler.get_transport_and_path(url)
+        self.assertEquals(path, 'webjam/webjam.git')
+        self.assertEquals(client.host, 'git@github.com')
+
+    def test_ssh_heroku_style(self):
+        url = "git+ssh://git@heroku.com:webjam.git"
+        client, path = self.handler.get_transport_and_path(url)
+        self.assertEquals(path, 'webjam.git')
+        self.assertEquals(client.host, 'git@heroku.com')
+
+    def test_gitdaemon_style(self):
+        url = "git://github.com/webjam/webjam.git"
+        client, path = self.handler.get_transport_and_path(url)
+        self.assertEquals(path, '/webjam/webjam.git')
+        try:
+            self.assertEquals(client._host, 'github.com')
+        except AttributeError:
+            self.assertEquals(client.host, 'github.com')
+
+    def test_ssh_github_style_slash_with_port(self):
+        url = "git+ssh://git@github.com:10022/webjam/webjam.git"
+        client, path = self.handler.get_transport_and_path(url)
+        self.assertEquals(path, '/webjam/webjam.git')
+        self.assertEquals(client.host, 'git@github.com')
+        self.assertEquals(client.port, '10022')
+
+    def test_gitdaemon_style_with_port(self):
+        url = "git://github.com:19418/webjam/webjam.git"
+        client, path = self.handler.get_transport_and_path(url)
+        self.assertEquals(path, '/webjam/webjam.git')
+        try:
+            self.assertEquals(client._host, 'github.com')
+        except AttributeError:
+            self.assertEquals(client.host, 'github.com')
+        self.assertEquals(client._port, '19418')
+
+if __name__ == '__main__':
+    tc = TestUrlParsing()
+    for test in ['test_ssh_github_style_slash',
+                 'test_ssh_github_style_colon',
+                 'test_ssh_heroku_style',
+                 'test_gitdaemon_style',
+                 'test_ssh_github_style_slash_with_port',
+                 'test_gitdaemon_style_with_port']:
+        tc.setUp()
+        getattr(tc, test)()
+        tc.tearDown()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/.hgext/hg-git/tests/test-url-parsing.py.out	Sun Aug 07 15:57:53 2011 +0200
@@ -0,0 +1,28 @@
+% expect '/webjam/webjam.git'
+/webjam/webjam.git
+% expect 'git@github.com'
+git@github.com
+% expect 'webjam/webjam.git'
+webjam/webjam.git
+% expect 'git@github.com'
+git@github.com
+% expect 'webjam.git'
+webjam.git
+% expect 'git@heroku.com'
+git@heroku.com
+% expect '/webjam/webjam.git'
+/webjam/webjam.git
+% expect 'github.com'
+github.com
+% expect '/webjam/webjam.git'
+/webjam/webjam.git
+% expect 'git@github.com'
+git@github.com
+% expect '10022'
+10022
+% expect '/webjam/webjam.git'
+/webjam/webjam.git
+% expect 'github.com'
+github.com
+% expect '19418'
+19418
--- a/.hgext/hggit/COPYING	Fri Aug 05 21:41:21 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,340 +0,0 @@
-		    GNU GENERAL PUBLIC LICENSE
-		       Version 2, June 1991
-
- Copyright (C) 1989, 1991 Free Software Foundation, Inc.
-     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-			    Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-License is intended to guarantee your freedom to share and change free
-software--to make sure the software is free for all its users.  This
-General Public License applies to most of the Free Software
-Foundation's software and to any other program whose authors commit to
-using it.  (Some other Free Software Foundation software is covered by
-the GNU Library General Public License instead.)  You can apply it to
-your programs, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if you
-distribute copies of the software, or if you modify it.
-
-  For example, if you distribute copies of such a program, whether
-gratis or for a fee, you must give the recipients all the rights that
-you have.  You must make sure that they, too, receive or can get the
-source code.  And you must show them these terms so they know their
-rights.
-
-  We protect your rights with two steps: (1) copyright the software, and
-(2) offer you this license which gives you legal permission to copy,
-distribute and/or modify the software.
-
-  Also, for each author's protection and ours, we want to make certain
-that everyone understands that there is no warranty for this free
-software.  If the software is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original, so
-that any problems introduced by others will not reflect on the original
-authors' reputations.
-
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that redistributors of a free
-program will individually obtain patent licenses, in effect making the
-program proprietary.  To prevent this, we have made it clear that any
-patent must be licensed for everyone's free use or not licensed at all.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.
-
-		    GNU GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License applies to any program or other work which contains
-a notice placed by the copyright holder saying it may be distributed
-under the terms of this General Public License.  The "Program", below,
-refers to any such program or work, and a "work based on the Program"
-means either the Program or any derivative work under copyright law:
-that is to say, a work containing the Program or a portion of it,
-either verbatim or with modifications and/or translated into another
-language.  (Hereinafter, translation is included without limitation in
-the term "modification".)  Each licensee is addressed as "you".
-
-Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running the Program is not restricted, and the output from the Program
-is covered only if its contents constitute a work based on the
-Program (independent of having been made by running the Program).
-Whether that is true depends on what the Program does.
-
-  1. You may copy and distribute verbatim copies of the Program's
-source code as you receive it, in any medium, provided that you
-conspicuously and appropriately publish on each copy an appropriate
-copyright notice and disclaimer of warranty; keep intact all the
-notices that refer to this License and to the absence of any warranty;
-and give any other recipients of the Program a copy of this License
-along with the Program.
-
-You may charge a fee for the physical act of transferring a copy, and
-you may at your option offer warranty protection in exchange for a fee.
-
-  2. You may modify your copy or copies of the Program or any portion
-of it, thus forming a work based on the Program, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) You must cause the modified files to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    b) You must cause any work that you distribute or publish, that in
-    whole or in part contains or is derived from the Program or any
-    part thereof, to be licensed as a whole at no charge to all third
-    parties under the terms of this License.
-
-    c) If the modified program normally reads commands interactively
-    when run, you must cause it, when started running for such
-    interactive use in the most ordinary way, to print or display an
-    announcement including an appropriate copyright notice and a
-    notice that there is no warranty (or else, saying that you provide
-    a warranty) and that users may redistribute the program under
-    these conditions, and telling the user how to view a copy of this
-    License.  (Exception: if the Program itself is interactive but
-    does not normally print such an announcement, your work based on
-    the Program is not required to print an announcement.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Program,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Program, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Program.
-
-In addition, mere aggregation of another work not based on the Program
-with the Program (or with a work based on the Program) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may copy and distribute the Program (or a work based on it,
-under Section 2) in object code or executable form under the terms of
-Sections 1 and 2 above provided that you also do one of the following:
-
-    a) Accompany it with the complete corresponding machine-readable
-    source code, which must be distributed under the terms of Sections
-    1 and 2 above on a medium customarily used for software interchange; or,
-
-    b) Accompany it with a written offer, valid for at least three
-    years, to give any third party, for a charge no more than your
-    cost of physically performing source distribution, a complete
-    machine-readable copy of the corresponding source code, to be
-    distributed under the terms of Sections 1 and 2 above on a medium
-    customarily used for software interchange; or,
-
-    c) Accompany it with the information you received as to the offer
-    to distribute corresponding source code.  (This alternative is
-    allowed only for noncommercial distribution and only if you
-    received the program in object code or executable form with such
-    an offer, in accord with Subsection b above.)
-
-The source code for a work means the preferred form of the work for
-making modifications to it.  For an executable work, complete source
-code means all the source code for all modules it contains, plus any
-associated interface definition files, plus the scripts used to
-control compilation and installation of the executable.  However, as a
-special exception, the source code distributed need not include
-anything that is normally distributed (in either source or binary
-form) with the major components (compiler, kernel, and so on) of the
-operating system on which the executable runs, unless that component
-itself accompanies the executable.
-
-If distribution of executable or object code is made by offering
-access to copy from a designated place, then offering equivalent
-access to copy the source code from the same place counts as
-distribution of the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  4. You may not copy, modify, sublicense, or distribute the Program
-except as expressly provided under this License.  Any attempt
-otherwise to copy, modify, sublicense or distribute the Program is
-void, and will automatically terminate your rights under this License.
-However, parties who have received copies, or rights, from you under
-this License will not have their licenses terminated so long as such
-parties remain in full compliance.
-
-  5. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Program or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Program (or any work based on the
-Program), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Program or works based on it.
-
-  6. Each time you redistribute the Program (or any work based on the
-Program), the recipient automatically receives a license from the
-original licensor to copy, distribute or modify the Program subject to
-these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
-  7. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Program at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Program by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Program.
-
-If any portion of this section is held invalid or unenforceable under
-any particular circumstance, the balance of the section is intended to
-apply and the section as a whole is intended to apply in other
-circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system, which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  8. If the distribution and/or use of the Program is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Program under this License
-may add an explicit geographical distribution limitation excluding
-those countries, so that distribution is permitted only in or among
-countries not thus excluded.  In such case, this License incorporates
-the limitation as if written in the body of this License.
-
-  9. The Free Software Foundation may publish revised and/or new versions
-of the General Public License from time to time.  Such new versions will
-be similar in spirit to the present version, but may differ in detail to
-address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Program
-specifies a version number of this License which applies to it and "any
-later version", you have the option of following the terms and conditions
-either of that version or of any later version published by the Free
-Software Foundation.  If the Program does not specify a version number of
-this License, you may choose any version ever published by the Free Software
-Foundation.
-
-  10. If you wish to incorporate parts of the Program into other free
-programs whose distribution conditions are different, write to the author
-to ask for permission.  For software which is copyrighted by the Free
-Software Foundation, write to the Free Software Foundation; we sometimes
-make exceptions for this.  Our decision will be guided by the two goals
-of preserving the free status of all derivatives of our free software and
-of promoting the sharing and reuse of software generally.
-
-			    NO WARRANTY
-
-  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
-FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
-OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
-PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
-OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
-MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
-TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
-PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
-REPAIR OR CORRECTION.
-
-  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
-WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
-REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
-INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
-OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
-TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
-YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
-PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
-POSSIBILITY OF SUCH DAMAGES.
-
-		     END OF TERMS AND CONDITIONS
-
-	    How to Apply These Terms to Your New Programs
-
-  If you develop a new program, and you want it to be of the greatest
-possible use to the public, the best way to achieve this is to make it
-free software which everyone can redistribute and change under these terms.
-
-  To do so, attach the following notices to the program.  It is safest
-to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least
-the "copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the program's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This program is free software; you can redistribute it and/or modify
-    it under the terms of the GNU General Public License as published by
-    the Free Software Foundation; either version 2 of the License, or
-    (at your option) any later version.
-
-    This program is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-    GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License
-    along with this program; if not, write to the Free Software
-    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-
-Also add information on how to contact you by electronic and paper mail.
-
-If the program is interactive, make it output a short notice like this
-when it starts in an interactive mode:
-
-    Gnomovision version 69, Copyright (C) year  name of author
-    Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
-    This is free software, and you are welcome to redistribute it
-    under certain conditions; type `show c' for details.
-
-The hypothetical commands `show w' and `show c' should show the appropriate
-parts of the General Public License.  Of course, the commands you use may
-be called something other than `show w' and `show c'; they could even be
-mouse-clicks or menu items--whatever suits your program.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the program, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the program
-  `Gnomovision' (which makes passes at compilers) written by James Hacker.
-
-  <signature of Ty Coon>, 1 April 1989
-  Ty Coon, President of Vice
-
-This General Public License does not permit incorporating your program into
-proprietary programs.  If your program is a subroutine library, you may
-consider it more useful to permit linking proprietary applications with the
-library.  If this is what you want to do, use the GNU Library General
-Public License instead of this License.
--- a/.hgext/hggit/DESIGN.txt	Fri Aug 05 21:41:21 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,69 +0,0 @@
-Hg-Git Plugin Design Notes
-==========================
-
-This plugin is designed to allow you to push to a Git server over the Git protocol and to pull from a Git based project.  All data is stored in Hg native format with a mapping table.  People collaborating in Git should not  even be able to tell that you're using Hg to collaborate on their project (except for the '--HG--' section added to commit message). 
-
-Nothing should need to be kept in the Git format - you should be able to run 'hg gclear' at any time to wipe out the Git directory and everything can be rebuilt losslessly from the existing Hg data - it is a cache only.
-
-We are using the Dulwich library, which I've modified quite a bit - I'll have to get these changes back upstream at some point.
-
-I've been adding 'TODO' comments all over the place where I only partially implemented something so I could get the entire first draft of functionality completed.  The TODO areas should be mostly edge cases (executable bits, file rename info, tags, submodules, etc).
-
-Lossless Two Way
-================
-
-We need to store data that Git records that Merc does not in a git/extra_data file.  This would be parents over two and committer information (author will be mapped to Hg committer).  This way two Hg developers can collaborate without the Git transport messing up the local commits.
-
-Each Git commit should be reproducible as a Merc ID and vice versa on any system without losing data (ie changing the SHA).
-
-Branch Translation Policy
-=========================
-
-Branches in Hg and Git are pretty different.  This is meant to provide a clear policy on how one is converted to the other.
-
-* Without Bookmarks: *
-
-If you don't have bookmarks enabled, Git simply maps your 'tip' to the 'master' branch of the repository you're pushing to, since that is the most commonly used default branch name.  Actually, pulling will map whatever the server points to as HEAD, but when pushing it will assume 'master' is your tip.
-
-	$ hg gpush origin        # will push tip to remote 'master'
-	$ hg gpush origin master # same as above
-	$ hg gpush origin --all  # same as above
-
-If the remote server has divergent branches (branches with commits not reachable from HEAD) it will basically ignore them, not convert them into Hg changesets.  It will tell you this (and why) when fetched.
-
-Conversely, on pushing, Hg named branches are ignored if they are not reachable from traversing the parents of tip. (SC: is this best?)
-
-* With Bookmarks: *
-
-If you have bookmarks enabled, it will treat your bookmarks like Git branches and will only push up references if you specify them.
-
-	hg gpush origin        # will error, you have to specify a branch
-	hg gpush origin master # pushes the master branch
-	hg gpush origin --all  # pushes all local branches
-
-If a fetch gets branches, it _will_ import them and will create bookmarks that point to them, even if they have no common ancestors with the mainline (HEAD).
-
-* Other points *
-
-If you do not specify a remote name, it will assume 'origin'.  This is helpful if you do not have bookmarks enabled as it will push tip automatically.  If you have bookmarks enabled this is not helpful because you have to specify a branch name after.
-
-Eventually, I would like to setup tracking branch refspecs much like Git - say 'this local branch pushes and pulls to/from this remote and branch', but that will be one of the last things done.
-
-Testing Hg-Git
-==============
-
-Tests are implemented in the Mercurial-standard way of small shell scripts.
-The scripts are located in the tests directory, and to run them you should
-change to that directory and then run tests/run-tests.py from the Mercurial
-sources. For example, if you have a copy of the Mercurial source code at
-/Stuff/hg-crew, you would do something like this:
-
-cd tests ; /Stuff/hg-crew/tests/run-tests.py
-
-And you should see output like this:
-.
-# Ran 1 tests, 0 skipped, 0 failed.
-
-Note that due to limitations of Dulwich at the moment, the tests need to
-start a git-daemon process. Right now, they use the default port, so will
-skip if they detect an already-running git-daemon.
--- a/.hgext/hggit/Makefile	Fri Aug 05 21:41:21 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,25 +0,0 @@
-PYTHON=python
-
-help:
-	@echo 'Commonly used make targets:'
-	@echo '  tests              - run all tests in the automatic test suite'
-	@echo '  all-version-tests - run all tests against many hg versions'
-	@echo '  tests-%s           - run all tests in the specified hg version'
-
-all: help
-
-tests:
-	cd tests && $(PYTHON) run-tests.py --with-hg=`which hg` $(TESTFLAGS)
-
-test-%:
-	cd tests && $(PYTHON) run-tests.py --with-hg=`which hg` $(TESTFLAGS) $@
-
-tests-%:
-	@echo "Path to crew repo is $(CREW) - set this with CREW= if needed."
-	hg -R $(CREW) checkout $$(echo $@ | sed s/tests-//) && \
-	(cd $(CREW) ; $(MAKE) clean ) && \
-	cd tests && $(PYTHON) $(CREW)/tests/run-tests.py $(TESTFLAGS)
-
-all-version-tests: tests-1.4.3 tests-1.5.4 tests-1.6.2 tests-1.7.2 tests-tip
-
-.PHONY: tests all-version-tests
--- a/.hgext/hggit/README.md	Fri Aug 05 21:41:21 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,156 +0,0 @@
-Hg-Git Mercurial Plugin
-=======================
-
-This is the Hg-Git plugin for Mercurial, adding the ability to push
-and pull to/from a Git server repository from Hg.  This means you can
-collaborate on Git based projects from Hg, or use a Git server as a
-collaboration point for a team with developers using both Git and Hg.
-
-The Hg-Git plugin can convert commits/changesets losslessly from one
-system to another, so you can push via an Hg repository and another Hg
-client can pull it and their changeset node ids will be identical -
-Mercurial data does not get lost in translation.  It is intended that
-Hg users may wish to use this to collaborate even if no Git users are
-involved in the project, and it may even provide some advantages if
-you're using Bookmarks (see below).
-
-Dependencies
-============
-
-This plugin is implemented entirely in Python - there are no Git
-binary dependencies, you do not need to have Git installed on your
-system.  The only dependencies are Mercurial and Dulwich.  The plugin
-is known to work on Hg versions 1.3 through 1.5 and requires at least
-Dulwich 0.6.0.
-
-Usage
-=====
-
-You can clone a Git repository from Hg by running `hg clone [url]`.  For
-example, if you were to run
-
-    $ hg clone git://github.com/schacon/hg-git.git
-
-hg-git would clone the repository down into the directory 'munger.git', then
-convert it to an Hg repository for you.
-
-If you want to clone a github repository for later pushing (or any
-other repository you access via ssh), you need to convert the ssh url
-to a format with an explicit protocol prefix. For example, the git url
-with push access
-
-    git@github.com:schacon/hg-git.git
-
-would read
-
-    git+ssh://git@github.com/schacon/hg-git.git
-
-(Mind the switch from colon to slash after the host!)
-
-Your clone command would thus look like this:
-
-    $ hg clone git+ssh://git@github.com/schacon/hg-git.git
-
-If you are starting from an existing Hg repository, you have to setup
-a Git repository somewhere that you have push access to, add it as
-default path or default-push path in your .hg/hgrc and then run `hg
-push` from within your project.  For example:
-
-    $ cd hg-git # (an Hg repository)
-    $ # edit .hg/hgrc and add the target git url in the paths section
-    $ hg push
-
-This will convert all your Hg data into Git objects and push them up to the Git server.
-
-Now that you have an Hg repository that can push/pull to/from a Git
-repository, you can fetch updates with `hg pull`.
-
-    $ hg pull
-
-That will pull down any commits that have been pushed to the server in
-the meantime and give you a new head that you can merge in.
-
-Hg-Git can also be used to convert a Mercurial repository to Git.  As
-Dulwich doesn't support local repositories yet, the easiest way is to
-setup up a local SSH server.  Then use the following commands to
-convert the repository (it assumes your running this in $HOME).
-
-    $ mkdir git-repo; cd git-repo; git init; cd ..
-    $ cd hg-repo
-    $ hg bookmarks hg
-    $ hg push git+ssh://localhost:git-repo
-
-The hg bookmark is necessary to prevent problems as otherwise hg-git
-pushes to the currently checked out branch confusing Git. This will
-create a branch named hg in the Git repository. To get the changes in
-master use the following command (only necessary in the first run,
-later just use git merge or rebase).
-
-    $ cd git-repo
-    $ git checkout -b master hg
-
-To import new changesets into the Git repository just rerun the hg
-push command and then use git merge or git rebase in your Git
-repository.
-
-Commands
-========
-
-gclear
-------
-
-TODO
-
-gimport
--------
-
-TODO
-
-gexport
--------
-
-TODO
-
-git-cleanup
------------
-
-TODO
-
-Hg Bookmarks Integration
-========================
-
-If you have the bookmarks extension enabled, Hg-Git will use it. It
-will push your bookmarks up to the Git server as branches and will
-pull Git branches down and set them up as bookmarks.
-
-This is actually pretty cool, since you can use this extension to
-transfer your Hg bookmarks via the Git protocol, rather than having to
-scp them, as the Hg transfer protocol does not currently support
-transferring bookmarks.
-
-Installing
-==========
-
-Clone this repository somewhere and make the 'extensions' section in
-your `~/.hgrc` file look something like this:
-
-    [extensions]
-    hgext.bookmarks =
-    hggit = [path-to]/hg-git/hggit
-
-That will enable the Hg-Git extension for you.  The bookmarks section
-is not compulsory, but it makes some things a bit nicer for you.
-
-Configuration
-=============
-
-git.intree
-----------
-
-hg-git keeps a git repository clone for reading and updating. By default, the
-git clone is the subdirectory `git` in your local Mercurial repository. If you
-would like this git clone to be at the same level of your Mercurial repository
-instead (named `.git`), add the following to your `hgrc`:
-
-    [git]
-    intree = True
--- a/.hgext/hggit/TODO.txt	Fri Aug 05 21:41:21 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,33 +0,0 @@
-GENERAL
-==========
-* work fine with eclipse plugin or tortoise-hg
-
-MAPPING ISSUES
-==============
-* work in Git on a named branch created in Hg is forward-ported to be named branch commits in Hg and stripped back out if re-exported
-
-
-REMOTE/BRANCH STUFF
-=====================
-* explain what branch mapping policy determined when updating refs
-* error nicer if pushing to remote without push access (over git://)
-
-WEBSITE
-===========
-* more usage documentation
-* screencast
-
-
-SPEED/EFFICIENCY
-================
-* dulwich improvements
-  - don't send blobs/trees already on server
-  - thin packs
-  - packfile creation benchmarking (seems to take a while sometimes)
-  - at least provide status output
-
-MAYBE
-==========
-* submodules?
-* .gitignore, etc - try to convert? 
-  - (probably not automatically, but perhaps a generator?)
--- a/.hgext/hggit/hggit/__init__.py	Fri Aug 05 21:41:21 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,147 +0,0 @@
-# git.py - git server bridge
-#
-# Copyright 2008 Scott Chacon <schacon at gmail dot com>
-#   also some code (and help) borrowed from durin42
-#
-# This software may be used and distributed according to the terms
-# of the GNU General Public License, incorporated herein by reference.
-
-'''push and pull from a Git server
-
-This extension lets you communicate (push and pull) with a Git server.
-This way you can use Git hosting for your project or collaborate with a
-project that is in Git.  A bridger of worlds, this plugin be.
-
-Try hg clone git:// or hg clone git+ssh://
-'''
-
-import inspect
-import os
-
-from mercurial import commands
-from mercurial import demandimport
-from mercurial import extensions
-from mercurial import hg
-from mercurial import localrepo
-from mercurial import util as hgutil
-from mercurial.i18n import _
-
-demandimport.ignore.extend([
-    'collections',
-    ])
-
-import gitrepo, hgrepo
-from git_handler import GitHandler
-
-# support for `hg clone git://github.com/defunkt/facebox.git`
-# also hg clone git+ssh://git@github.com/schacon/simplegit.git
-hg.schemes['git'] = gitrepo
-hg.schemes['git+ssh'] = gitrepo
-
-# support for `hg clone localgitrepo`
-_oldlocal = hg.schemes['file']
-
-def _local(path):
-    p = hgutil.drop_scheme('file', path)
-    if (os.path.exists(os.path.join(p, '.git')) and
-        not os.path.exists(os.path.join(p, '.hg'))):
-        return gitrepo
-    # detect a bare repository
-    if (os.path.exists(os.path.join(p, 'HEAD')) and
-        os.path.exists(os.path.join(p, 'objects')) and
-        os.path.exists(os.path.join(p, 'refs')) and
-        not os.path.exists(os.path.join(p, '.hg'))):
-        return gitrepo
-    return _oldlocal(path)
-
-hg.schemes['file'] = _local
-
-hgdefaultdest = hg.defaultdest
-def defaultdest(source):
-    for scheme in ('git', 'git+ssh'):
-        if source.startswith('%s://' % scheme) and source.endswith('.git'):
-            source = source[:-4]
-            break
-    return hgdefaultdest(source)
-hg.defaultdest = defaultdest
-
-# defend against tracebacks if we specify -r in 'hg pull'
-def safebranchrevs(orig, lrepo, repo, branches, revs):
-    revs, co = orig(lrepo, repo, branches, revs)
-    if getattr(lrepo, 'changelog', False) and co not in lrepo.changelog:
-        co = None
-    return revs, co
-if getattr(hg, 'addbranchrevs', False):
-    extensions.wrapfunction(hg, 'addbranchrevs', safebranchrevs)
-
-def reposetup(ui, repo):
-    if not isinstance(repo, gitrepo.gitrepo):
-        klass = hgrepo.generate_repo_subclass(repo.__class__)
-        repo.__class__ = klass
-
-def gimport(ui, repo, remote_name=None):
-    git = GitHandler(repo, ui)
-    git.import_commits(remote_name)
-
-def gexport(ui, repo):
-    git = GitHandler(repo, ui)
-    git.export_commits()
-
-def gclear(ui, repo):
-    repo.ui.status(_("clearing out the git cache data\n"))
-    git = GitHandler(repo, ui)
-    git.clear()
-
-def git_cleanup(ui, repo):
-    new_map = []
-    for line in repo.opener(GitHandler.mapfile):
-        gitsha, hgsha = line.strip().split(' ', 1)
-        if hgsha in repo:
-            new_map.append('%s %s\n' % (gitsha, hgsha))
-    f = repo.opener(GitHandler.mapfile, 'wb')
-    map(f.write, new_map)
-    ui.status(_('git commit map cleaned\n'))
-
-# drop this when we're 1.6-only, this just backports new behavior
-def sortednodetags(orig, *args, **kwargs):
-    ret = orig(*args, **kwargs)
-    ret.sort()
-    return ret
-extensions.wrapfunction(localrepo.localrepository, 'nodetags', sortednodetags)
-
-try:
-    from mercurial import discovery
-    kwname = 'heads'
-    if hg.util.version() >= '1.7':
-        kwname = 'remoteheads'
-    def findoutgoing(orig, local, remote, *args, **kwargs):
-        kw = {}
-        kw.update(kwargs)
-        for val, k in zip(args, ('base', kwname, 'force')):
-            kw[k] = val
-        if isinstance(remote, gitrepo.gitrepo):
-            # clean up this cruft when we're 1.7-only, remoteheads and
-            # the return value change happened between 1.6 and 1.7.
-            git = GitHandler(local, local.ui)
-            base, heads = git.get_refs(remote.path)
-            newkw = {'base': base, kwname: heads}
-            newkw.update(kw)
-            kw = newkw
-            if kwname == 'heads':
-                r = orig(local, remote, **kw)
-                return [x[0] for x in r]
-        return orig(local, remote, **kw)
-    extensions.wrapfunction(discovery, 'findoutgoing', findoutgoing)
-except ImportError:
-    pass
-
-cmdtable = {
-  "gimport":
-        (gimport, [], _('hg gimport')),
-  "gexport":
-        (gexport, [], _('hg gexport')),
-  "gclear":
-      (gclear, [], _('Clears out the Git cached data')),
-  "git-cleanup": (git_cleanup, [], _(
-        "Cleans up git repository after history editing"))
-}
Binary file .hgext/hggit/hggit/__init__.pyc has changed
--- a/.hgext/hggit/hggit/_ssh.py	Fri Aug 05 21:41:21 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,30 +0,0 @@
-from mercurial import util
-
-class SSHVendor(object):
-    """Parent class for ui-linked Vendor classes."""
-
-
-def generate_ssh_vendor(ui):
-    """
-    Allows dulwich to use hg's ui.ssh config. The dulwich.client.get_ssh_vendor
-    property should point to the return value.
-    """
-
-    class _Vendor(SSHVendor):
-        def connect_ssh(self, host, command, username=None, port=None):
-            from dulwich.client import SubprocessWrapper
-            from mercurial import util
-            import subprocess
-
-            sshcmd = ui.config("ui", "ssh", "ssh")
-            args = util.sshargs(sshcmd, host, username, port)
-            cmd = '%s %s %s' % (sshcmd, args, 
-                                util.shellquote(' '.join(command)))
-            ui.debug('calling ssh: %s\n' % cmd)
-            print command
-            proc = subprocess.Popen(util.quotecommand(cmd), shell=True,
-                                    stdin=subprocess.PIPE,
-                                    stdout=subprocess.PIPE)
-            return SubprocessWrapper(proc)
-
-    return _Vendor
--- a/.hgext/hggit/hggit/git_handler.py	Fri Aug 05 21:41:21 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,936 +0,0 @@
-import os, math, urllib, re
-
-from dulwich.errors import HangupException
-from dulwich.index import commit_tree
-from dulwich.objects import Blob, Commit, Tag, Tree, parse_timezone
-from dulwich.pack import create_delta, apply_delta
-from dulwich.repo import Repo
-from dulwich import client
-
-try:
-    from mercurial import bookmarks
-    bookmarks.update
-    from mercurial import commands
-except ImportError:
-    from hgext import bookmarks
-from mercurial.i18n import _
-from mercurial.node import hex, bin, nullid
-from mercurial import context, util as hgutil
-from mercurial import error
-
-import _ssh
-import util
-
-class GitHandler(object):
-    mapfile = 'git-mapfile'
-    tagsfile = 'git-tags'
-
-    def __init__(self, dest_repo, ui):
-        self.repo = dest_repo
-        self.ui = ui
-
-        if ui.configbool('git', 'intree'):
-            self.gitdir = self.repo.wjoin('.git')
-        else:
-            self.gitdir = self.repo.join('git')
-
-        self.paths = ui.configitems('paths')
-
-        self.load_map()
-        self.load_tags()
-
-    # make the git data directory
-    def init_if_missing(self):
-        if os.path.exists(self.gitdir):
-            self.git = Repo(self.gitdir)
-        else:
-            os.mkdir(self.gitdir)
-            self.git = Repo.init_bare(self.gitdir)
-
-    ## FILE LOAD AND SAVE METHODS
-
-    def map_set(self, gitsha, hgsha):
-        self._map_git[gitsha] = hgsha
-        self._map_hg[hgsha] = gitsha
-
-    def map_hg_get(self, gitsha):
-        return self._map_git.get(gitsha)
-
-    def map_git_get(self, hgsha):
-        return self._map_hg.get(hgsha)
-
-    def load_map(self):
-        self._map_git = {}
-        self._map_hg = {}
-        if os.path.exists(self.repo.join(self.mapfile)):
-            for line in self.repo.opener(self.mapfile):
-                gitsha, hgsha = line.strip().split(' ', 1)
-                self._map_git[gitsha] = hgsha
-                self._map_hg[hgsha] = gitsha
-
-    def save_map(self):
-        file = self.repo.opener(self.mapfile, 'w+', atomictemp=True)
-        for hgsha, gitsha in sorted(self._map_hg.iteritems()):
-            file.write("%s %s\n" % (gitsha, hgsha))
-        file.rename()
-
-    def load_tags(self):
-        self.tags = {}
-        if os.path.exists(self.repo.join(self.tagsfile)):
-            for line in self.repo.opener(self.tagsfile):
-                sha, name = line.strip().split(' ', 1)
-                self.tags[name] = sha
-
-    def save_tags(self):
-        file = self.repo.opener(self.tagsfile, 'w+', atomictemp=True)
-        for name, sha in sorted(self.tags.iteritems()):
-            if not self.repo.tagtype(name) == 'global':
-                file.write("%s %s\n" % (sha, name))
-        file.rename()
-
-    ## END FILE LOAD AND SAVE METHODS
-
-    ## COMMANDS METHODS
-
-    def import_commits(self, remote_name):
-        self.import_git_objects(remote_name)
-        self.save_map()
-
-    def fetch(self, remote, heads):
-        self.export_commits()
-        refs = self.fetch_pack(remote, heads)
-        remote_name = self.remote_name(remote)
-
-        if refs:
-            self.import_git_objects(remote_name, refs)
-            self.import_tags(refs)
-            self.update_hg_bookmarks(refs)
-            if remote_name:
-                self.update_remote_branches(remote_name, refs)
-            elif not self.paths:
-                # intial cloning
-                self.update_remote_branches('default', refs)
-        else:
-            self.ui.status(_("nothing new on the server\n"))
-
-        self.save_map()
-
-    def export_commits(self):
-        try:
-            self.export_git_objects()
-            self.export_hg_tags()
-            self.update_references()
-        finally:
-            self.save_map()
-
-    def get_refs(self, remote):
-        self.export_commits()
-        client, path = self.get_transport_and_path(remote)
-        old_refs = {}
-        new_refs = {}
-        def changed(refs):
-            old_refs.update(refs)
-            to_push = set(self.local_heads().values() + self.tags.values())
-            new_refs.update(self.get_changed_refs(refs, to_push, True))
-            # don't push anything
-            return {}
-
-        try:
-            client.send_pack(path, changed, None)
-
-            changed_refs = [ref for ref, sha in new_refs.iteritems()
-                            if sha != old_refs.get(ref)]
-            new = [bin(self.map_hg_get(new_refs[ref])) for ref in changed_refs]
-            old = dict( (bin(self.map_hg_get(old_refs[r])), 1)
-                       for r in changed_refs if r in old_refs)
-
-            return old, new
-        except HangupException:
-            raise hgutil.Abort("the remote end hung up unexpectedly")
-
-    def push(self, remote, revs, force):
-        self.export_commits()
-        changed_refs = self.upload_pack(remote, revs, force)
-        remote_name = self.remote_name(remote)
-
-        if remote_name and changed_refs:
-            for ref, sha in changed_refs.iteritems():
-                self.ui.status("    %s::%s => GIT:%s\n" %
-                               (remote_name, ref, sha[0:8]))
-
-            self.update_remote_branches(remote_name, changed_refs)
-
-    def clear(self):
-        mapfile = self.repo.join(self.mapfile)
-        if os.path.exists(self.gitdir):
-            for root, dirs, files in os.walk(self.gitdir, topdown=False):
-                for name in files:
-                    os.remove(os.path.join(root, name))
-                for name in dirs:
-                    os.rmdir(os.path.join(root, name))
-            os.rmdir(self.gitdir)
-        if os.path.exists(mapfile):
-            os.remove(mapfile)
-
-    ## CHANGESET CONVERSION METHODS
-
-    def export_git_objects(self):
-        self.ui.status(_("importing Hg objects into Git\n"))
-        self.init_if_missing()
-
-        nodes = [self.repo.lookup(n) for n in self.repo]
-        export = [node for node in nodes if not hex(node) in self._map_hg]
-        total = len(export)
-        for i, rev in enumerate(export):
-            util.progress(self.ui, 'importing', i, total=total)
-            ctx = self.repo.changectx(rev)
-            state = ctx.extra().get('hg-git', None)
-            if state == 'octopus':
-                self.ui.debug("revision %d is a part "
-                              "of octopus explosion\n" % ctx.rev())
-                continue
-            self.export_hg_commit(rev)
-        util.progress(self.ui, 'importing', None, total=total)
-
-
-    # convert this commit into git objects
-    # go through the manifest, convert all blobs/trees we don't have
-    # write the commit object (with metadata info)
-    def export_hg_commit(self, rev):
-        self.ui.note(_("converting revision %s\n") % hex(rev))
-
-        oldenc = self.swap_out_encoding()
-
-        ctx = self.repo.changectx(rev)
-        extra = ctx.extra()
-
-        commit = Commit()
-
-        (time, timezone) = ctx.date()
-        commit.author = self.get_git_author(ctx)
-        commit.author_time = int(time)
-        commit.author_timezone = -timezone
-
-        if 'committer' in extra:
-            # fixup timezone
-            (name, timestamp, timezone) = extra['committer'].rsplit(' ', 2)
-            commit.committer = name
-            commit.commit_time = timestamp
-
-            # work around a timezone format change
-            if int(timezone) % 60 != 0: #pragma: no cover
-                timezone = parse_timezone(timezone)
-                # Newer versions of Dulwich return a tuple here
-                if isinstance(timezone, tuple):
-                    timezone, neg_utc = timezone
-                    commit._commit_timezone_neg_utc = neg_utc
-            else:
-                timezone = -int(timezone)
-            commit.commit_timezone = timezone
-        else:
-            commit.committer = commit.author
-            commit.commit_time = commit.author_time
-            commit.commit_timezone = commit.author_timezone
-
-        commit.parents = []
-        for parent in self.get_git_parents(ctx):
-            hgsha = hex(parent.node())
-            git_sha = self.map_git_get(hgsha)
-            if git_sha:
-                commit.parents.append(git_sha)
-
-        commit.message = self.get_git_message(ctx)
-
-        if 'encoding' in extra:
-            commit.encoding = extra['encoding']
-
-        tree_sha = commit_tree(self.git.object_store, self.iterblobs(ctx))
-        commit.tree = tree_sha
-
-        self.git.object_store.add_object(commit)
-        self.map_set(commit.id, ctx.hex())
-
-        self.swap_out_encoding(oldenc)
-        return commit.id
-
-    def get_git_author(self, ctx):
-        # hg authors might not have emails
-        author = ctx.user()
-
-        # check for git author pattern compliance
-        regex = re.compile('^(.*?) \<(.*?)\>(.*)$')
-        a = regex.match(author)
-
-        if a:
-            name = a.group(1)
-            email = a.group(2)
-            if len(a.group(3)) > 0:
-                name += ' ext:(' + urllib.quote(a.group(3)) + ')'
-            author = name + ' <' + email + '>'
-        else:
-            author = author + ' <none@none>'
-
-        if 'author' in ctx.extra():
-            author = "".join(apply_delta(author, ctx.extra()['author']))
-
-        return author
-
-    def get_git_parents(self, ctx):
-        def is_octopus_part(ctx):
-            return ctx.extra().get('hg-git', None) in ('octopus', 'octopus-done')
-
-        parents = []
-        if ctx.extra().get('hg-git', None) == 'octopus-done':
-            # implode octopus parents
-            part = ctx
-            while is_octopus_part(part):
-                (p1, p2) = part.parents()
-                assert not is_octopus_part(p1)
-                parents.append(p1)
-                part = p2
-            parents.append(p2)
-        else:
-            parents = ctx.parents()
-
-        return parents
-
-    def get_git_message(self, ctx):
-        extra = ctx.extra()
-
-        message = ctx.description() + "\n"
-        if 'message' in extra:
-            message = "".join(apply_delta(message, extra['message']))
-
-        # HG EXTRA INFORMATION
-        add_extras = False
-        extra_message = ''
-        if not ctx.branch() == 'default':
-            add_extras = True
-            extra_message += "branch : " + ctx.branch() + "\n"
-
-        renames = []
-        for f in ctx.files():
-            if f not in ctx.manifest():
-                continue
-            rename = ctx.filectx(f).renamed()
-            if rename:
-                renames.append((rename[0], f))
-
-        if renames:
-            add_extras = True
-            for oldfile, newfile in renames:
-                extra_message += "rename : " + oldfile + " => " + newfile + "\n"
-
-        for key, value in extra.iteritems():
-            if key in ('author', 'committer', 'encoding', 'message', 'branch', 'hg-git'):
-                continue
-            else:
-                add_extras = True
-                extra_message += "extra : " + key + " : " +  urllib.quote(value) + "\n"
-
-        if add_extras:
-            message += "\n--HG--\n" + extra_message
-
-        return message
-
-    def iterblobs(self, ctx):
-        for f in ctx:
-            fctx = ctx[f]
-            blobid = self.map_git_get(hex(fctx.filenode()))
-
-            if not blobid:
-                blob = Blob.from_string(fctx.data())
-                self.git.object_store.add_object(blob)
-                self.map_set(blob.id, hex(fctx.filenode()))
-                blobid = blob.id
-
-            if 'l' in ctx.flags(f):
-                mode = 0120000
-            elif 'x' in ctx.flags(f):
-                mode = 0100755
-            else:
-                mode = 0100644
-
-            yield f, blobid, mode
-
-    def import_git_objects(self, remote_name=None, refs=None):
-        self.ui.status(_("importing Git objects into Hg\n"))
-        self.init_if_missing()
-
-        # import heads and fetched tags as remote references
-        todo = []
-        done = set()
-        convert_list = {}
-
-        # get a list of all the head shas
-        seenheads = set()
-        if refs is None:
-            refs = self.git.refs.as_dict()
-        if refs:
-            for sha in refs.itervalues():
-                # refs contains all the refs in the server, not just the ones
-                # we are pulling
-                if sha in self.git.object_store:
-                    obj = self.git.get_object(sha)
-                    while isinstance(obj, Tag):
-                        obj_type, sha = obj.object
-                        obj = self.git.get_object(sha)
-                    if isinstance (obj, Commit) and sha not in seenheads:
-                        seenheads.add(sha)
-                        todo.append(sha)
-
-        # sort by commit date
-        def commitdate(sha):
-            obj = self.git.get_object(sha)
-            return obj.commit_time-obj.commit_timezone
-
-        todo.sort(key=commitdate, reverse=True)
-
-        # traverse the heads getting a list of all the unique commits
-        commits = []
-        seen = set(todo)
-        while todo:
-            sha = todo[-1]
-            if sha in done:
-                todo.pop()
-                continue
-            assert isinstance(sha, str)
-            obj = self.git.get_object(sha)
-            assert isinstance(obj, Commit)
-            for p in obj.parents:
-                if p not in done:
-                    todo.append(p)
-                    break
-            else:
-                commits.append(sha)
-                convert_list[sha] = obj
-                done.add(sha)
-                todo.pop()
-
-        commits = [commit for commit in commits if not commit in self._map_git]
-        # import each of the commits, oldest first
-        total = len(commits)
-        for i, csha in enumerate(commits):
-            util.progress(self.ui, 'importing', i, total=total, unit='commits')
-            commit = convert_list[csha]
-            self.import_git_commit(commit)
-        util.progress(self.ui, 'importing', None, total=total, unit='commits')
-
-    def import_git_commit(self, commit):
-        self.ui.debug(_("importing: %s\n") % commit.id)
-
-        (strip_message, hg_renames,
-         hg_branch, extra) = self.extract_hg_metadata(commit.message)
-
-        # get a list of the changed, added, removed files
-        files = self.get_files_changed(commit)
-
-        date = (commit.author_time, -commit.author_timezone)
-        text = strip_message
-
-        origtext = text
-        try:
-            text.decode('utf-8')
-        except UnicodeDecodeError:
-            text = self.decode_guess(text, commit.encoding)
-
-        text = '\n'.join([l.rstrip() for l in text.splitlines()]).strip('\n')
-        if text + '\n' != origtext:
-            extra['message'] = create_delta(text +'\n', origtext)
-
-        author = commit.author
-
-        # convert extra data back to the end
-        if ' ext:' in commit.author:
-            regex = re.compile('^(.*?)\ ext:\((.*)\) <(.*)\>$')
-            m = regex.match(commit.author)
-            if m:
-                name = m.group(1)
-                ex = urllib.unquote(m.group(2))
-                email = m.group(3)
-                author = name + ' <' + email + '>' + ex
-
-        if ' <none@none>' in commit.author:
-            author = commit.author[:-12]
-
-        try:
-            author.decode('utf-8')
-        except UnicodeDecodeError:
-            origauthor = author
-            author = self.decode_guess(author, commit.encoding)
-            extra['author'] = create_delta(author, origauthor)
-
-        oldenc = self.swap_out_encoding()
-
-        def getfilectx(repo, memctx, f):
-            delete, mode, sha = files[f]
-            if delete:
-                raise IOError
-
-            data = self.git[sha].data
-            copied_path = hg_renames.get(f)
-            e = self.convert_git_int_mode(mode)
-
-            return context.memfilectx(f, data, 'l' in e, 'x' in e, copied_path)
-
-        gparents = map(self.map_hg_get, commit.parents)
-        p1, p2 = (nullid, nullid)
-        octopus = False
-
-        if len(gparents) > 1:
-            # merge, possibly octopus
-            def commit_octopus(p1, p2):
-                ctx = context.memctx(self.repo, (p1, p2), text, list(files), getfilectx,
-                                     author, date, {'hg-git': 'octopus'})
-                return hex(self.repo.commitctx(ctx))
-
-            octopus = len(gparents) > 2
-            p2 = gparents.pop()
-            p1 = gparents.pop()
-            while len(gparents) > 0:
-                p2 = commit_octopus(p1, p2)
-                p1 = gparents.pop()
-        else:
-            if gparents:
-                p1 = gparents.pop()
-
-        pa = None
-        if not (p2 == nullid):
-            node1 = self.repo.changectx(p1)
-            node2 = self.repo.changectx(p2)
-            pa = node1.ancestor(node2)
-
-        # if named branch, add to extra
-        if hg_branch:
-            extra['branch'] = hg_branch
-
-        # if committer is different than author, add it to extra
-        if commit.author != commit.committer \
-               or commit.author_time != commit.commit_time \
-               or commit.author_timezone != commit.commit_timezone:
-            extra['committer'] = "%s %d %d" % (
-                commit.committer, commit.commit_time, -commit.commit_timezone)
-
-        if commit.encoding:
-            extra['encoding'] = commit.encoding
-
-        if hg_branch:
-            extra['branch'] = hg_branch
-
-        if octopus:
-            extra['hg-git'] ='octopus-done'
-
-        # TODO use 'n in self.repo' when we require hg 1.5
-        def repo_contains(n):
-            try:
-                return bool(self.repo.lookup(n))
-            except error.RepoLookupError:
-                return False
-
-        if not (repo_contains(p1) and repo_contains(p2)):
-            raise hgutil.Abort(_('you appear to have run strip - '
-                                 'please run hg git-cleanup'))
-        ctx = context.memctx(self.repo, (p1, p2), text, list(files), getfilectx,
-                             author, date, extra)
-
-        node = self.repo.commitctx(ctx)
-
-        self.swap_out_encoding(oldenc)
-
-        # save changeset to mapping file
-        cs = hex(node)
-        self.map_set(commit.id, cs)
-
-    ## PACK UPLOADING AND FETCHING
-
-    def upload_pack(self, remote, revs, force):
-        client, path = self.get_transport_and_path(remote)
-        def changed(refs):
-            to_push = revs or set(self.local_heads().values() + self.tags.values())
-            return self.get_changed_refs(refs, to_push, force)
-
-        genpack = self.git.object_store.generate_pack_contents
-        try:
-            self.ui.status(_("creating and sending data\n"))
-            changed_refs = client.send_pack(path, changed, genpack)
-            return changed_refs
-        except HangupException:
-            raise hgutil.Abort("the remote end hung up unexpectedly")
-
-    def get_changed_refs(self, refs, revs, force):
-        new_refs = refs.copy()
-
-        #The remote repo is empty and the local one doesn't have bookmarks/tags
-        if refs.keys()[0] == 'capabilities^{}':
-            del new_refs['capabilities^{}']
-            if not self.local_heads():
-                tip = hex(self.repo.lookup('tip'))
-                try:
-                    commands.bookmark(self.ui, self.repo, 'master', tip, force=True)
-                except NameError:
-                    bookmarks.bookmark(self.ui, self.repo, 'master', tip, force=True)
-                bookmarks.setcurrent(self.repo, 'master')
-                new_refs['refs/heads/master'] = self.map_git_get(tip)
-
-        for rev in revs:
-            ctx = self.repo[rev]
-            if getattr(ctx, 'bookmarks', None):
-                labels = lambda c: ctx.tags() + ctx.bookmarks()
-            else:
-                labels = lambda c: ctx.tags()
-            prep = lambda itr: [i.replace(' ', '_') for i in itr]
-
-            heads = [t for t in prep(labels(ctx)) if t in self.local_heads()]
-            tags = [t for t in prep(labels(ctx)) if t in self.tags]
-
-            if not (heads or tags):
-                raise hgutil.Abort("revision %s cannot be pushed since"
-                                   " it doesn't have a ref" % ctx)
-
-            # Check if the tags the server is advertising are annotated tags,
-            # by attempting to retrieve it from the our git repo, and building a
-            # list of these tags.
-            #
-            # This is possible, even though (currently) annotated tags are
-            # dereferenced and stored as lightweight ones, as the annotated tag
-            # is still stored in the git repo.
-            uptodate_annotated_tags = []
-            for r in tags:
-                ref = 'refs/tags/'+r
-                # Check tag.
-                if not ref in refs:
-                    continue
-                try:
-                    # We're not using Repo.tag(), as it's deprecated.
-                    tag = self.git.get_object(refs[ref])
-                    if not isinstance(tag, Tag):
-                        continue
-                except KeyError:
-                    continue
-
-                # If we've reached here, the tag's good.
-                uptodate_annotated_tags.append(ref)
-
-            for r in heads + tags:
-                if r in heads:
-                    ref = 'refs/heads/'+r
-                else:
-                    ref = 'refs/tags/'+r
-
-                if ref not in refs:
-                    new_refs[ref] = self.map_git_get(ctx.hex())
-                elif new_refs[ref] in self._map_git:
-                    rctx = self.repo[self.map_hg_get(new_refs[ref])]
-                    if rctx.ancestor(ctx) == rctx or force:
-                        new_refs[ref] = self.map_git_get(ctx.hex())
-                    else:
-                        raise hgutil.Abort("pushing %s overwrites %s"
-                                           % (ref, ctx))
-                elif ref in uptodate_annotated_tags:
-                    # we already have the annotated tag.
-                    pass
-                else:
-                    raise hgutil.Abort("%s changed on the server, please pull "
-                                       "and merge before pushing" % ref)
-
-        return new_refs
-
-
-    def fetch_pack(self, remote_name, heads):
-        client, path = self.get_transport_and_path(remote_name)
-        graphwalker = self.git.get_graph_walker()
-        def determine_wants(refs):
-            if heads:
-                want = []
-                # contains pairs of ('refs/(heads|tags|...)/foo', 'foo')
-                # if ref is just '<foo>', then we get ('foo', 'foo')
-                stripped_refs = [
-                    (r, r[r.find('/', r.find('/')+1)+1:])
-                        for r in refs]
-                for h in heads:
-                    r = [pair[0] for pair in stripped_refs if pair[1] == h]
-                    if not r:
-                        raise hgutil.Abort("ref %s not found on remote server" % h)
-                    elif len(r) == 1:
-                        want.append(refs[r[0]])
-                    else:
-                        raise hgutil.Abort("ambiguous reference %s: %r" % (h, r))
-            else:
-                want = [sha for ref, sha in refs.iteritems()
-                        if not ref.endswith('^{}')]
-            return want
-        f, commit = self.git.object_store.add_pack()
-        try:
-            try:
-                return client.fetch_pack(path, determine_wants, graphwalker,
-                                         f.write, self.ui.status)
-            except HangupException:
-                raise hgutil.Abort("the remote end hung up unexpectedly")
-        finally:
-            commit()
-
-    ## REFERENCES HANDLING
-
-    def update_references(self):
-        heads = self.local_heads()
-
-        # Create a local Git branch name for each
-        # Mercurial bookmark.
-        for key in heads:
-            self.git.refs['refs/heads/' + key] = self.map_git_get(heads[key])
-
-    def export_hg_tags(self):
-        for tag, sha in self.repo.tags().iteritems():
-            if self.repo.tagtype(tag) in ('global', 'git'):
-                tag = tag.replace(' ', '_')
-                self.git.refs['refs/tags/' + tag] = self.map_git_get(hex(sha))
-                self.tags[tag] = hex(sha)
-
-    def local_heads(self):
-        try:
-            if getattr(bookmarks, 'parse', None):
-                bms = bookmarks.parse(self.repo)
-            else:
-                bms = self.repo._bookmarks
-            return dict([(bm, hex(bms[bm])) for bm in bms])
-        except AttributeError: #pragma: no cover
-            return {}
-
-    def import_tags(self, refs):
-        keys = refs.keys()
-        if not keys:
-            return
-        for k in keys[:]:
-            ref_name = k
-            parts = k.split('/')
-            if parts[0] == 'refs' and parts[1] == 'tags':
-                ref_name = "/".join([v for v in parts[2:]])
-                # refs contains all the refs in the server, not just
-                # the ones we are pulling
-                if refs[k] not in self.git.object_store:
-                    continue
-                if ref_name[-3:] == '^{}':
-                    ref_name = ref_name[:-3]
-                if not ref_name in self.repo.tags():
-                    obj = self.git.get_object(refs[k])
-                    sha = None
-                    if isinstance (obj, Commit): # lightweight
-                        sha = self.map_hg_get(refs[k])
-                        self.tags[ref_name] = sha
-                    elif isinstance (obj, Tag): # annotated
-                        (obj_type, obj_sha) = obj.object
-                        obj = self.git.get_object(obj_sha)
-                        if isinstance (obj, Commit):
-                            sha = self.map_hg_get(obj_sha)
-                            # TODO: better handling for annotated tags
-                            self.tags[ref_name] = sha
-        self.save_tags()
-
-    def update_hg_bookmarks(self, refs):
-        try:
-            oldbm = getattr(bookmarks, 'parse', None)
-            if oldbm:
-                bms = bookmarks.parse(self.repo)
-            else:
-                bms = self.repo._bookmarks
-            heads = dict([(ref[11:],refs[ref]) for ref in refs
-                          if ref.startswith('refs/heads/')])
-
-            for head, sha in heads.iteritems():
-                # refs contains all the refs in the server, not just
-                # the ones we are pulling
-                if sha not in self.git.object_store:
-                    continue
-                hgsha = bin(self.map_hg_get(sha))
-                if not head in bms:
-                    # new branch
-                    bms[head] = hgsha
-                else:
-                    bm = self.repo[bms[head]]
-                    if bm.ancestor(self.repo[hgsha]) == bm:
-                        # fast forward
-                        bms[head] = hgsha
-            if heads:
-                if oldbm:
-                    bookmarks.write(self.repo, bms)
-                else:
-                    self.repo._bookmarks = bms
-                    bookmarks.write(self.repo)
-
-        except AttributeError:
-            self.ui.warn(_('creating bookmarks failed, do you have'
-                         ' bookmarks enabled?\n'))
-
-    def update_remote_branches(self, remote_name, refs):
-        tagfile = self.repo.join(os.path.join('git-remote-refs'))
-        tags = self.repo.gitrefs()
-        # since we re-write all refs for this remote each time, prune
-        # all entries matching this remote from our tags list now so
-        # that we avoid any stale refs hanging around forever
-        for t in list(tags):
-            if t.startswith(remote_name + '/'):
-                del tags[t]
-        tags = dict((k, hex(v)) for k, v in tags.iteritems())
-        store = self.git.object_store
-        for ref_name, sha in refs.iteritems():
-            if ref_name.startswith('refs/heads'):
-                if sha not in store:
-                    continue
-                hgsha = self.map_hg_get(sha)
-                head = ref_name[11:]
-                tags['/'.join((remote_name, head))] = hgsha
-                # TODO(durin42): what is this doing?
-                new_ref = 'refs/remotes/%s/%s' % (remote_name, head)
-                self.git.refs[new_ref] = sha
-            elif (ref_name.startswith('refs/tags')
-                  and not ref_name.endswith('^{}')):
-                self.git.refs[ref_name] = sha
-
-        tf = open(tagfile, 'wb')
-        for tag, node in tags.iteritems():
-            tf.write('%s %s\n' % (node, tag))
-        tf.close()
-
-
-    ## UTILITY FUNCTIONS
-
-    def convert_git_int_mode(self, mode):
-        # TODO: make these into constants
-        convert = {
-         0100644: '',
-         0100755: 'x',
-         0120000: 'l'}
-        if mode in convert:
-            return convert[mode]
-        return ''
-
-    def extract_hg_metadata(self, message):
-        split = message.split("\n--HG--\n", 1)
-        renames = {}
-        extra = {}
-        branch = False
-        if len(split) == 2:
-            message, meta = split
-            lines = meta.split("\n")
-            for line in lines:
-                if line == '':
-                    continue
-
-                command, data = line.split(" : ", 1)
-
-                if command == 'rename':
-                    before, after = data.split(" => ", 1)
-                    renames[after] = before
-                if command == 'branch':
-                    branch = data
-                if command == 'extra':
-                    before, after = data.split(" : ", 1)
-                    extra[before] = urllib.unquote(after)
-        return (message, renames, branch, extra)
-
-    def get_file(self, commit, f):
-        otree = self.git.tree(commit.tree)
-        parts = f.split('/')
-        for part in parts:
-            (mode, sha) = otree[part]
-            obj = self.git.get_object(sha)
-            if isinstance (obj, Blob):
-                return (mode, sha, obj._text)
-            elif isinstance(obj, Tree):
-                otree = obj
-
-    def get_files_changed(self, commit):
-        tree = commit.tree
-        btree = None
-
-        if commit.parents:
-            btree = self.git[commit.parents[0]].tree
-
-        changes = self.git.object_store.tree_changes(btree, tree)
-        files = {}
-        for (oldfile, newfile), (oldmode, newmode), (oldsha, newsha) in changes:
-            # don't create new submodules
-            if newmode == 0160000:
-                if oldfile:
-                    # become a regular delete
-                    newfile, newmode = None, None
-                else:
-                    continue
-            # so old submodules shoudn't exist
-            if oldmode == 0160000:
-                if newfile:
-                    # become a regular add
-                    oldfile, oldmode = None, None
-                else:
-                    continue
-
-            if newfile is None:
-                file = oldfile
-                delete = True
-            else:
-                file = newfile
-                delete = False
-
-            files[file] = (delete, newmode, newsha)
-
-        return files
-
-    def remote_name(self, remote):
-        names = [name for name, path in self.paths if path == remote]
-        if names:
-            return names[0]
-
-    # Stolen from hgsubversion
-    def swap_out_encoding(self, new_encoding='UTF-8'):
-        try:
-            from mercurial import encoding
-            old = encoding.encoding
-            encoding.encoding = new_encoding
-        except ImportError:
-            old = hgutil._encoding
-            hgutil._encoding = new_encoding
-        return old
-
-    def decode_guess(self, string, encoding):
-        # text is not valid utf-8, try to make sense of it
-        if encoding:
-            try:
-                return string.decode(encoding).encode('utf-8')
-            except UnicodeDecodeError:
-                pass
-
-        try:
-            return string.decode('latin-1').encode('utf-8')
-        except UnicodeDecodeError:
-            return string.decode('ascii', 'replace').encode('utf-8')
-
-    def get_transport_and_path(self, uri):
-        # pass hg's ui.ssh config to dulwich
-        if not issubclass(client.get_ssh_vendor, _ssh.SSHVendor):
-            client.get_ssh_vendor = _ssh.generate_ssh_vendor(self.ui)
-
-        for handler, transport in (("git://", client.TCPGitClient),
-                                   ("git@", client.SSHGitClient),
-                                   ("git+ssh://", client.SSHGitClient)):
-            if uri.startswith(handler):
-                # We need to split around : or /, whatever comes first
-                hostpath = uri[len(handler):]
-                if (hostpath.find(':') > 0 and hostpath.find('/') > 0):
-                    # we have both, whatever is first wins.
-                    if hostpath.find(':') < hostpath.find('/'):
-                      hostpath_seper = ':'
-                    else:
-                      hostpath_seper = '/'
-                elif hostpath.find(':') > 0:
-                    hostpath_seper = ':'
-                else:
-                    hostpath_seper = '/'
-
-                host, path = hostpath.split(hostpath_seper, 1)
-                if hostpath_seper == '/':
-                    transportpath = '/' + path
-                else:
-                    transportpath = path
-                return transport(host, thin_packs=False), transportpath
-        # if its not git or git+ssh, try a local url..
-        return client.SubprocessGitClient(thin_packs=False), uri
Binary file .hgext/hggit/hggit/git_handler.pyc has changed
--- a/.hgext/hggit/hggit/gitrepo.py	Fri Aug 05 21:41:21 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,36 +0,0 @@
-from mercurial import repo, util
-try:
-    from mercurial.error import RepoError
-except ImportError:
-    from mercurial.repo import RepoError
-
-from git_handler import GitHandler
-
-class gitrepo(repo.repository):
-    capabilities = ['lookup']
-
-    def __init__(self, ui, path, create):
-        if create: # pragma: no cover
-            raise util.Abort('Cannot create a git repository.')
-        self.ui = ui
-        self.path = path
-
-    def lookup(self, key):
-        if isinstance(key, str):
-            return key
-
-    def local(self):
-        if not self.path:
-            raise RepoError
-
-    def heads(self):
-        return []
-
-    def listkeys(self, namespace):
-        return {}
-
-    def pushkey(self, namespace, key, old, new):
-        return False
-
-
-instance = gitrepo
Binary file .hgext/hggit/hggit/gitrepo.pyc has changed
--- a/.hgext/hggit/hggit/hgrepo.py	Fri Aug 05 21:41:21 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-import os
-
-from mercurial.node import bin
-
-from git_handler import GitHandler
-from gitrepo import gitrepo
-
-
-def generate_repo_subclass(baseclass):
-    class hgrepo(baseclass):
-        def pull(self, remote, heads=None, force=False):
-            if isinstance(remote, gitrepo):
-                git = GitHandler(self, self.ui)
-                git.fetch(remote.path, heads)
-            else: #pragma: no cover
-                return super(hgrepo, self).pull(remote, heads, force)
-
-        # TODO figure out something useful to do with the newbranch param
-        def push(self, remote, force=False, revs=None, newbranch=None):
-            if isinstance(remote, gitrepo):
-                git = GitHandler(self, self.ui)
-                git.push(remote.path, revs, force)
-            else: #pragma: no cover
-                # newbranch was added in 1.6
-                if newbranch is None:
-                    return super(hgrepo, self).push(remote, force, revs)
-                else:
-                    return super(hgrepo, self).push(remote, force, revs,
-                                                    newbranch)
-
-        def findoutgoing(self, remote, base=None, heads=None, force=False):
-            if isinstance(remote, gitrepo):
-                git = GitHandler(self, self.ui)
-                base, heads = git.get_refs(remote.path)
-                out, h = super(hgrepo, self).findoutgoing(remote, base, heads, force)
-                return out
-            else: #pragma: no cover
-                return super(hgrepo, self).findoutgoing(remote, base, heads, force)
-
-        def _findtags(self):
-            (tags, tagtypes) = super(hgrepo, self)._findtags()
-
-            git = GitHandler(self, self.ui)
-            for tag, rev in git.tags.iteritems():
-                if tag in tags:
-                    continue
-
-                tags[tag] = bin(rev)
-                tagtypes[tag] = 'git'
-
-            return (tags, tagtypes)
-
-        def gitrefs(self):
-            tagfile = self.join(os.path.join('git-remote-refs'))
-            if os.path.exists(tagfile):
-                tf = open(tagfile, 'rb')
-                tagdata = tf.read().split('\n')
-                td = [line.split(' ', 1) for line in tagdata if line]
-                return dict([(name, bin(sha)) for sha, name in td])
-            return {}
-
-        def tags(self):
-            if not hasattr(self, 'tagscache'):
-                # mercurial 1.4
-                tmp = super(hgrepo, self).tags()
-                tmp.update(self.gitrefs())
-                return tmp
-            if self.tagscache:
-                return self.tagscache
-
-            git = GitHandler(self, self.ui)
-            tagscache = super(hgrepo, self).tags()
-            for tag, rev in git.tags.iteritems():
-                if tag in tagscache:
-                    continue
-
-                tagscache[tag] = bin(rev)
-                self._tagstypecache[tag] = 'git'
-
-            return tagscache
-
-    return hgrepo
Binary file .hgext/hggit/hggit/hgrepo.pyc has changed
--- a/.hgext/hggit/hggit/util.py	Fri Aug 05 21:41:21 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,5 +0,0 @@
-"""Compatability functions for old Mercurial versions."""
-
-def progress(ui, *args, **kwargs):
-    """Shim for progress on hg < 1.4. Remove when 1.3 is dropped."""
-    getattr(ui, 'progress', lambda *x, **kw: None)(*args, **kwargs)
--- a/.hgext/hggit/setup.py	Fri Aug 05 21:41:21 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-try:
-    from setuptools import setup
-except:
-    from distutils.core import setup
-
-setup(
-    name='hg-git',
-    version='0.2.6',
-    author='Scott Chacon',
-    maintainer='Augie Fackler',
-    maintainer_email='durin42@gmail.com',
-    url='http://hg-git.github.com/',
-    description='push and pull from a Git server using Mercurial',
-    long_description="""
-This extension lets you communicate (push and pull) with a Git server.
-This way you can use Git hosting for your project or collaborate with a
-project that is in Git.  A bridger of worlds, this plugin be.
-    """.strip(),
-    keywords='hg git mercurial',
-    license='GPLv2',
-    packages=['hggit'],
-    install_requires=['dulwich>=0.6.0'],
-)
--- a/.hgext/hggit/tests/latin-1-encoding	Fri Aug 05 21:41:21 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,18 +0,0 @@
-# -*- coding: latin-1 -*-
-
-# this file contains some latin-1 messages for test-encoding
-
-GIT_AUTHOR_NAME='tst ncdng'; export GIT_AUTHOR_NAME
-echo beta > beta
-git add beta
-commit -m 'add beta'
-
-echo gamma > gamma
-git add gamma
-commit -m 'add gmm'
-
-# test the commit encoding field
-git config i18n.commitencoding latin-1
-echo delta > delta
-git add delta
-commit -m 'add dlt'
--- a/.hgext/hggit/tests/run-tests.py	Fri Aug 05 21:41:21 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,708 +0,0 @@
-#!/usr/bin/env python
-#
-# run-tests.py - Run a set of tests on Mercurial
-#
-# Copyright 2006 Matt Mackall <mpm@selenic.com>
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2, incorporated herein by reference.
-
-import difflib
-import errno
-import optparse
-import os
-try:
-    import subprocess
-    subprocess.Popen  # trigger ImportError early
-    closefds = os.name == 'posix'
-    def Popen4(cmd, bufsize=-1):
-        p = subprocess.Popen(cmd, shell=True, bufsize=bufsize,
-                             close_fds=closefds,
-                             stdin=subprocess.PIPE, stdout=subprocess.PIPE,
-                             stderr=subprocess.STDOUT)
-        p.fromchild = p.stdout
-        p.tochild = p.stdin
-        p.childerr = p.stderr
-        return p
-except ImportError:
-    subprocess = None
-    from popen2 import Popen4
-import shutil
-import signal
-import sys
-import tempfile
-import time
-
-# reserved exit code to skip test (used by hghave)
-SKIPPED_STATUS = 80
-SKIPPED_PREFIX = 'skipped: '
-FAILED_PREFIX  = 'hghave check failed: '
-PYTHON = sys.executable
-
-requiredtools = ["python", "diff", "grep", "unzip", "gunzip", "bunzip2", "sed"]
-
-defaults = {
-    'jobs': ('HGTEST_JOBS', 1),
-    'timeout': ('HGTEST_TIMEOUT', 180),
-    'port': ('HGTEST_PORT', 20059),
-}
-
-def parseargs():
-    parser = optparse.OptionParser("%prog [options] [tests]")
-    parser.add_option("-C", "--annotate", action="store_true",
-        help="output files annotated with coverage")
-    parser.add_option("--child", type="int",
-        help="run as child process, summary to given fd")
-    parser.add_option("-c", "--cover", action="store_true",
-        help="print a test coverage report")
-    parser.add_option("-f", "--first", action="store_true",
-        help="exit on the first test failure")
-    parser.add_option("-i", "--interactive", action="store_true",
-        help="prompt to accept changed output")
-    parser.add_option("-j", "--jobs", type="int",
-        help="number of jobs to run in parallel"
-             " (default: $%s or %d)" % defaults['jobs'])
-    parser.add_option("--keep-tmpdir", action="store_true",
-        help="keep temporary directory after running tests"
-             " (best used with --tmpdir)")
-    parser.add_option("-R", "--restart", action="store_true",
-        help="restart at last error")
-    parser.add_option("-p", "--port", type="int",
-        help="port on which servers should listen"
-             " (default: $%s or %d)" % defaults['port'])
-    parser.add_option("-r", "--retest", action="store_true",
-        help="retest failed tests")
-    parser.add_option("-s", "--cover_stdlib", action="store_true",
-        help="print a test coverage report inc. standard libraries")
-    parser.add_option("-t", "--timeout", type="int",
-        help="kill errant tests after TIMEOUT seconds"
-             " (default: $%s or %d)" % defaults['timeout'])
-    parser.add_option("--tmpdir", type="string",
-        help="run tests in the given temporary directory")
-    parser.add_option("-v", "--verbose", action="store_true",
-        help="output verbose messages")
-    parser.add_option("-n", "--nodiff", action="store_true",
-        help="skip showing test changes")
-    parser.add_option("--with-hg", type="string",
-        help="test existing install at given location")
-    parser.add_option("--pure", action="store_true",
-        help="use pure Python code instead of C extensions")
-
-    for option, default in defaults.items():
-        defaults[option] = int(os.environ.get(*default))
-    parser.set_defaults(**defaults)
-    (options, args) = parser.parse_args()
-
-    global vlog
-    options.anycoverage = (options.cover or
-                           options.cover_stdlib or
-                           options.annotate)
-
-    if options.verbose:
-        def vlog(*msg):
-            for m in msg:
-                print m,
-            print
-    else:
-        vlog = lambda *msg: None
-
-    if options.jobs < 1:
-        print >> sys.stderr, 'ERROR: -j/--jobs must be positive'
-        sys.exit(1)
-    if options.interactive and options.jobs > 1:
-        print '(--interactive overrides --jobs)'
-        options.jobs = 1
-
-    return (options, args)
-
-def rename(src, dst):
-    """Like os.rename(), trade atomicity and opened files friendliness
-    for existing destination support.
-    """
-    shutil.copy(src, dst)
-    os.remove(src)
-
-def splitnewlines(text):
-    '''like str.splitlines, but only split on newlines.
-    keep line endings.'''
-    i = 0
-    lines = []
-    while True:
-        n = text.find('\n', i)
-        if n == -1:
-            last = text[i:]
-            if last:
-                lines.append(last)
-            return lines
-        lines.append(text[i:n+1])
-        i = n + 1
-
-def parsehghaveoutput(lines):
-    '''Parse hghave log lines.
-    Return tuple of lists (missing, failed):
-      * the missing/unknown features
-      * the features for which existence check failed'''
-    missing = []
-    failed = []
-    for line in lines:
-        if line.startswith(SKIPPED_PREFIX):
-            line = line.splitlines()[0]
-            missing.append(line[len(SKIPPED_PREFIX):])
-        elif line.startswith(FAILED_PREFIX):
-            line = line.splitlines()[0]
-            failed.append(line[len(FAILED_PREFIX):])
-
-    return missing, failed
-
-def showdiff(expected, output):
-    for line in difflib.unified_diff(expected, output,
-            "Expected output", "Test output"):
-        sys.stdout.write(line)
-
-def findprogram(program):
-    """Search PATH for a executable program"""
-    for p in os.environ.get('PATH', os.defpath).split(os.pathsep):
-        name = os.path.join(p, program)
-        if os.access(name, os.X_OK):
-            return name
-    return None
-
-def checktools():
-    # Before we go any further, check for pre-requisite tools
-    # stuff from coreutils (cat, rm, etc) are not tested
-    for p in requiredtools:
-        if os.name == 'nt':
-            p += '.exe'
-        found = findprogram(p)
-        if found:
-            vlog("# Found prerequisite", p, "at", found)
-        else:
-            print "WARNING: Did not find prerequisite tool: "+p
-
-def cleanup(options):
-    if not options.keep_tmpdir:
-        if options.verbose:
-            print "# Cleaning up HGTMP", HGTMP
-        shutil.rmtree(HGTMP, True)
-
-def usecorrectpython():
-    # some tests run python interpreter. they must use same
-    # interpreter we use or bad things will happen.
-    exedir, exename = os.path.split(sys.executable)
-    if exename == 'python':
-        path = findprogram('python')
-        if os.path.dirname(path) == exedir:
-            return
-    vlog('# Making python executable in test path use correct Python')
-    mypython = os.path.join(BINDIR, 'python')
-    try:
-        os.symlink(sys.executable, mypython)
-    except AttributeError:
-        # windows fallback
-        shutil.copyfile(sys.executable, mypython)
-        shutil.copymode(sys.executable, mypython)
-
-def installhg(options):
-    global PYTHON
-    vlog("# Performing temporary installation of HG")
-    installerrs = os.path.join("tests", "install.err")
-    pure = options.pure and "--pure" or ""
-
-    # Run installer in hg root
-    os.chdir(os.path.join(os.path.dirname(sys.argv[0]), '..'))
-    cmd = ('%s setup.py %s clean --all'
-           ' install --force --prefix="%s" --install-lib="%s"'
-           ' --install-scripts="%s" >%s 2>&1'
-           % (sys.executable, pure, INST, PYTHONDIR, BINDIR, installerrs))
-    vlog("# Running", cmd)
-    if os.system(cmd) == 0:
-        if not options.verbose:
-            os.remove(installerrs)
-    else:
-        f = open(installerrs)
-        for line in f:
-            print line,
-        f.close()
-        sys.exit(1)
-    os.chdir(TESTDIR)
-
-    os.environ["PATH"] = "%s%s%s" % (BINDIR, os.pathsep, os.environ["PATH"])
-
-    pydir = os.pathsep.join([PYTHONDIR, TESTDIR])
-    pythonpath = os.environ.get("PYTHONPATH")
-    if pythonpath:
-        pythonpath = pydir + os.pathsep + pythonpath
-    else:
-        pythonpath = pydir
-    os.environ["PYTHONPATH"] = pythonpath
-
-    usecorrectpython()
-    global hgpkg
-    hgpkg = _hgpath()
-
-    vlog("# Installing dummy diffstat")
-    f = open(os.path.join(BINDIR, 'diffstat'), 'w')
-    f.write('#!' + sys.executable + '\n'
-            'import sys\n'
-            'files = 0\n'
-            'for line in sys.stdin:\n'
-            '    if line.startswith("diff "):\n'
-            '        files += 1\n'
-            'sys.stdout.write("files patched: %d\\n" % files)\n')
-    f.close()
-    os.chmod(os.path.join(BINDIR, 'diffstat'), 0700)
-
-    if options.anycoverage:
-        vlog("# Installing coverage wrapper")
-        os.environ['COVERAGE_FILE'] = COVERAGE_FILE
-        if os.path.exists(COVERAGE_FILE):
-            os.unlink(COVERAGE_FILE)
-        # Create a wrapper script to invoke hg via coverage.py
-        os.rename(os.path.join(BINDIR, "hg"), os.path.join(BINDIR, "_hg.py"))
-        f = open(os.path.join(BINDIR, 'hg'), 'w')
-        f.write('#!' + sys.executable + '\n')
-        f.write('import sys, os; os.execv(sys.executable, [sys.executable, '
-                '"%s", "-x", "%s"] + sys.argv[1:])\n' %
-                (os.path.join(TESTDIR, 'coverage.py'),
-                 os.path.join(BINDIR, '_hg.py')))
-        f.close()
-        os.chmod(os.path.join(BINDIR, 'hg'), 0700)
-        PYTHON = '"%s" "%s" -x' % (sys.executable,
-                                   os.path.join(TESTDIR,'coverage.py'))
-
-def _hgpath():
-    cmd = '%s -c "import mercurial; print mercurial.__path__[0]"'
-    hgpath = os.popen(cmd % PYTHON)
-    path = hgpath.read().strip()
-    hgpath.close()
-    return path
-
-def outputcoverage(options):
-    vlog("# Producing coverage report")
-    omit = [BINDIR, TESTDIR, PYTHONDIR]
-    if not options.cover_stdlib:
-        # Exclude as system paths (ignoring empty strings seen on win)
-        omit += [x for x in sys.path if x != '']
-    omit = ','.join(omit)
-    os.chdir(PYTHONDIR)
-    cmd = '"%s" "%s" -i -r "--omit=%s"' % (
-        sys.executable, os.path.join(TESTDIR, 'coverage.py'), omit)
-    vlog("# Running: "+cmd)
-    os.system(cmd)
-    if options.annotate:
-        adir = os.path.join(TESTDIR, 'annotated')
-        if not os.path.isdir(adir):
-            os.mkdir(adir)
-        cmd = '"%s" "%s" -i -a "--directory=%s" "--omit=%s"' % (
-            sys.executable, os.path.join(TESTDIR, 'coverage.py'),
-            adir, omit)
-        vlog("# Running: "+cmd)
-        os.system(cmd)
-
-class Timeout(Exception):
-    pass
-
-def alarmed(signum, frame):
-    raise Timeout
-
-def run(cmd, options):
-    """Run command in a sub-process, capturing the output (stdout and stderr).
-    Return the exist code, and output."""
-    # TODO: Use subprocess.Popen if we're running on Python 2.4
-    if os.name == 'nt' or sys.platform.startswith('java'):
-        tochild, fromchild = os.popen4(cmd)
-        tochild.close()
-        output = fromchild.read()
-        ret = fromchild.close()
-        if ret == None:
-            ret = 0
-    else:
-        proc = Popen4(cmd)
-        try:
-            output = ''
-            proc.tochild.close()
-            output = proc.fromchild.read()
-            ret = proc.wait()
-            if os.WIFEXITED(ret):
-                ret = os.WEXITSTATUS(ret)
-        except Timeout:
-            vlog('# Process %d timed out - killing it' % proc.pid)
-            os.kill(proc.pid, signal.SIGTERM)
-            ret = proc.wait()
-            if ret == 0:
-                ret = signal.SIGTERM << 8
-            output += ("\n### Abort: timeout after %d seconds.\n"
-                       % options.timeout)
-    return ret, splitnewlines(output)
-
-def runone(options, test, skips, fails):
-    '''tristate output:
-    None -> skipped
-    True -> passed
-    False -> failed'''
-
-    def skip(msg):
-        if not options.verbose:
-            skips.append((test, msg))
-        else:
-            print "\nSkipping %s: %s" % (test, msg)
-        return None
-
-    def fail(msg):
-        fails.append((test, msg))
-        if not options.nodiff:
-            print "\nERROR: %s %s" % (test, msg)
-        return None
-
-    vlog("# Test", test)
-
-    # create a fresh hgrc
-    hgrc = file(HGRCPATH, 'w+')
-    hgrc.write('[ui]\n')
-    hgrc.write('slash = True\n')
-    hgrc.write('[defaults]\n')
-    hgrc.write('backout = -d "0 0"\n')
-    hgrc.write('commit = -d "0 0"\n')
-    hgrc.write('debugrawcommit = -d "0 0"\n')
-    hgrc.write('tag = -d "0 0"\n')
-    hgrc.close()
-
-    err = os.path.join(TESTDIR, test+".err")
-    ref = os.path.join(TESTDIR, test+".out")
-    testpath = os.path.join(TESTDIR, test)
-
-    if os.path.exists(err):
-        os.remove(err)       # Remove any previous output files
-
-    # Make a tmp subdirectory to work in
-    tmpd = os.path.join(HGTMP, test)
-    os.mkdir(tmpd)
-    os.chdir(tmpd)
-
-    try:
-        tf = open(testpath)
-        firstline = tf.readline().rstrip()
-        tf.close()
-    except:
-        firstline = ''
-    lctest = test.lower()
-
-    if lctest.endswith('.py') or firstline == '#!/usr/bin/env python':
-        cmd = '%s "%s"' % (PYTHON, testpath)
-    elif lctest.endswith('.bat'):
-        # do not run batch scripts on non-windows
-        if os.name != 'nt':
-            return skip("batch script")
-        # To reliably get the error code from batch files on WinXP,
-        # the "cmd /c call" prefix is needed. Grrr
-        cmd = 'cmd /c call "%s"' % testpath
-    else:
-        # do not run shell scripts on windows
-        if os.name == 'nt':
-            return skip("shell script")
-        # do not try to run non-executable programs
-        if not os.path.exists(testpath):
-            return fail("does not exist")
-        elif not os.access(testpath, os.X_OK):
-            return skip("not executable")
-        cmd = '"%s"' % testpath
-
-    if options.timeout > 0:
-        signal.alarm(options.timeout)
-
-    vlog("# Running", cmd)
-    ret, out = run(cmd, options)
-    vlog("# Ret was:", ret)
-
-    if options.timeout > 0:
-        signal.alarm(0)
-
-    mark = '.'
-
-    skipped = (ret == SKIPPED_STATUS)
-    # If reference output file exists, check test output against it
-    if os.path.exists(ref):
-        f = open(ref, "r")
-        refout = splitnewlines(f.read())
-        f.close()
-    else:
-        refout = []
-    if skipped:
-        mark = 's'
-        missing, failed = parsehghaveoutput(out)
-        if not missing:
-            missing = ['irrelevant']
-        if failed:
-            fail("hghave failed checking for %s" % failed[-1])
-            skipped = False
-        else:
-            skip(missing[-1])
-    elif out != refout:
-        mark = '!'
-        if ret:
-            fail("output changed and returned error code %d" % ret)
-        else:
-            fail("output changed")
-        if not options.nodiff:
-            showdiff(refout, out)
-        ret = 1
-    elif ret:
-        mark = '!'
-        fail("returned error code %d" % ret)
-
-    if not options.verbose:
-        sys.stdout.write(mark)
-        sys.stdout.flush()
-
-    if ret != 0 and not skipped:
-        # Save errors to a file for diagnosis
-        f = open(err, "wb")
-        for line in out:
-            f.write(line)
-        f.close()
-
-    # Kill off any leftover daemon processes
-    try:
-        fp = file(DAEMON_PIDS)
-        for line in fp:
-            try:
-                pid = int(line)
-            except ValueError:
-                continue
-            try:
-                os.kill(pid, 0)
-                vlog('# Killing daemon process %d' % pid)
-                os.kill(pid, signal.SIGTERM)
-                time.sleep(0.25)
-                os.kill(pid, 0)
-                vlog('# Daemon process %d is stuck - really killing it' % pid)
-                os.kill(pid, signal.SIGKILL)
-            except OSError, err:
-                if err.errno != errno.ESRCH:
-                    raise
-        fp.close()
-        os.unlink(DAEMON_PIDS)
-    except IOError:
-        pass
-
-    os.chdir(TESTDIR)
-    if not options.keep_tmpdir:
-        shutil.rmtree(tmpd, True)
-    if skipped:
-        return None
-    return ret == 0
-
-def runchildren(options, expecthg, tests):
-    if not options.with_hg:
-        installhg(options)
-        if hgpkg != expecthg:
-            print '# Testing unexpected mercurial: %s' % hgpkg
-
-    optcopy = dict(options.__dict__)
-    optcopy['jobs'] = 1
-    optcopy['with_hg'] = INST
-    opts = []
-    for opt, value in optcopy.iteritems():
-        name = '--' + opt.replace('_', '-')
-        if value is True:
-            opts.append(name)
-        elif value is not None:
-            opts.append(name + '=' + str(value))
-
-    tests.reverse()
-    jobs = [[] for j in xrange(options.jobs)]
-    while tests:
-        for job in jobs:
-            if not tests: break
-            job.append(tests.pop())
-    fps = {}
-    for j, job in enumerate(jobs):
-        if not job:
-            continue
-        rfd, wfd = os.pipe()
-        childopts = ['--child=%d' % wfd, '--port=%d' % (options.port + j * 3)]
-        cmdline = [PYTHON, sys.argv[0]] + opts + childopts + job
-        vlog(' '.join(cmdline))
-        fps[os.spawnvp(os.P_NOWAIT, cmdline[0], cmdline)] = os.fdopen(rfd, 'r')
-        os.close(wfd)
-    failures = 0
-    tested, skipped, failed = 0, 0, 0
-    skips = []
-    fails = []
-    while fps:
-        pid, status = os.wait()
-        fp = fps.pop(pid)
-        l = fp.read().splitlines()
-        test, skip, fail = map(int, l[:3])
-        split = -fail or len(l)
-        for s in l[3:split]:
-            skips.append(s.split(" ", 1))
-        for s in l[split:]:
-            fails.append(s.split(" ", 1))
-        tested += test
-        skipped += skip
-        failed += fail
-        vlog('pid %d exited, status %d' % (pid, status))
-        failures |= status
-    print
-    for s in skips:
-        print "Skipped %s: %s" % (s[0], s[1])
-    for s in fails:
-        print "Failed %s: %s" % (s[0], s[1])
-
-    if hgpkg != expecthg:
-        print '# Tested unexpected mercurial: %s' % hgpkg
-    print "# Ran %d tests, %d skipped, %d failed." % (
-        tested, skipped, failed)
-    sys.exit(failures != 0)
-
-def runtests(options, expecthg, tests):
-    global DAEMON_PIDS, HGRCPATH
-    DAEMON_PIDS = os.environ["DAEMON_PIDS"] = os.path.join(HGTMP, 'daemon.pids')
-    HGRCPATH = os.environ["HGRCPATH"] = os.path.join(HGTMP, '.hgrc')
-
-    try:
-        if not options.with_hg:
-            installhg(options)
-
-            if hgpkg != expecthg:
-                print '# Testing unexpected mercurial: %s' % hgpkg
-
-        if options.timeout > 0:
-            try:
-                signal.signal(signal.SIGALRM, alarmed)
-                vlog('# Running tests with %d-second timeout' %
-                     options.timeout)
-            except AttributeError:
-                print 'WARNING: cannot run tests with timeouts'
-                options.timeout = 0
-
-        tested = 0
-        failed = 0
-        skipped = 0
-
-        if options.restart:
-            orig = list(tests)
-            while tests:
-                if os.path.exists(tests[0] + ".err"):
-                    break
-                tests.pop(0)
-            if not tests:
-                print "running all tests"
-                tests = orig
-
-        skips = []
-        fails = []
-        for test in tests:
-            if options.retest and not os.path.exists(test + ".err"):
-                skipped += 1
-                continue
-            ret = runone(options, test, skips, fails)
-            if ret is None:
-                skipped += 1
-            elif not ret:
-                if options.interactive:
-                    print "Accept this change? [n] ",
-                    answer = sys.stdin.readline().strip()
-                    if answer.lower() in "y yes".split():
-                        rename(test + ".err", test + ".out")
-                        tested += 1
-                        fails.pop()
-                        continue
-                failed += 1
-                if options.first:
-                    break
-            tested += 1
-
-        if options.child:
-            fp = os.fdopen(options.child, 'w')
-            fp.write('%d\n%d\n%d\n' % (tested, skipped, failed))
-            for s in skips:
-                fp.write("%s %s\n" % s)
-            for s in fails:
-                fp.write("%s %s\n" % s)
-            fp.close()
-        else:
-            print
-            for s in skips:
-                print "Skipped %s: %s" % s
-            for s in fails:
-                print "Failed %s: %s" % s
-            if hgpkg != expecthg:
-                print '# Tested unexpected mercurial: %s' % hgpkg
-            print "# Ran %d tests, %d skipped, %d failed." % (
-                tested, skipped, failed)
-
-        if options.anycoverage:
-            outputcoverage(options)
-    except KeyboardInterrupt:
-        failed = True
-        print "\ninterrupted!"
-
-    if failed:
-        sys.exit(1)
-
-hgpkg = None
-def main():
-    (options, args) = parseargs()
-    if not options.child:
-        os.umask(022)
-
-        checktools()
-
-    # Reset some environment variables to well-known values so that
-    # the tests produce repeatable output.
-    os.environ['LANG'] = os.environ['LC_ALL'] = 'C'
-    os.environ['TZ'] = 'GMT'
-    os.environ["EMAIL"] = "Foo Bar <foo.bar@example.com>"
-    os.environ['CDPATH'] = ''
-
-    global TESTDIR, HGTMP, INST, BINDIR, PYTHONDIR, COVERAGE_FILE
-    TESTDIR = os.environ["TESTDIR"] = os.getcwd()
-    HGTMP = os.environ['HGTMP'] = os.path.realpath(tempfile.mkdtemp('', 'hgtests.',
-                                                   options.tmpdir))
-    DAEMON_PIDS = None
-    HGRCPATH = None
-
-    os.environ["HGEDITOR"] = sys.executable + ' -c "import sys; sys.exit(0)"'
-    os.environ["HGMERGE"] = "internal:merge"
-    os.environ["HGUSER"]   = "test"
-    os.environ["HGENCODING"] = "ascii"
-    os.environ["HGENCODINGMODE"] = "strict"
-    os.environ["HGPORT"] = str(options.port)
-    os.environ["HGPORT1"] = str(options.port + 1)
-    os.environ["HGPORT2"] = str(options.port + 2)
-
-    if options.with_hg:
-        INST = options.with_hg
-    else:
-        INST = os.path.join(HGTMP, "install")
-    BINDIR = os.environ["BINDIR"] = os.path.join(INST, "bin")
-    PYTHONDIR = os.path.join(INST, "lib", "python")
-    COVERAGE_FILE = os.path.join(TESTDIR, ".coverage")
-
-    expecthg = os.path.join(HGTMP, 'install', 'lib', 'python', 'mercurial')
-
-    if len(args) == 0:
-        args = os.listdir(".")
-        args.sort()
-
-    tests = []
-    for test in args:
-        if (test.startswith("test-") and '~' not in test and
-            ('.' not in test or test.endswith('.py') or
-             test.endswith('.bat'))):
-            tests.append(test)
-
-    vlog("# Using TESTDIR", TESTDIR)
-    vlog("# Using HGTMP", HGTMP)
-
-    try:
-        if len(tests) > 1 and options.jobs > 1:
-            runchildren(options, expecthg, tests)
-        else:
-            runtests(options, expecthg, tests)
-    finally:
-        cleanup(options)
-
-main()
--- a/.hgext/hggit/tests/test-empty-working-tree	Fri Aug 05 21:41:21 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,60 +0,0 @@
-#!/bin/sh
-
-# Fails for some reason, need to investigate
-# "$TESTDIR/hghave" git || exit 80
-
-# bail if the user does not have dulwich
-python -c 'import dulwich, dulwich.repo' || exit 80
-
-# bail early if the user is already running git-daemon
-echo hi | nc localhost 9418 2> /dev/null && exit 80
-
-echo "[extensions]" >> $HGRCPATH
-echo "hggit=$(echo $(dirname $(dirname $0)))/hggit" >> $HGRCPATH
-echo 'hgext.bookmarks =' >> $HGRCPATH
-
-cat >> $HGRCPATH <<EOF
-
-[bookmarks]
-track.current = True
-EOF
-
-GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
-GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
-GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0000"; export GIT_AUTHOR_DATE
-GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME
-GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL
-GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE
-
-mkdir gitrepo
-cd gitrepo
-git init | python -c "import sys; print sys.stdin.read().replace('$(dirname $(pwd))/', '')"
-
-git commit --allow-empty -m empty >/dev/null 2>/dev/null || echo "git commit error"
-
-cd ..
-mkdir gitrepo2
-cd gitrepo2
-git init --bare | python -c "import sys; print sys.stdin.read().replace('$(dirname $(pwd))/', '')"
-
-# dulwich does not presently support local git repos, workaround
-cd ..
-git daemon --base-path="$(pwd)"\
- --listen=localhost\
- --export-all\
- --pid-file=gitdaemon.pid \
- --detach --reuseaddr \
- --enable=receive-pack
-
-hg clone git://localhost/gitrepo hgrepo | grep -v '^updating'
-cd hgrepo
-hg log -r tip --template 'files: {files}\n'
-
-hg gclear
-hg push git://localhost/gitrepo2
-
-cd ../gitrepo2
-git log --pretty=medium
-
-cd ..
-kill `cat gitdaemon.pid`
--- a/.hgext/hggit/tests/test-empty-working-tree.out	Fri Aug 05 21:41:21 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,19 +0,0 @@
-Initialized empty Git repository in gitrepo/.git/
-
-Initialized empty Git repository in gitrepo2/
-
-importing Hg objects into Git
-Counting objects: 2, done.
-Total 2 (delta 0), reused 0 (delta 0)
-importing Git objects into Hg
-0 files updated, 0 files merged, 0 files removed, 0 files unresolved
-files: 
-clearing out the git cache data
-pushing to git://localhost/gitrepo2
-importing Hg objects into Git
-creating and sending data
-commit 678256865a8c85ae925bf834369264193c88f8de
-Author: test <test@example.org>
-Date:   Mon Jan 1 00:00:00 2007 +0000
-
-    empty
--- a/.hgext/hggit/tests/test-encoding	Fri Aug 05 21:41:21 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-#!/bin/sh
-
-# -*- coding: utf-8 -*-
-
-# Fails for some reason, need to investigate
-# "$TESTDIR/hghave" git || exit 80
-
-# bail if the user does not have dulwich
-python -c 'import dulwich, dulwich.repo' || exit 80
-
-# bail early if the user is already running git-daemon
-echo hi | nc localhost 9418 2>/dev/null && exit 80
-
-echo "[extensions]" >> $HGRCPATH
-echo "hggit=$(echo $(dirname $(dirname $0)))/hggit" >> $HGRCPATH
-echo 'hgext.graphlog =' >> $HGRCPATH
-echo 'hgext.bookmarks =' >> $HGRCPATH
-
-GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
-GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
-GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0000"; export GIT_AUTHOR_DATE
-GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME
-GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL
-GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE
-
-count=10
-commit()
-{
-    GIT_AUTHOR_DATE="2007-01-01 00:00:$count +0000"
-    GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
-    git commit "$@" >/dev/null || echo "git commit error"
-    count=`expr $count + 1`
-}
-
-mkdir gitrepo
-cd gitrepo
-git init | python -c "import sys; print sys.stdin.read().replace('$(dirname $(pwd))/', '')"
-
-# utf-8 encoded commit message
-echo alpha > alpha
-git add alpha
-commit -m 'add älphà'
-
-. $TESTDIR/latin-1-encoding
-
-cd ..
-mkdir gitrepo2
-cd gitrepo2
-git init --bare | python -c "import sys; print sys.stdin.read().replace('$(dirname $(pwd))/', '')"
-
-# dulwich does not presently support local git repos, workaround
-cd ..
-git daemon --base-path="$(pwd)"\
- --listen=localhost\
- --export-all\
- --pid-file=gitdaemon.pid \
- --detach --reuseaddr \
- --enable=receive-pack
-
-hg clone git://localhost/gitrepo hgrepo | grep -v '^updating'
-cd hgrepo
-
-HGENCODING=utf-8 hg log --graph --debug
-
-hg gclear
-hg push git://localhost/gitrepo2
-
-cd ../gitrepo2
-git log --pretty=medium
-
-cd ..
-kill `cat gitdaemon.pid`
--- a/.hgext/hggit/tests/test-encoding.out	Fri Aug 05 21:41:21 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,103 +0,0 @@
-Initialized empty Git repository in gitrepo/.git/
-
-Warning: commit message does not conform to UTF-8.
-You may want to amend it after fixing the message, or set the config
-variable i18n.commitencoding to the encoding your project uses.
-Warning: commit message does not conform to UTF-8.
-You may want to amend it after fixing the message, or set the config
-variable i18n.commitencoding to the encoding your project uses.
-Initialized empty Git repository in gitrepo2/
-
-importing Hg objects into Git
-Counting objects: 12, done.
-Compressing objects:  14% (1/7)   
Compressing objects:  28% (2/7)   
Compressing objects:  42% (3/7)   
Compressing objects:  57% (4/7)   
Compressing objects:  71% (5/7)   
Compressing objects:  85% (6/7)   
Compressing objects: 100% (7/7)   
Compressing objects: 100% (7/7), done.
-Total 12 (delta 1), reused 0 (delta 0)
-importing Git objects into Hg
-4 files updated, 0 files merged, 0 files removed, 0 files unresolved
-@  changeset:   3:8549ee7fe0801b2dafc06047ca6f66d36da709f5
-|  tag:         default/master
-|  tag:         master
-|  tag:         tip
-|  parent:      2:0422fbb4ec39fb69e87b94a3874ac890333de11a
-|  parent:      -1:0000000000000000000000000000000000000000
-|  manifest:    3:ea49f93388380ead5601c8fcbfa187516e7c2ed8
-|  user:        tést èncödîng <test@example.org>
-|  date:        Mon Jan 01 00:00:13 2007 +0000
-|  files+:      delta
-|  extra:       author=$ \x90\x01\x01\xe9\x91\x03\x03\x01\xe8\x91\x08\x02\x01\xf6\x91\x0c\x01\x01\xee\x91\x0f\x15
-|  extra:       branch=default
-|  extra:       committer=test <test@example.org> 1167609613 0
-|  extra:       encoding=latin-1
-|  extra:       message=\x0c\n\x90\x05\x01\xe9\x91\x07\x02\x01\xe0\x91\x0b\x01
-|  description:
-|  add déltà
-|
-|
-o  changeset:   2:0422fbb4ec39fb69e87b94a3874ac890333de11a
-|  parent:      1:9f6268bfc9eb3956c5ab8752d7b983b0ffe57115
-|  parent:      -1:0000000000000000000000000000000000000000
-|  manifest:    2:f580e7da3673c137370da2b931a1dee83590d7b4
-|  user:        tést èncödîng <test@example.org>
-|  date:        Mon Jan 01 00:00:12 2007 +0000
-|  files+:      gamma
-|  extra:       author=$ \x90\x01\x01\xe9\x91\x03\x03\x01\xe8\x91\x08\x02\x01\xf6\x91\x0c\x01\x01\xee\x91\x0f\x15
-|  extra:       branch=default
-|  extra:       committer=test <test@example.org> 1167609612 0
-|  extra:       message=\x0c\n\x90\x05\x01\xe4\x91\x07\x02\x01\xe2\x91\x0b\x01
-|  description:
-|  add gämmâ
-|
-|
-o  changeset:   1:9f6268bfc9eb3956c5ab8752d7b983b0ffe57115
-|  parent:      0:bb7d36568d6188ce0de2392246c43f6f213df954
-|  parent:      -1:0000000000000000000000000000000000000000
-|  manifest:    1:f0bd6fbafbaebe4bb59c35108428f6fce152431d
-|  user:        tést èncödîng <test@example.org>
-|  date:        Mon Jan 01 00:00:11 2007 +0000
-|  files+:      beta
-|  extra:       author=$ \x90\x01\x01\xe9\x91\x03\x03\x01\xe8\x91\x08\x02\x01\xf6\x91\x0c\x01\x01\xee\x91\x0f\x15
-|  extra:       branch=default
-|  extra:       committer=test <test@example.org> 1167609611 0
-|  description:
-|  add beta
-|
-|
-o  changeset:   0:bb7d36568d6188ce0de2392246c43f6f213df954
-   parent:      -1:0000000000000000000000000000000000000000
-   parent:      -1:0000000000000000000000000000000000000000
-   manifest:    0:8b8a0e87dfd7a0706c0524afa8ba67e20544cbf0
-   user:        test <test@example.org>
-   date:        Mon Jan 01 00:00:10 2007 +0000
-   files+:      alpha
-   extra:       branch=default
-   description:
-   add älphà
-
-
-clearing out the git cache data
-pushing to git://localhost/gitrepo2
-importing Hg objects into Git
-creating and sending data
-commit da0edb01d4f3d1abf08b1be298379b0b2960e680
-Author: tst ncdng <test@example.org>
-Date:   Mon Jan 1 00:00:13 2007 +0000
-
-    add dlt
-
-commit 2372b6c8f1b91f2db8ae5eb0f9e0427c318b449c
-Author: tst ncdng <test@example.org>
-Date:   Mon Jan 1 00:00:12 2007 +0000
-
-    add gmm
-
-commit 9ef7f6dcffe643b89ba63f3323621b9a923e4802
-Author: tst ncdng <test@example.org>
-Date:   Mon Jan 1 00:00:11 2007 +0000
-
-    add beta
-
-commit 0530b75d8c203e10dc934292a6a4032c6e958a83
-Author: test <test@example.org>
-Date:   Mon Jan 1 00:00:10 2007 +0000
-
-    add älphà
--- a/.hgext/hggit/tests/test-file-removal	Fri Aug 05 21:41:21 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,86 +0,0 @@
-#!/bin/sh
-
-# Fails for some reason, need to investigate
-# "$TESTDIR/hghave" git || exit 80
-
-# bail if the user does not have dulwich
-python -c 'import dulwich, dulwich.repo' || exit 80
-
-# bail early if the user is already running git-daemon
-echo hi | nc localhost 9418 2>/dev/null && exit 80
-
-echo "[extensions]" >> $HGRCPATH
-echo "hggit=$(echo $(dirname $(dirname $0)))/hggit" >> $HGRCPATH
-echo 'hgext.graphlog =' >> $HGRCPATH
-echo 'hgext.bookmarks =' >> $HGRCPATH
-
-GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
-GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
-GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0000"; export GIT_AUTHOR_DATE
-GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME
-GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL
-GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE
-
-count=10
-commit()
-{
-    GIT_AUTHOR_DATE="2007-01-01 00:00:$count +0000"
-    GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
-    git commit "$@" >/dev/null 2>/dev/null || echo "git commit error"
-    count=`expr $count + 1`
-}
-
-mkdir gitrepo
-cd gitrepo
-git init | python -c "import sys; print sys.stdin.read().replace('$(dirname $(pwd))/', '')"
-echo alpha > alpha
-git add alpha
-commit -m 'add alpha'
-echo beta > beta
-git add beta
-commit -m 'add beta'
-mkdir foo
-echo blah > foo/bar
-git add foo
-commit -m 'add foo'
-git rm alpha
-commit -m 'remove alpha'
-git rm foo/bar
-commit -m 'remove foo/bar'
-echo % final manifest in git is just beta
-git ls-files
-
-cd ..
-mkdir gitrepo2
-cd gitrepo2
-git init --bare | python -c "import sys; print sys.stdin.read().replace('$(dirname $(pwd))/', '')"
-
-# dulwich does not presently support local git repos, workaround
-cd ..
-git daemon --base-path="$(pwd)"\
- --listen=localhost\
- --export-all\
- --pid-file=gitdaemon.pid \
- --detach --reuseaddr \
- --enable=receive-pack
-
-hg clone git://localhost/gitrepo hgrepo | grep -v '^updating'
-cd hgrepo
-hg log --graph
-
-echo
-echo % make sure alpha is not in this manifest
-hg manifest -r 3
-
-echo
-echo % make sure that only beta is in the manifest
-hg manifest
-
-hg gclear
-hg push git://localhost/gitrepo2
-
-cd ../gitrepo2
-git log --pretty=medium
-
-cd ..
-kill `cat gitdaemon.pid`
--- a/.hgext/hggit/tests/test-file-removal.out	Fri Aug 05 21:41:21 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,82 +0,0 @@
-Initialized empty Git repository in gitrepo/.git/
-
-rm 'alpha'
-rm 'foo/bar'
-% final manifest in git is just beta
-beta
-Initialized empty Git repository in gitrepo2/
-
-importing Hg objects into Git
-Counting objects: 14, done.
-Compressing objects:  12% (1/8)   
Compressing objects:  25% (2/8)   
Compressing objects:  37% (3/8)   
Compressing objects:  50% (4/8)   
Compressing objects:  62% (5/8)   
Compressing objects:  75% (6/8)   
Compressing objects:  87% (7/8)   
Compressing objects: 100% (8/8)   
Compressing objects: 100% (8/8), done.
-Total 14 (delta 1), reused 0 (delta 0)
-importing Git objects into Hg
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-@  changeset:   4:ea41a3f0ed10
-|  tag:         default/master
-|  tag:         master
-|  tag:         tip
-|  user:        test <test@example.org>
-|  date:        Mon Jan 01 00:00:14 2007 +0000
-|  summary:     remove foo/bar
-|
-o  changeset:   3:c84537f94bcc
-|  user:        test <test@example.org>
-|  date:        Mon Jan 01 00:00:13 2007 +0000
-|  summary:     remove alpha
-|
-o  changeset:   2:e25450e1354f
-|  user:        test <test@example.org>
-|  date:        Mon Jan 01 00:00:12 2007 +0000
-|  summary:     add foo
-|
-o  changeset:   1:7bcd915dc873
-|  user:        test <test@example.org>
-|  date:        Mon Jan 01 00:00:11 2007 +0000
-|  summary:     add beta
-|
-o  changeset:   0:3442585be8a6
-   user:        test <test@example.org>
-   date:        Mon Jan 01 00:00:10 2007 +0000
-   summary:     add alpha
-
-
-% make sure alpha is not in this manifest
-beta
-foo/bar
-
-% make sure that only beta is in the manifest
-beta
-clearing out the git cache data
-pushing to git://localhost/gitrepo2
-importing Hg objects into Git
-creating and sending data
-commit b991de8952c482a7cd51162674ffff8474862218
-Author: test <test@example.org>
-Date:   Mon Jan 1 00:00:14 2007 +0000
-
-    remove foo/bar
-
-commit b0edaf0adac19392cf2867498b983bc5192b41dd
-Author: test <test@example.org>
-Date:   Mon Jan 1 00:00:13 2007 +0000
-
-    remove alpha
-
-commit f2d0d5bfa905e12dee728b509b96cf265bb6ee43
-Author: test <test@example.org>
-Date:   Mon Jan 1 00:00:12 2007 +0000
-
-    add foo
-
-commit 9497a4ee62e16ee641860d7677cdb2589ea15554
-Author: test <test@example.org>
-Date:   Mon Jan 1 00:00:11 2007 +0000
-
-    add beta
-
-commit 7eeab2ea75ec1ac0ff3d500b5b6f8a3447dd7c03
-Author: test <test@example.org>
-Date:   Mon Jan 1 00:00:10 2007 +0000
-
-    add alpha
--- a/.hgext/hggit/tests/test-git-clone	Fri Aug 05 21:41:21 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-#!/bin/sh
-
-# Fails for some reason, need to investigate
-# "$TESTDIR/hghave" git || exit 80
-
-# bail if the user does not have dulwich
-python -c 'import dulwich, dulwich.repo' || exit 80
-
-# bail early if the user is already running git-daemon
-echo hi | nc localhost 9418 2>/dev/null && exit 80
-
-echo "[extensions]" >> $HGRCPATH
-echo "hggit=$(echo $(dirname $(dirname $0)))/hggit" >> $HGRCPATH
-echo 'hgext.graphlog =' >> $HGRCPATH
-echo 'hgext.bookmarks =' >> $HGRCPATH
-
-GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
-GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
-GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0000"; export GIT_AUTHOR_DATE
-GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME
-GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL
-GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE
-
-count=10
-commit()
-{
-    GIT_AUTHOR_DATE="2007-01-01 00:00:$count +0000"
-    GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
-    git commit "$@" >/dev/null 2>/dev/null || echo "git commit error"
-    count=`expr $count + 1`
-}
-
-mkdir gitrepo
-cd gitrepo
-git init | python -c "import sys; print sys.stdin.read().replace('$(dirname $(pwd))/', '')"
-echo alpha > alpha
-git add alpha
-commit -m 'add alpha'
-echo beta > beta
-git add beta
-commit -m 'add beta'
-
-cd ..
-
-hg clone gitrepo hgrepo | grep -v '^updating'
-cd hgrepo
-hg log --graph
-
-echo % we should have some bookmarks
-hg book
--- a/.hgext/hggit/tests/test-git-clone.out	Fri Aug 05 21:41:21 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,23 +0,0 @@
-Initialized empty Git repository in gitrepo/.git/
-
-importing Hg objects into Git
-Counting objects: 6, done.
-Compressing objects:  33% (1/3)   
Compressing objects:  66% (2/3)   
Compressing objects: 100% (3/3)   
Compressing objects: 100% (3/3), done.
-Total 6 (delta 0), reused 0 (delta 0)
-importing Git objects into Hg
-2 files updated, 0 files merged, 0 files removed, 0 files unresolved
-@  changeset:   1:7bcd915dc873
-|  tag:         default/master
-|  tag:         master
-|  tag:         tip
-|  user:        test <test@example.org>
-|  date:        Mon Jan 01 00:00:11 2007 +0000
-|  summary:     add beta
-|
-o  changeset:   0:3442585be8a6
-   user:        test <test@example.org>
-   date:        Mon Jan 01 00:00:10 2007 +0000
-   summary:     add alpha
-
-% we should have some bookmarks
- * master                    1:7bcd915dc873
--- a/.hgext/hggit/tests/test-git-submodules	Fri Aug 05 21:41:21 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-#!/bin/sh
-
-# Fails for some reason, need to investigate
-# "$TESTDIR/hghave" git || exit 80
-
-# bail if the user does not have dulwich
-python -c 'import dulwich, dulwich.repo' || exit 80
-
-# bail early if the user is already running git-daemon
-echo hi | nc localhost 9418 2>/dev/null && exit 80
-
-echo "[extensions]" >> $HGRCPATH
-echo "hggit=$(echo $(dirname $(dirname $0)))/hggit" >> $HGRCPATH
-echo 'hgext.graphlog =' >> $HGRCPATH
-echo 'hgext.bookmarks =' >> $HGRCPATH
-
-GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
-GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
-GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0000"; export GIT_AUTHOR_DATE
-GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME
-GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL
-GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE
-
-count=10
-commit()
-{
-    GIT_AUTHOR_DATE="2007-01-01 00:00:$count +0000"
-    GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
-    git commit "$@" >/dev/null 2>/dev/null || echo "git commit error"
-    count=`expr $count + 1`
-}
-
-mkdir gitrepo1
-cd gitrepo1
-git init | python -c "import sys; print sys.stdin.read().replace('$(dirname $(pwd))/', '')"
-echo alpha > alpha
-git add alpha
-commit -m 'add alpha'
-cd ..
-
-mkdir gitsubrepo
-cd gitsubrepo
-git init | python -c "import sys; print sys.stdin.read().replace('$(dirname $(pwd))/', '')"
-echo beta > beta
-git add beta
-commit -m 'add beta'
-cd ..
-
-mkdir gitrepo2
-cd gitrepo2
-
-rmpwd="import sys; print sys.stdin.read().replace('$(dirname $(pwd))/', '')"
-# different versions of git spell the dir differently. Older versions
-# use the full path to the directory all the time, whereas newer
-# version spell it sanely as it was given (eg . in a newer version,
-# while older git will use the full normalized path for .)
-clonefilt='s/Cloning into/Initialized empty Git repository in/;s/in .*/in .../'
-
-git clone ../gitrepo1 . | python -c "$rmpwd" | sed "$clonefilt" | egrep -v '^done\.$'
-git submodule add ../gitsubrepo subrepo | python -c "$rmpwd" | sed "$clonefilt" | egrep -v '^done\.$'
-git commit -m 'add subrepo'
-git rm --cached subrepo
-git rm .gitmodules
-git commit -m 'rm subrepo'
-cd ..
-
-hg clone gitrepo2 hgrepo | grep -v '^updating'
-cd hgrepo
-hg log --graph
-
-echo % we should have some bookmarks
-hg book
--- a/.hgext/hggit/tests/test-git-submodules.out	Fri Aug 05 21:41:21 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,44 +0,0 @@
-Initialized empty Git repository in gitrepo1/.git/
-
-Initialized empty Git repository in gitsubrepo/.git/
-
-Initialized empty Git repository in ...
-
-Initialized empty Git repository in ...
-
-[master e42b08b] add subrepo
- 2 files changed, 4 insertions(+), 0 deletions(-)
- create mode 100644 .gitmodules
- create mode 160000 subrepo
-rm 'subrepo'
-rm '.gitmodules'
-[master 7e4c934] rm subrepo
- 2 files changed, 0 insertions(+), 4 deletions(-)
- delete mode 100644 .gitmodules
- delete mode 160000 subrepo
-importing Hg objects into Git
-Counting objects: 7, done.
-Compressing objects:  20% (1/5)   
Compressing objects:  40% (2/5)   
Compressing objects:  60% (3/5)   
Compressing objects:  80% (4/5)   
Compressing objects: 100% (5/5)   
Compressing objects: 100% (5/5), done.
-Total 7 (delta 1), reused 0 (delta 0)
-importing Git objects into Hg
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-@  changeset:   2:954cdf1c8c82
-|  tag:         default/master
-|  tag:         master
-|  tag:         tip
-|  user:        test <test@example.org>
-|  date:        Mon Jan 01 00:00:11 2007 +0000
-|  summary:     rm subrepo
-|
-o  changeset:   1:145121c71064
-|  user:        test <test@example.org>
-|  date:        Mon Jan 01 00:00:11 2007 +0000
-|  summary:     add subrepo
-|
-o  changeset:   0:3442585be8a6
-   user:        test <test@example.org>
-   date:        Mon Jan 01 00:00:10 2007 +0000
-   summary:     add alpha
-
-% we should have some bookmarks
- * master                    2:954cdf1c8c82
--- a/.hgext/hggit/tests/test-git-tags	Fri Aug 05 21:41:21 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,72 +0,0 @@
-#!/bin/sh
-
-# Fails for some reason, need to investigate
-# "$TESTDIR/hghave" git || exit 80
-
-# bail if the user does not have dulwich
-python -c 'import dulwich, dulwich.repo' || exit 80
-
-# bail early if the user is already running git-daemon
-echo hi | nc localhost 9418 2>/dev/null && exit 80
-
-echo "[extensions]" >> $HGRCPATH
-echo "hggit=$(echo $(dirname $(dirname $0)))/hggit" >> $HGRCPATH
-echo 'hgext.graphlog =' >> $HGRCPATH
-echo 'hgext.bookmarks =' >> $HGRCPATH
-
-GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
-GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
-GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0000"; export GIT_AUTHOR_DATE
-GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME
-GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL
-GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE
-
-count=10
-commit()
-{
-    GIT_AUTHOR_DATE="2007-01-01 00:00:$count +0000"
-    GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
-    git commit "$@" >/dev/null 2>/dev/null || echo "git commit error"
-    count=`expr $count + 1`
-}
-tag()
-{
-    GIT_AUTHOR_DATE="2007-01-01 00:00:$count +0000"
-    GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
-    git tag "$@" >/dev/null 2>/dev/null || echo "git commit error"
-    count=`expr $count + 1`
-}
-
-mkdir gitrepo
-cd gitrepo
-git init | python -c "import sys; print sys.stdin.read().replace('$(dirname $(pwd))/', '')"
-git config receive.denyCurrentBranch ignore
-echo alpha > alpha
-git add alpha
-commit -m 'add alpha'
-tag alpha
-
-echo beta > beta
-git add beta
-commit -m 'add beta'
-tag -a -m 'added tag beta' beta
-
-# dulwich does not presently support local git repos, workaround
-cd ..
-git daemon --base-path="$(pwd)"\
- --listen=localhost\
- --export-all\
- --pid-file=gitdaemon.pid \
- --detach --reuseaddr \
- --enable=receive-pack
-
-hg clone git://localhost/gitrepo hgrepo | grep -v '^updating'
-
-cd hgrepo
-hg log --graph
-echo beta-fix >> beta
-hg commit -m 'fix for beta'
-hg push
-
-cd ..
-kill `cat gitdaemon.pid`
--- a/.hgext/hggit/tests/test-git-tags.out	Fri Aug 05 21:41:21 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,29 +0,0 @@
-Initialized empty Git repository in gitrepo/.git/
-
-importing Hg objects into Git
-Counting objects: 7, done.
-Compressing objects:  25% (1/4)   
Compressing objects:  50% (2/4)   
Compressing objects:  75% (3/4)   
Compressing objects: 100% (4/4)   
Compressing objects: 100% (4/4), done.
-Total 7 (delta 0), reused 0 (delta 0)
-importing Git objects into Hg
-2 files updated, 0 files merged, 0 files removed, 0 files unresolved
-@  changeset:   1:99dcc15b7b07
-|  tag:         beta
-|  tag:         default/master
-|  tag:         master
-|  tag:         tip
-|  user:        test <test@example.org>
-|  date:        Mon Jan 01 00:00:12 2007 +0000
-|  summary:     add beta
-|
-o  changeset:   0:3442585be8a6
-   tag:         alpha
-   user:        test <test@example.org>
-   date:        Mon Jan 01 00:00:10 2007 +0000
-   summary:     add alpha
-
-pushing to git://localhost/gitrepo
-importing Hg objects into Git
-creating and sending data
-    default::refs/tags/beta => GIT:e6f255c6
-    default::refs/tags/alpha => GIT:7eeab2ea
-    default::refs/heads/master => GIT:3b7fd1b3
--- a/.hgext/hggit/tests/test-git-workflow	Fri Aug 05 21:41:21 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,68 +0,0 @@
-#!/bin/sh
-
-# Fails for some reason, need to investigate
-# "$TESTDIR/hghave" git || exit 80
-
-# bail if the user does not have dulwich
-python -c 'import dulwich, dulwich.repo' || exit 80
-
-# bail early if the user is already running git-daemon
-echo hi | nc localhost 9418 2>/dev/null && exit 80
-
-echo "[extensions]" >> $HGRCPATH
-echo "hggit=$(echo $(dirname $(dirname $0)))/hggit" >> $HGRCPATH
-echo 'hgext.graphlog =' >> $HGRCPATH
-echo 'hgext.bookmarks =' >> $HGRCPATH
-
-GIT_AUTHOR_NAME='test'; export GIT_AUTHOR_NAME
-GIT_AUTHOR_EMAIL='test@example.org'; export GIT_AUTHOR_EMAIL
-GIT_AUTHOR_DATE="2007-01-01 00:00:00 +0000"; export GIT_AUTHOR_DATE
-GIT_COMMITTER_NAME="$GIT_AUTHOR_NAME"; export GIT_COMMITTER_NAME
-GIT_COMMITTER_EMAIL="$GIT_AUTHOR_EMAIL"; export GIT_COMMITTER_EMAIL
-GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"; export GIT_COMMITTER_DATE
-
-count=10
-commit()
-{
-    GIT_AUTHOR_DATE="2007-01-01 00:00:$count +0000"
-    GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE"
-    git commit "$@" >/dev/null 2>/dev/null || echo "git commit error"
-    count=`expr $count + 1`
-}
-hgcommit()
-{
-    HGDATE="2007-01-01 00:00:$count +0000"
-    hg commit -d "$HGDATE" "$@" >/dev/null 2>/dev/null || echo "hg commit error"
-    count=`expr $count + 1`
-}
-
-mkdir hgrepo
-cd hgrepo
-hg init
-
-echo alpha > alpha
-hg add alpha
-hgcommit -m "add alpha"
-hg glog --debug
-
-cd ..
-
-echo % configure for use from git
-hg clone hgrepo gitrepo
-cd gitrepo
-hg book master
-hg up null
-echo "[git]" >> .hg/hgrc
-echo "intree = True" >> .hg/hgrc
-hg gexport
-
-echo % do some work
-git config core.bare false
-git checkout master 2>&1 | sed s/\'/\"/g
-echo beta > beta
-git add beta
-commit -m 'add beta'
-
-echo % get things back to hg
-hg gimport
-hg glog --debug
--- a/.hgext/hggit/tests/test-git-workflow.out	Fri Aug 05 21:41:21 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-@  changeset:   0:0221c246a56712c6aa64e5ee382244d8a471b1e2
-   tag:         tip
-   parent:      -1:0000000000000000000000000000000000000000
-   parent:      -1:0000000000000000000000000000000000000000
-   manifest:    0:8b8a0e87dfd7a0706c0524afa8ba67e20544cbf0
-   user:        test
-   date:        Mon Jan 01 00:00:10 2007 +0000
-   files+:      alpha
-   extra:       branch=default
-   description:
-   add alpha
-
-
-% configure for use from git
-updating to branch default
-1 files updated, 0 files merged, 0 files removed, 0 files unresolved
-0 files updated, 0 files merged, 1 files removed, 0 files unresolved
-importing Hg objects into Git
-% do some work
-Already on "master"
-% get things back to hg
-importing Git objects into Hg
-o  changeset:   1:7108ae7bd184226a29b8203619a8253d314643bf
-|  tag:         master
-|  tag:         tip
-|  parent:      0:0221c246a56712c6aa64e5ee382244d8a471b1e2
-|  parent:      -1:0000000000000000000000000000000000000000
-|  manifest:    1:f0bd6fbafbaebe4bb59c35108428f6fce152431d
-|  user:        test <test@example.org>
-|  date:        Mon Jan 01 00:00:11 2007 +0000
-|  files+:      beta
-|  extra:       branch=default
-|  description:
-|  add beta
-|
-|
-o  changeset:   0:0221c246a56712c6aa64e5ee382244d8a471b1e2
-   parent:      -1:0000000000000000000000000000000000000000
-   parent:      -1:0000000000000000000000000000000000000000
-   manifest:    0:8b8a0e87dfd7a0706c0524afa8ba67e20544cbf0
-   user:        test
-   date:        Mon Jan 01 00:00:10 2007 +0000
-   files+:      alpha
-   extra:       branch=default
-   description:
-   add alpha
-
-
--- a/.hgext/hggit/tests/test-hg-author	Fri Aug 05 21:41:21 2011 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,85 +0,0 @@
-#!/bin/sh
-
-# Fails for some reason, need to investigate
-# "$TESTDIR/hghave" git || exit 80
-
-# bail if the user does not have dulwich
-python -c 'import dulwich, dulwich.repo' || exit 80
-
-# bail early if the user is already running git-daemon
-echo hi | nc localhost 9418 2>/dev/null && exit 80
-
-echo "[extensions]" >> $HGRCPATH