diff --git a/eden/mononoke/tests/integration/test-gitimport-committer.t b/eden/mononoke/tests/integration/test-gitimport-committer.t index cf36ed7580..aa524ac5d7 100644 --- a/eden/mononoke/tests/integration/test-gitimport-committer.t +++ b/eden/mononoke/tests/integration/test-gitimport-committer.t @@ -104,17 +104,3 @@ $ hg log -r another_committer -T '{extras}' branch=defaultcommitter=second_committer 1000000000 0 (no-eol) -# Push to a git repo and check that we have correct committer there - $ hg pull --config extensions.hggit= "$TESTTMP/repo-git-clone" - pulling from $TESTTMP/repo-git-clone - importing git objects into hg - $ hgmn push --config extensions.hggit= -r another_committer "$TESTTMP/repo-git-clone" --debug -f &> /dev/null - $ cd "$TESTTMP/repo-git-clone" - $ git log another_committer --pretty=fuller - commit a1368bfa4ec1c5478d03385b567ea2a8541ee566 - Author: mononoke - AuthorDate: Sat Jan 1 00:00:00 2000 +0000 - Commit: second_committer - CommitDate: Sun Sep 9 01:46:40 2001 +0000 - - Add file1 diff --git a/eden/mononoke/tests/integration/test-gitimport.t b/eden/mononoke/tests/integration/test-gitimport.t index d38d4765dd..912be0ce76 100644 --- a/eden/mononoke/tests/integration/test-gitimport.t +++ b/eden/mononoke/tests/integration/test-gitimport.t @@ -84,7 +84,3 @@ $ cat "file2" this is file2 -# Try out hggit compatibility - $ hg --config extensions.hggit= git-updatemeta - $ hg --config extensions.hggit= log -T '{gitnode}' - 8ce3eae44760b500bf3f2c3922a95dcd3c908e9e (no-eol) diff --git a/eden/scm/contrib/fix-code.py b/eden/scm/contrib/fix-code.py index 2f46311e06..1d9e0828f6 100755 --- a/eden/scm/contrib/fix-code.py +++ b/eden/scm/contrib/fix-code.py @@ -68,7 +68,6 @@ def ispathskipped(path): for name in [ "contrib", "doc", - "hggit", "newdoc", "pywatchman", # Part of "tests" are hg-git code. diff --git a/eden/scm/doc/hggit/CONTRIBUTING b/eden/scm/doc/hggit/CONTRIBUTING deleted file mode 100644 index e1aa89e098..0000000000 --- a/eden/scm/doc/hggit/CONTRIBUTING +++ /dev/null @@ -1,28 +0,0 @@ -The short version: - * Patches should have a good summary line for first line of commit message - * Patches should be sent to the Google Group[0] - * Patch needs to do exactly one thing - * testsuite passes - -The longer version: - -We use a variant of Mercurial's own contribution -system. https://www.mercurial-scm.org/wiki/ContributingChanges contains -their full guidelines. Key differences are (by rule number): - - 1. For hg-git, I'm not strict about the "topic: a few words" format - for the first line, but I do insist on a sensible summary as the - first line of your commit - 2. We don't require use of issueNNN for bug fixes (we have no robot) - 3. Use the hg-git google group - 10. We use mostly pep8 style. The current codebase is a mess, but new - code should be basically pep8. - -0: -Mailing list: hg-git@googlegroups.com -Archives: https://groups.google.com/forum/#!forum/hg-git - -Pull requests are generally not noticed more than once every few -months. If you do a pull request, I'm still going to expect you to -have a clean history, and to be willing to rework history so it's -clean before I push the "merge" button. diff --git a/eden/scm/doc/hggit/COPYING b/eden/scm/doc/hggit/COPYING deleted file mode 100644 index d159169d10..0000000000 --- a/eden/scm/doc/hggit/COPYING +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 Lesser 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. - - - Copyright (C) - - 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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. - - , 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 Lesser General -Public License instead of this License. diff --git a/eden/scm/doc/hggit/DESIGN.txt b/eden/scm/doc/hggit/DESIGN.txt deleted file mode 100644 index c0875fdcb9..0000000000 --- a/eden/scm/doc/hggit/DESIGN.txt +++ /dev/null @@ -1,65 +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. diff --git a/eden/scm/doc/hggit/README.md b/eden/scm/doc/hggit/README.md deleted file mode 100644 index 60fd3d59b5..0000000000 --- a/eden/scm/doc/hggit/README.md +++ /dev/null @@ -1,280 +0,0 @@ -Hg-Git Mercurial Plugin -======================= - -* Homepage: http://hg-git.github.com/ -* https://bitbucket.org/durin42/hg-git (primary) -* https://github.com/schacon/hg-git (mirror) - -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. See the -Makefile for information about which versions of Mercurial are -known to work, and setup.py for which versions of Dulwich are required. - -Usage -===== - -You can clone a Git repository from Hg by running `hg clone [dest]`. For -example, if you were to run - - $ hg clone git://github.com/schacon/hg-git.git - -Hg-Git would clone the repository and 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 set up -a Git repository somewhere that you have push access to, add a path entry -for it in your .hg/hgrc file, and then run `hg push [name]` from within -your repository. 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 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. You can use -a local repository or a remote repository accessed via SSH, HTTP or HTTPS. Use -the following commands to convert the repository (it assumes you're running this -in $HOME). - - $ mkdir git-repo; cd git-repo; git init; cd .. - $ cd hg-repo - $ hg bookmarks hg - $ hg push ../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 -======== - -See `hg help -e hggit`. - -Hg Bookmarks Integration -======================== - -Hg-Git pushes your bookmarks up to the Git server as branches and will -pull Git branches down and set them up as bookmarks. - -Installing -========== - -Clone this repository somewhere and make the 'extensions' section in -your `~/.hgrc` file look something like this: - - [extensions] - hggit = [path-to]/hg-git/hggit - -That will enable the Hg-Git extension for you. - -See the Makefile for a list of compatible Mercurial versions. - -Configuration -============= - -git.authors ------------ - -Git uses a strict convention for "author names" when representing changesets, -using the form `[realname] [email address]`. Mercurial encourages this -convention as well but is not as strict, so it's not uncommon for a Mercurial -repo to have authors listed as, for example, simple usernames. hg-git by default -will attempt to translate Mercurial usernames using the following rules: - -* If the Mercurial username fits the pattern `NAME `, the git name will be - set to NAME and the email to EMAIL. -* If the Mercurial username looks like an email (if it contains an `@`), the - git name and email will both be set to that email. -* If the Mercurial username consists of only a name, the email will be set to `none@none`. -* Illegal characters (stray `<`s or `>`s) will be stripped out, and for `NAME ` - usernames, any content after the right-bracket (for example, a second `>`) will be - turned into a url-encoded sigil like `ext:(%3E)` in the git author name. - -Since these default behaviors may not be what you want (`none@none`, for example, -shows up unpleasantly on Github as "illegal email address"), the `git.authors` -option provides for an "authors translation file" that will be used during outgoing -transfers from mercurial to git only, by modifying `hgrc` as such: - - [git] - authors = authors.txt - -Where `authors.txt` is the name of a text file containing author name translations, -one per each line, using the following format: - - johnny = John Smith - dougie = Doug Johnson - -Empty lines and lines starting with a "#" are ignored. - -It should be noted that **this translation is on the hg->git side only**. Changesets -coming from Git back to Mercurial will not translate back into hg usernames, so -it's best that the same username/email combination be used on both the hg and git sides; -the author file is mostly useful for translating legacy changesets. - -git.blockdotgit ---------------- - -Blocks exporting revisions to Git that contain a directory named .git or any -letter-case variation thereof. This prevents creating repositories that newer -versions of Git and many Git hosting services block due to security -concerns. Defaults to True. - -git.blockdothg --------------- - -Blocks importing revisions from Git that contain a directory named .hg. Defaults -to True. - -git.branch_bookmark_suffix ---------------------------- - -hg-git does not convert between Mercurial named branches and git branches as -the two are conceptually different; instead, it uses Mercurial bookmarks to -represent the concept of a git branch. Therefore, when translating an hg repo -over to git, you typically need to create bookmarks to mirror all the named -branches that you'd like to see transferred over to git. The major caveat with -this is that you can't use the same name for your bookmark as that of the -named branch, and furthermore there's no feasible way to rename a branch in -Mercurial. For the use case where one would like to transfer an hg repo over -to git, and maintain the same named branches as are present on the hg side, -the `branch_bookmark_suffix` might be all that's needed. This presents a -string "suffix" that will be recognized on each bookmark name, and stripped -off as the bookmark is translated to a git branch: - - [git] - branch_bookmark_suffix=_bookmark - -Above, if an hg repo had a named branch called `release_6_maintenance`, you could -then link it to a bookmark called `release_6_maintenance_bookmark`. hg-git will then -strip off the `_bookmark` suffix from this bookmark name, and create a git branch -called `release_6_maintenance`. When pulling back from git to hg, the `_bookmark` -suffix is then applied back, if and only if an hg named branch of that name exists. -E.g., when changes to the `release_6_maintenance` branch are checked into git, these -will be placed into the `release_6_maintenance_bookmark` bookmark on hg. But if a -new branch called `release_7_maintenance` were pulled over to hg, and there was -not a `release_7_maintenance` named branch already, the bookmark will be named -`release_7_maintenance` with no usage of the suffix. - -The `branch_bookmark_suffix` option is, like the `authors` option, intended for -migrating legacy hg named branches. Going forward, an hg repo that is to -be linked with a git repo should only use bookmarks for named branching. - -git.findcopiesharder --------------------- - -Whether to consider unmodified files as copy sources. This is a very expensive -operation for large projects, so use it with caution. Similar to `git diff`'s ---find-copies-harder option. - -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 - -git.mindate ------------ - -If set, branches where the latest commit's commit time is older than this will -not be imported. Accepts any date formats that Mercurial does -- see -`hg help dates` for more. - -git.public ----------- - -A list of Git branches that should be considered "published", and therefore -converted to Mercurial in the 'public' phase. This is only used if -hggit.usephases is set. - -git.renamelimit ---------------- - -The number of files to consider when performing the copy/rename detection. -Detection is disabled if the number of files modified in a commit is above the -limit. Detection is O(N^2) in the number of files modified, so be sure not to -set the limit too high. Similar to Git's `diff.renameLimit` config. The default -is "400", the same as Git. - -git.similarity --------------- - -Specify how similar files modified in a Git commit must be to be imported as -Mercurial renames or copies, as a percentage between "0" (disabled) and "100" -(files must be identical). For example, "90" means that a delete/add pair will -be imported as a rename if more than 90% of the file has stayed the same. The -default is "0" (disabled). - -hggit.mapsavefrequency ----------------------- - -Controls how often the mapping between Git and Mercurial commit hashes gets -saved when importing or exporting changesets. Set this to a number greater than -0 to save the mapping after converting that many commits. This can help when the -conversion encounters an error partway through a large batch of -changes. Defaults to 0, so that the mapping is saved once at the end. - -hggit.usephases ---------------- - -When converting Git revisions to Mercurial, place them in the 'public' phase as -appropriate. Namely, revisions that are reachable from the remote Git -repository's HEAD will be marked 'public'. For most repositories, this means the -remote 'master' will be converted as public. This speeds up some local Mercurial -operations including `hg shelve`. diff --git a/eden/scm/doc/hggit/TODO.txt b/eden/scm/doc/hggit/TODO.txt deleted file mode 100644 index 5ef5fa6481..0000000000 --- a/eden/scm/doc/hggit/TODO.txt +++ /dev/null @@ -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?) diff --git a/eden/scm/edenscm/hgext/hggit/__init__.py b/eden/scm/edenscm/hgext/hggit/__init__.py deleted file mode 100644 index 9e102b7856..0000000000 --- a/eden/scm/edenscm/hgext/hggit/__init__.py +++ /dev/null @@ -1,538 +0,0 @@ -# git.py - git server bridge -# -# Copyright 2008 Scott Chacon -# 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:// - -For more information and instructions, see :hg:`help git` -""" - -# global modules -import os -import shutil -import sys -import warnings -from bisect import insort - -from bindings import nodemap as nodemapmod -from edenscm.mercurial import ( - bundlerepo, - cmdutil, - demandimport, - discovery, - extensions, - help, - hg, - localrepo, - manifest, - phases, - pycompat, - revset, - scmutil, - templatekw, - ui as hgui, - util as hgutil, -) -from edenscm.mercurial.error import LookupError -from edenscm.mercurial.i18n import _ -from edenscm.mercurial.node import hex, nullid - -# local modules -from . import compat, gitrepo, hgrepo, overlay, util, verify -from .git_handler import GitHandler - - -# Disable DeprecationWarning from newer dulwich since hggit also supports older -# dulwich. -warnings.filterwarnings(r"ignore", r"", DeprecationWarning, r"edenscm.hgext.hggit") -warnings.filterwarnings( - r"ignore", r"", DeprecationWarning, r"edenscm.mercurial.pycompat" -) - -try: - from edenscm.mercurial import exchange - - exchange.push # existed in first iteration of this file -except (AttributeError, ImportError): - # We only *use* the exchange module in hg 3.2+, so this is safe - pass - -try: - # pyre-fixme[21]: Could not find name `ignore` in `edenscm.mercurial`. - from edenscm.mercurial import ignore - - # pyre-fixme[16]: Module `mercurial` has no attribute `ignore`. - ignore.readpats - ignoremod = True -except (AttributeError, ImportError): - # The ignore module disappeared in Mercurial 3.5 - ignoremod = False - -baseset = set -try: - baseset = revset.baseset -except AttributeError: - # baseset was added in hg 3.0 - pass - -demandimport.ignore.extend(["collections"]) - -__version__ = "0.8.10" - -testedwith = ( - "2.8.2 2.9.2 3.0.2 3.1.2 3.2.4 3.3.3 3.4.2 3.5.2 3.6.3 3.7.3" - "3.8.4 3.9.2 4.0.2 4.1.3 4.2.3 4.3.3 4.4" -) -buglink = "https://bitbucket.org/durin42/hg-git/issues" - -cmdtable = {} -configtable = {} -try: - from edenscm.mercurial import registrar - - command = registrar.command(cmdtable) - configitem = registrar.configitem(configtable) - compat.registerconfigs(configitem) - -except (ImportError, AttributeError): - command = cmdutil.command(cmdtable) - -# support for `hg clone git://github.com/defunkt/facebox.git` -# also hg clone git+ssh://git@github.com/schacon/simplegit.git -for _scheme in util.gitschemes: - hg.schemes[_scheme] = 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 _isgitdir(path): - """True if the given file path is a git repo.""" - if os.path.exists(os.path.join(path, ".hg")): - return False - - if os.path.exists(os.path.join(path, ".git")): - # is full git repo - return True - - if ( - os.path.exists(os.path.join(path, "HEAD")) - and os.path.exists(os.path.join(path, "objects")) - and os.path.exists(os.path.join(path, "refs")) - ): - # is bare git repo - return True - - return False - - -def _local(path): - p = urlcls(path).localpath() - if _isgitdir(p): - return gitrepo - # detect git ssh urls (which mercurial thinks is a file-like path) - if util.isgitsshuri(p): - return gitrepo - return _oldlocal(path) - - -hg.schemes["file"] = _local - -# we need to wrap this so that git-like ssh paths are not prepended with a -# local filesystem path. ugh. -def _url(orig, path, **kwargs): - # we'll test for 'git@' then use our heuristic method to determine if it's - # a git uri - if not (path.startswith(pycompat.ossep) and ":" in path): - return orig(path, **kwargs) - - # the file path will be everything up until the last slash right before the - # ':' - lastsep = path.rindex(pycompat.ossep, None, path.index(":")) + 1 - gituri = path[lastsep:] - - if util.isgitsshuri(gituri): - return orig(gituri, **kwargs) - return orig(path, **kwargs) - - -extensions.wrapfunction(hgutil, "url", _url) - - -hgdefaultdest = hg.defaultdest - - -def defaultdest(source): - for scheme in util.gitschemes: - if source.startswith("%s://" % scheme) and source.endswith(".git"): - return hgdefaultdest(source[:-4]) - - if source.endswith(".git"): - return hgdefaultdest(source[:-4]) - - return hgdefaultdest(source) - - -hg.defaultdest = defaultdest - - -def getversion(): - """return version with dependencies for hg --version -v""" - import dulwich - - dulver = ".".join(str(i) for i in dulwich.__version__) - return __version__ + (" (dulwich %s)" % dulver) - - -# 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 ( - isinstance(co, int) - and hgutil.safehasattr(lrepo, "changelog") - and co not in lrepo.changelog - ): - co = None - return revs, co - - -if getattr(hg, "addbranchrevs", False): - extensions.wrapfunction(hg, "addbranchrevs", safebranchrevs) - - -def extsetup(ui): - templatekw.keywords.update({"gitnode": gitnodekw}) - revset.symbols.update({"fromgit": revset_fromgit, "gitnode": revset_gitnode}) - helpdir = os.path.join(os.path.dirname(__file__), "help") - entry = ( - ["git"], - _("Working with Git Repositories"), - # Mercurial >= 3.6: doc(ui) - lambda *args: open(os.path.join(helpdir, "git.rst")).read(), - ) - insort(help.helptable, entry) - # Mercurial >= 3.2 - extensions.wrapfunction(exchange, "pull", exchangepull) - # Mercurial >= 3.4 - extensions.wrapfunction(manifest.manifestdict, "diff", overlay.wrapmanifestdictdiff) - - -def reposetup(ui, repo): - if not isinstance(repo, gitrepo.gitrepo): - klass = hgrepo.generate_repo_subclass(repo.__class__) - repo.__class__ = klass - - -@command("external-sync", [], _("REMOTE HEAD LIMIT")) -def externalsync(ui, repo, remote, head, limit): - limit = int(limit) - repo.ui.status( - _("importing up to %d commits from %s in %s\n") % (limit, remote, head) - ) - with repo.wlock(), repo.lock(): - refs = repo.githandler.fetch_pack(remote, [head]) - refs = repo.githandler.filter_refs(refs, [head]) - imported = repo.githandler.import_git_objects(refs, limit) - repo.ui.status(_("imported %s commits\n") % imported) - - -@command("gimport") -def gimport(ui, repo, remote_name=None): - """import commits from Git to Mercurial""" - with repo.wlock(), repo.lock(): - repo.githandler.import_commits(remote_name) - - -@command("gexport") -def gexport(ui, repo): - """export commits from Mercurial to Git""" - repo.githandler.export_commits() - - -@command("gclear") -def gclear(ui, repo): - """clear out the Git cached data - - Strips all Git-related metadata from the repo, including the mapping - between Git and Mercurial changesets. This is an irreversible - destructive operation that may prevent further interaction with - other clones. - """ - repo.ui.status(_("clearing out the git cache data\n")) - repo.githandler.clear() - - -@command( - "gverify", [("r", "rev", "", _("revision to verify"), _("REV"))], _("[-r REV]") -) -def gverify(ui, repo, **opts): - """verify that a Mercurial rev matches the corresponding Git rev - - Given a Mercurial revision that has a corresponding Git revision in the map, - this attempts to answer whether that revision has the same contents as the - corresponding Git revision. - - """ - ctx = scmutil.revsingle(repo, opts.get("rev"), ".") - return verify.verify(ui, repo, ctx) - - -@command("git-cleanup") -def git_cleanup(ui, repo): - """clean up Git commit map after history editing""" - items = repo.githandler._map.items() - if ui.configbool("hggit", "indexedlognodemap", False): - dir = repo.sharedvfs.join(repo.githandler.map_file + "-log") - tempdir = dir + ".temp" - if os.path.exists(tempdir): - hgutil.removedirs(tempdir) - - nodemap = nodemapmod.nodemap(tempdir) - for gitsha, hgsha in items: - if hgsha in repo: - nodemap.add(gitsha, hgsha) - nodemap.flush() - with repo.wlock(): - tempdir2 = dir + ".temp2" - hgutil.rename(dir, tempdir2) - hgutil.rename(tempdir, dir) - shutil.rmtree(tempdir2) - - new_map = [] - for gitsha, hgsha in items: - if hgsha in repo: - new_map.append(pycompat.encodeutf8("%s %s\n" % (hex(gitsha), hex(hgsha)))) - wlock = repo.wlock() - try: - f = repo.sharedvfs(GitHandler.map_file, "wb") - list(map(f.write, new_map)) - finally: - wlock.release() - ui.status(_("git commit map cleaned\n")) - - -@command("git-updatemeta") -def gitupdatemeta(ui, repo): - """Reads git hashes from the latest hg commits and adds them to the git-hg - mapping.""" - with repo.wlock(), repo.lock(): - stack = repo.heads() - githandler = repo.githandler - parents = repo.changelog.parents - clrev = repo.changelog.rev - clrevision = repo.changelog.changelogrevision - phase = repo._phasecache.phase - public = phases.public - - seen = set(stack) - seen.add(nullid) - while stack: - node = stack.pop() - hgsha = hex(node) - gitsha = githandler.map_git_get(hgsha) - - # If the gitsha is not already known, add it if we can - if gitsha is None: - gitsha = None - commitdata = clrevision(node) - if ( - commitdata._rawextra is not None - and b"convert_revision" in commitdata._rawextra - ): - gitsha = commitdata.extra.get("convert_revision") - - # If there is no git sha, it may be a local commit. Just walk past - # it. - if gitsha: - githandler.map_set(gitsha, hgsha) - - if gitsha or phase(repo, clrev(node)) != public: - for pnode in parents(node): - if pnode not in seen: - seen.add(pnode) - stack.append(pnode) - - githandler.save_map(githandler.map_file) - - -def findcommonoutgoing(orig, repo, other, *args, **kwargs): - if isinstance(other, gitrepo.gitrepo): - heads = repo.githandler.get_refs(other.path)[0] - kw = {} - kw.update(kwargs) - for val, k in zip(args, ("onlyheads", "force", "commoninc", "portable")): - kw[k] = val - force = kw.get("force", False) - commoninc = kw.get("commoninc", None) - if commoninc is None: - commoninc = discovery.findcommonincoming( - repo, other, heads=heads, force=force - ) - kw["commoninc"] = commoninc - return orig(repo, other, **kw) - return orig(repo, other, *args, **kwargs) - - -extensions.wrapfunction(discovery, "findcommonoutgoing", findcommonoutgoing) - - -def getremotechanges(orig, ui, repo, other, *args, **opts): - if isinstance(other, gitrepo.gitrepo): - if args: - revs = args[0] - else: - revs = opts.get("onlyheads", opts.get("revs")) - r, c, cleanup = repo.githandler.getremotechanges(other, revs) - # ugh. This is ugly even by mercurial API compatibility standards - if sys.version_info[0] >= 3: - if "onlyheads" not in orig.__code__.co_varnames: - cleanup = None - else: - if "onlyheads" not in orig.func_code.co_varnames: - cleanup = None - return r, c, cleanup - return orig(ui, repo, other, *args, **opts) - - -extensions.wrapfunction(bundlerepo, "getremotechanges", getremotechanges) - - -def peer(orig, uiorrepo, *args, **opts): - newpeer = orig(uiorrepo, *args, **opts) - if isinstance(newpeer, gitrepo.gitrepo): - if isinstance(uiorrepo, localrepo.localrepository): - newpeer.localrepo = uiorrepo - return newpeer - - -extensions.wrapfunction(hg, "peer", peer) - - -def isvalidlocalpath(orig, self, path): - return orig(self, path) or _isgitdir(path) - - -if hgutil.safehasattr(hgui, "path") and hgutil.safehasattr( - hgui.path, "_isvalidlocalpath" -): - extensions.wrapfunction(hgui.path, "_isvalidlocalpath", isvalidlocalpath) - - -@util.transform_notgit -def exchangepull(orig, repo, remote, heads=None, force=False, bookmarks=(), **kwargs): - if isinstance(remote, gitrepo.gitrepo): - # transaction manager is present in Mercurial >= 3.3 - try: - trmanager = getattr(exchange, "transactionmanager") - except AttributeError: - trmanager = None - pullop = exchange.pulloperation(repo, remote, heads, force, bookmarks=bookmarks) - if trmanager: - pullop.trmanager = trmanager(repo, "pull", remote.url()) - wlock = repo.wlock() - lock = repo.lock() - try: - pullop.cgresult = repo.githandler.fetch(remote.path, heads) - if trmanager: - pullop.trmanager.close() - else: - pullop.closetransaction() - return pullop - finally: - if trmanager: - pullop.trmanager.release() - else: - pullop.releasetransaction() - lock.release() - wlock.release() - else: - return orig(repo, remote, heads, force, bookmarks=bookmarks, **kwargs) - - -@util.transform_notgit -def exchangepush(orig, repo, remote, force=False, revs=None, bookmarks=(), **kwargs): - if isinstance(remote, gitrepo.gitrepo): - # opargs is in Mercurial >= 3.6 - opargs = kwargs.get("opargs") - if opargs is None: - opargs = {} - pushop = exchange.pushoperation(repo, remote, force, revs, bookmarks, **opargs) - pushop.cgresult = repo.githandler.push(remote.path, revs, force) - return pushop - else: - return orig(repo, remote, force, revs, bookmarks=bookmarks, **kwargs) - - -if not hgutil.safehasattr(localrepo.localrepository, "push"): - # Mercurial >= 3.2 - extensions.wrapfunction(exchange, "push", exchangepush) - - -def revset_fromgit(repo, subset, x): - """``fromgit()`` - Select changesets that originate from Git. - """ - revset.getargs(x, 0, 0, "fromgit takes no arguments") - git = repo.githandler - node = repo.changelog.node - return baseset( - (r for r in subset if git.map_git_get(hex(node(r))) is not None), repo=repo - ) - - -def revset_gitnode(repo, subset, x): - """``gitnode(hash)`` - Select the changeset that originates in the given Git revision. The hash - may be abbreviated: `gitnode(a5b)` selects the revision whose Git hash - starts with `a5b`. Aborts if multiple changesets match the abbreviation. - """ - args = revset.getargs(x, 1, 1, "gitnode takes one argument") - rev = revset.getstring(args[0], "the argument to gitnode() must be a hash") - git = repo.githandler - node = repo.changelog.node - - def matches(r): - gitnode = git.map_git_get(hex(node(r))) - if gitnode is None: - return False - return gitnode.startswith(rev) - - result = baseset((r for r in subset if matches(r)), repo=repo) - if 0 <= len(result) < 2: - return result - raise LookupError(rev, git.map_file, _("ambiguous identifier")) - - -def gitnodekw(**args): - """:gitnode: String. The Git changeset identification hash, as a 40 char - hexadecimal digit string.""" - node = args["ctx"] - repo = args["repo"] - fromextra = node.extra().get("convert_revision", "") - if fromextra: - return fromextra - gitnode = repo.githandler.map_git_get(node.hex()) - if gitnode is None: - gitnode = "" - return gitnode diff --git a/eden/scm/edenscm/hgext/hggit/_ssh.py b/eden/scm/edenscm/hgext/hggit/_ssh.py deleted file mode 100644 index c20c45c2ee..0000000000 --- a/eden/scm/edenscm/hgext/hggit/_ssh.py +++ /dev/null @@ -1,40 +0,0 @@ -import subprocess - -from dulwich.client import SubprocessWrapper -from edenscm.mercurial import pycompat, 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 run_command(self, host, command, username=None, port=None): - if isinstance(command, (str, bytes, pycompat.unicode)): - # 0.12.x dulwich sends the raw string - command = [command] - elif len(command) > 1: - # 0.11.x dulwich sends an array of [command arg1 arg2 ...], so - # we detect that here and reformat it back to what hg-git - # expects (e.g. "command 'arg1 arg2'") - command = ["%s '%s'" % (command[0], " ".join(command[1:]))] - sshcmd = ui.config("ui", "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) - proc = subprocess.Popen( - util.quotecommand(cmd), - bufsize=0, - shell=True, - stdin=subprocess.PIPE, - stdout=subprocess.PIPE, - ) - return SubprocessWrapper(proc) - - return _Vendor diff --git a/eden/scm/edenscm/hgext/hggit/compat.py b/eden/scm/edenscm/hgext/hggit/compat.py deleted file mode 100644 index d21fc875a9..0000000000 --- a/eden/scm/edenscm/hgext/hggit/compat.py +++ /dev/null @@ -1,102 +0,0 @@ -# dulwich doesn't return the symref where remote HEAD points, so we monkey -# patch it here -from dulwich.errors import GitProtocolError -from dulwich.protocol import extract_capabilities -from edenscm.mercurial import url, util as hgutil - - -try: - from edenscm.mercurial import encoding - - hfsignoreclean = encoding.hfsignoreclean -except AttributeError: - # compat with hg 3.2.1 and earlier, which doesn't have - # hfsignoreclean (This was borrowed wholesale from hg 3.2.2.) - _ignore = [ - # pyre-fixme[10]: Name `unichr` is used but not defined. - unichr(int(x, 16)).encode("utf-8") # noqa: F821 - for x in "200c 200d 200e 200f 202a 202b 202c 202d 202e " - "206a 206b 206c 206d 206e 206f feff".split() - ] - # verify the next function will work - assert set([i[0] for i in _ignore]) == set(["\xe2", "\xef"]) - - def hfsignoreclean(s): - """Remove codepoints ignored by HFS+ from s. - - >>> hfsignoreclean(u'.h\u200cg'.encode('utf-8')) - '.hg' - >>> hfsignoreclean(u'.h\ufeffg'.encode('utf-8')) - '.hg' - """ - if "\xe2" in s or "\xef" in s: - for c in _ignore: - s = s.replace(c, "") - return s - - -def passwordmgr(ui): - try: - realm = hgutil.urlreq.httppasswordmgrwithdefaultrealm() - return url.passwordmgr(ui, realm) - except (TypeError, AttributeError): - # compat with hg < 3.9 - return url.passwordmgr(ui) - - -def read_pkt_refs(proto): - server_capabilities = None - refs = {} - # Receive refs from server - for pkt in proto.read_pkt_seq(): - (sha, ref) = pkt.rstrip(b"\n").split(None, 1) - if sha == b"ERR": - raise GitProtocolError(ref) - if server_capabilities is None: - (ref, server_capabilities) = extract_capabilities(ref) - symref = b"symref=HEAD:" - for cap in server_capabilities: - if cap.startswith(symref): - sha = cap.replace(symref, b"") - refs[ref] = sha - - if len(refs) == 0: - return None, set([]) - return refs, set(server_capabilities) - - -CONFIG_DEFAULTS = { - "git": { - "authors": None, - "blockdotgit": True, - "blockdothg": True, - "branch_bookmark_suffix": None, - "debugextrainmessage": False, # test only -- do not document this! - "findcopiesharder": False, - "intree": None, - "mindate": None, - "public": list, - "renamelimit": 400, - "similarity": 0, - }, - "hggit": {"mapsavefrequency": 0, "usephases": False}, -} - -hasconfigitems = False - - -def registerconfigs(configitem): - global hasconfigitems - hasconfigitems = True - for section, items in CONFIG_DEFAULTS.items(): - for item, default in items.items(): - configitem(section, item, default=default) - - -def config(ui, subtype, section, item): - if subtype == "string": - subtype = "" - getconfig = getattr(ui, "config" + subtype) - if hasconfigitems: - return getconfig(section, item) - return getconfig(section, item, CONFIG_DEFAULTS[section][item]) diff --git a/eden/scm/edenscm/hgext/hggit/git2hg.py b/eden/scm/edenscm/hgext/hggit/git2hg.py deleted file mode 100644 index 32fae29b80..0000000000 --- a/eden/scm/edenscm/hgext/hggit/git2hg.py +++ /dev/null @@ -1,160 +0,0 @@ -# git2hg.py - convert Git repositories and commits to Mercurial ones - -from dulwich.objects import Commit, Tag -from edenscm.mercurial import pycompat, util -from edenscm.mercurial.node import bin - - -def find_incoming(git_object_store, git_map, refs): - """find what commits need to be imported - - git_object_store is a dulwich object store. - git_map is a map with keys being Git commits that have already been imported - refs is a map of refs to SHAs that we're interested in.""" - - done = set() - commit_cache = {} - - # sort by commit date - def commitdate(sha): - obj = git_object_store[sha] - return obj.commit_time - obj.commit_timezone - - # get a list of all the head shas - def get_heads(refs): - todo = [] - seenheads = set() - for ref, sha in pycompat.iteritems(refs): - # refs could contain refs on the server that we haven't pulled down - # the objects for; also make sure it's a sha and not a symref - assert isinstance(sha, bytes), "expected bytes, actual %s %s" % ( - sha.__class__, - sha, - ) - if ref != "HEAD" and len(sha) == 40 and sha in git_object_store: - obj = git_object_store[sha] - while isinstance(obj, Tag): - obj_type, sha = obj.object - obj = git_object_store[sha] - if isinstance(obj, Commit) and sha not in seenheads: - seenheads.add(sha) - todo.append(sha) - - todo.sort(key=commitdate, reverse=True) - - # We convert to utf8 after the sort, since commitdate expects byte shas - return [pycompat.decodeutf8(s) for s in todo] - - def get_unseen_commits(todo): - """get all unseen commits reachable from todo in topological order - - 'unseen' means not reachable from the done set and not in the git map. - Mutates todo and the done set in the process.""" - commits = [] - while todo: - sha = todo[-1] - if sha in done or git_map.lookupbyfirst(bin(sha)) is not None: - todo.pop() - continue - if sha in commit_cache: - obj = commit_cache[sha] - else: - obj = git_object_store[pycompat.encodeutf8(sha)] - commit_cache[sha] = obj - assert isinstance(obj, Commit) - for p in obj.parents: - p = pycompat.decodeutf8(p) - if p not in done and git_map.lookupbyfirst(bin(p)) is None: - todo.append(p) - # process parents of a commit before processing the - # commit itself, and come back to this commit later - break - else: - commits.append(sha) - done.add(sha) - todo.pop() - - return commits - - todo = get_heads(refs) - commits = get_unseen_commits(todo) - - return GitIncomingResult(commits, commit_cache) - - -class GitIncomingResult(object): - """struct to store result from find_incoming""" - - def __init__(self, commits, commit_cache): - self.commits = commits - self.commit_cache = commit_cache - - -def extract_hg_metadata(message, git_extra): - # The git message may contain non-utf8 characters, which will later be - # encoded into a hg extras. So let's keep the message in bytes, even as we - # turn the metadata into utf8 below. - split = message.split(b"\n--HG--\n", 1) - - # Renames are explicitly stored in Mercurial but inferred in Git. For - # commits that originated in Git we'd like to optionally infer rename - # information to store in Mercurial, but for commits that originated in - # Mercurial we'd like to disable this. How do we tell whether the commit - # originated in Mercurial or in Git? We rely on the presence of extra hg-git - # fields in the Git commit. - # - Commits exported by hg-git versions past 0.7.0 always store at least one - # hg-git field. - # - For commits exported by hg-git versions before 0.7.0, this becomes a - # heuristic: if the commit has any extra hg fields, it definitely - # originated in Mercurial. If the commit doesn't, we aren't really sure. - # If we think the commit originated in Mercurial, we set renames to a - # dict. If we don't, we set renames to None. Callers can then determine - # whether to infer rename information. - renames = None - extra = {} - branch = None - if len(split) == 2: - renames = {} - message, meta = split - meta = pycompat.decodeutf8(meta) - lines = meta.split("\n") - for line in lines: - if line == "": - continue - - if " : " not in line: - break - command, data = line.split(" : ", 1) - - if command == "rename": - before, after = data.split(" => ", 1) - renames[after] = before - if command == "branch": - branch = data - if command == "extra": - k, v = data.split(" : ", 1) - extra[k] = util.urlreq.unquote(v) - - git_fn = 0 - for field, data in git_extra: - field = pycompat.decodeutf8(field) - data = pycompat.decodeutf8(data) - if field.startswith("HG:"): - if renames is None: - renames = {} - command = field[3:] - if command == "rename": - before, after = data.split(":", 1) - renames[util.urlreq.unquote(after)] = util.urlreq.unquote(before) - elif command == "extra": - k, v = data.split(":", 1) - extra[util.urlreq.unquote(k)] = util.urlreq.unquote(v) - else: - # preserve ordering in Git by using an incrementing integer for - # each field. Note that extra metadata in Git is an ordered list - # of pairs. - hg_field = "GIT%d-%s" % (git_fn, field) - git_fn += 1 - extra[util.urlreq.quote(hg_field)] = util.urlreq.quote(data) - - return (message, renames, branch, extra) diff --git a/eden/scm/edenscm/hgext/hggit/git_handler.py b/eden/scm/edenscm/hgext/hggit/git_handler.py deleted file mode 100644 index da0d21e59f..0000000000 --- a/eden/scm/edenscm/hgext/hggit/git_handler.py +++ /dev/null @@ -1,1893 +0,0 @@ -# Copyright (c) Facebook, Inc. and its affiliates. -# -# This software may be used and distributed according to the terms of the -# GNU General Public License version 2. - -import collections -import itertools -import os -import re -import shutil -import sys - -from bindings import nodemap -from dulwich import client, config as dul_config, diff_tree -from dulwich.errors import GitProtocolError, HangupException -from dulwich.objects import Blob, Commit, Tag, Tree, parse_timezone -from dulwich.pack import apply_delta, create_delta -from dulwich.repo import Repo, check_ref_format -from edenscm.mercurial import ( - bookmarks, - commands, - context, - encoding, - error, - phases, - progress, - pycompat, - util as hgutil, - vfs as vfsmod, -) -from edenscm.mercurial.i18n import _ -from edenscm.mercurial.node import bin, hex, nullid, nullrev - -from . import _ssh, compat, git2hg, hg2git, util -from .overlay import overlayrepo - - -RE_GIT_AUTHOR = re.compile("^(.*?) ?\<(.*?)(?:\>(.*))?$") - -RE_GIT_SANITIZE_AUTHOR = re.compile("[<>\n]") - -RE_GIT_AUTHOR_EXTRA = re.compile(b"^(.*?)\ ext:\((.*)\) <(.*)\>$") - -RE_GIT_EXTRA_KEY = re.compile("GIT([0-9]*)-(.*)") - -# Test for git:// and git+ssh:// URI. -# Support several URL forms, including separating the -# host and path with either a / or : (sepr) -RE_GIT_URI = re.compile( - r"^(?Pgit([+]ssh)?://)(?P.*?)(:(?P\d+))?" - r"(?P[:/])(?P.*)$" -) - -RE_NEWLINES = re.compile("[\r\n]") -RE_GIT_PROGRESS = re.compile("\((\d+)/(\d+)\)") - -RE_AUTHOR_FILE = re.compile("\s*=\s*") - -CALLBACK_BUFFER = b"" - - -class GitProgress(object): - """convert git server progress strings into mercurial progress""" - - def __init__(self, ui, prog): - self.ui = ui - self.prog = prog - - self.lasttopic = None - self.msgbuf = "" - - def progress(self, msg): - # 'Counting objects: 33640, done.\n' - # 'Compressing objects: 0% (1/9955) \r - msg = pycompat.decodeutf8(msg) - msgs = RE_NEWLINES.split(self.msgbuf + msg) - self.msgbuf = msgs.pop() - - for msg in msgs: - td = msg.split(":", 1) - data = td.pop() - if not td: - self.ui.note(data + "\n") - continue - topic = td[0] - - m = RE_GIT_PROGRESS.search(data) - if m: - pos, total = list(map(int, m.group(1, 2))) - if topic != self.lasttopic: - self.prog.reset(topic, total=total) - self.lasttopic = topic - self.prog.value = pos - else: - self.ui.note(msg + "\n") - - -class GitHandler(object): - map_file = "git-mapfile" - remote_refs_file = "git-remote-refs" - tags_file = "git-tags" - - def __init__(self, dest_repo, ui): - self.repo = dest_repo - self.ui = ui - self.vfs = self.repo.sharedvfs - - if compat.config(ui, "bool", "git", "intree"): - self.gitdir = self.repo.wvfs.join(".git") - else: - self.gitdir = self.vfs.join("git") - - self.init_author_file() - - self.paths = ui.configitems("paths") - - self.branch_bookmark_suffix = compat.config( - ui, "string", "git", "branch_bookmark_suffix" - ) - - self._map_real = None - self._map_hg_modifications = set() - self.load_tags() - self._remote_refs = None - - @property - def _map(self): - if self._map_real is None: - self.load_map() - return self._map_real - - @property - def remote_refs(self): - if self._remote_refs is None: - self.load_remote_refs() - return self._remote_refs - - @hgutil.propertycache - def git(self): - gitpath = self.gitdir - # make the git data directory - if os.path.exists(self.gitdir): - return Repo(gitpath) - else: - # Set disallowinitbare to prevent hggit from creating a .hg/git - # directory. This is useful when the .hg/git directory should be - # managed externally. - if self.ui.configbool("hggit", "disallowinitbare"): - raise error.Abort(_("missing .hg/git repo")) - os.mkdir(self.gitdir) - return Repo.init_bare(gitpath) - - def init_author_file(self): - self.author_map = {} - authors_path = compat.config(self.ui, "string", "git", "authors") - if authors_path: - with open(self.repo.wvfs.join(authors_path)) as f: - for line in f: - line = line.strip() - if not line or line.startswith("#"): - continue - from_, to = RE_AUTHOR_FILE.split(line, 2) - self.author_map[from_] = to - - # FILE LOAD AND SAVE METHODS - - def map_set(self, gitsha, hgsha): - assert isinstance(gitsha, str) - assert isinstance(hgsha, str) - hgnode = bin(hgsha) - self._map.add(bin(gitsha), hgnode) - self._map_hg_modifications.add(hgnode) - - def map_hg_get(self, gitsha): - node = self._map.lookupbyfirst(bin(gitsha)) - if node is not None: - node = hex(node) - return node - - def map_git_get(self, hgsha): - node = self._map.lookupbysecond(bin(hgsha)) - if node is not None: - node = hex(node) - return node - - def load_map(self): - if self.ui.configbool("hggit", "indexedlognodemap", False): - dir = self.vfs.join(self.map_file + "-log") - - # Check for log existance before we instantiate it. - logexists = self.vfs.exists(dir) - - self._map_real = nodemap.nodemap(dir) - - # If the indexedlog map doesn't exist, populate it. - if not logexists and self.vfs.exists(self.map_file): - # Don't construct - oldmap = GitMap(self.vfs(self.map_file)) - for gitsha, hgsha in oldmap.items(): - self._map_real.add(gitsha, hgsha) - self._map_real.flush() - else: - content = [] - if os.path.exists(self.vfs.join(self.map_file)): - content = self.vfs(self.map_file) - - self._map_real = GitMap(content) - - def save_map(self, map_file): - wlock = self.repo.wlock() - try: - map = self._map - - if self.ui.configbool("hggit", "indexedlognodemap", False): - self._map_real.flush() - else: - file = self.vfs(map_file, "a+", atomictemp=True) - buf = hgutil.stringio() - bwrite = buf.write - # Append new entries to the end of the file so we can search - # backwards from the end for recently added entries. - for hgnode in self._map_hg_modifications: - gitnode = map.lookupbysecond(hgnode) - if gitnode is None: - raise KeyError(hex(hgnode)) - bwrite(pycompat.encodeutf8("%s %s\n" % (hex(gitnode), hex(hgnode)))) - file.write(buf.getvalue()) - buf.close() - # If this complains, atomictempfile no longer has close - file.close() - self._map_hg_modifications.clear() - finally: - wlock.release() - - def load_tags(self): - self.tags = {} - if os.path.exists(self.vfs.join(self.tags_file)): - for line in self.vfs(self.tags_file): - sha, name = line.strip().split(" ", 1) - self.tags[name] = sha - - def save_tags(self): - file = self.vfs(self.tags_file, "w+", atomictemp=True) - for name, sha in sorted(pycompat.iteritems(self.tags)): - if not self.repo.tagtype(name) == "global": - file.write("%s %s\n" % (sha, name)) - # If this complains, atomictempfile no longer has close - file.close() - - def load_remote_refs(self): - self._remote_refs = {} - refdir = os.path.join(self.git.path, "refs", "remotes") - - paths = self.paths - # if paths are set, we should still check 'default' - if not paths: - paths = [("default", None)] - - # we avoid using dulwich's refs method because it is incredibly slow; - # on a repo with a few hundred branches and a few thousand tags, - # dulwich took about 200ms - for p in paths: - remotedir = os.path.join(refdir, p[0]) - for root, dirs, files in os.walk(remotedir): - for f in files: - try: - ref = root.replace(refdir + pycompat.ossep, "") + "/" - node = open(os.path.join(root, f)).read().strip() - hgsha = self._map.lookupbyfirst(bin(node)) - if hgsha is None: - raise KeyError(hex(node)) - self._remote_refs[ref + f] = hgsha - except (KeyError, IOError): - pass - - # END FILE LOAD AND SAVE METHODS - - # COMMANDS METHODS - - def import_commits(self, remote_name): - refs = self.git.refs.as_dict() - filteredrefs = self.filter_min_date(refs) - self.import_git_objects(filteredrefs) - self.update_hg_bookmarks(refs) - self.save_map(self.map_file) - - def fetch(self, remote, heads): - refs = self.fetch_pack(remote, heads) - remote_name = self.remote_name(remote) - - # if remote returns a symref for HEAD, then let's store that - rhead = None - rnode = None - oldheads = self.repo.heads() - imported = 0 - if refs: - filteredrefs = self.filter_min_date(self.filter_refs(refs, heads)) - imported = self.import_git_objects(filteredrefs) - self.update_hg_bookmarks(refs) - - try: - symref = refs["HEAD"] - if symref.startswith("refs/heads"): - rhead = symref.replace("refs/heads/", "") - - rnode = refs["refs/heads/%s" % rhead] - hgrnode = self._map.lookupbyfirst(bin(rnode)) - if hgrnode is None: - raise KeyError(rnode) - rnode = self.repo[hgrnode].node() - except KeyError: - # if there is any error make sure to clear the variables - rhead = None - rnode = None - - if remote_name: - self.update_remote_branches(remote_name, refs) - elif getattr(self.repo.currenttransaction(), "desc", None) == "clone": - # intial cloning - self.update_remote_branches("default", refs) - - # "Activate" a tipmost bookmark. - bms = self.repo["tip"].bookmarks() - - # override the 'tipmost' behavior if we know the remote HEAD - if rnode: - # make sure the bookmark exists; at the point the remote - # branches has already been set up - suffix = self.branch_bookmark_suffix or "" - changes = [(rhead + suffix, rnode)] - util.updatebookmarks(self.repo, changes) - bms = [rhead + suffix] - - if bms: - try: - bookmarks.activate(self.repo, bms[0]) - except AttributeError: - # hg < 3.5 - bookmarks.setcurrent(self.repo, bms[0]) - - self.save_map(self.map_file) - - # also mark public any branches the user specified - blist = [ - self.repo[branch].node() for branch in self.ui.configlist("git", "public") - ] - if rnode and self.ui.configbool("hggit", "usephases"): - blist.append(rnode) - - if blist: - lock = self.repo.lock() - try: - tr = self.repo.transaction("phase") - try: - phases.advanceboundary(self.repo, tr, phases.public, blist) - except TypeError: - # hg < 3.2 - phases.advanceboundary(self.repo, phases.public, blist) - tr.close() - finally: - if tr is not None: - tr.release() - lock.release() - - if imported == 0: - return 0 - - # code taken from localrepo.py:addchangegroup - dh = 0 - if oldheads: - heads = self.repo.heads() - dh = len(heads) - len(oldheads) - for h in heads: - if h not in oldheads and self.repo[h].closesbranch(): - dh -= 1 - - if dh < 0: - return dh - 1 - else: - return dh + 1 - - def export_commits(self): - try: - self.export_git_objects() - self.update_references() - finally: - self.save_map(self.map_file) - - 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) - exportable = self.get_exportable() - new_refs.update(self.get_changed_refs(refs, exportable, True)) - return refs # always return the same refs to make the send a no-op - - try: - client.send_pack(path, changed, lambda have, want: []) - - changed_refs = [ - ref - for ref, sha in pycompat.iteritems(new_refs) - 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) as e: - raise error.Abort(_("git remote error: ") + str(e)) - - def push(self, remote, revs, force): - self.export_commits() - old_refs, new_refs = self.upload_pack(remote, revs, force) - remote_name = self.remote_name(remote) - - if remote_name and new_refs: - for ref, new_sha in sorted(pycompat.iteritems(new_refs)): - old_sha = old_refs.get(ref) - - ref = pycompat.decodeutf8(ref) - if old_sha is None: - if self.ui.verbose: - self.ui.note( - _("adding reference %s::%s => GIT:%s\n") - % (remote_name, ref, new_sha[0:8]) - ) - else: - self.ui.status_err(_("adding reference %s\n") % ref) - elif new_sha != old_sha: - if self.ui.verbose: - self.ui.note( - _("updating reference %s::%s => GIT:%s\n") - % (remote_name, ref, new_sha[0:8]) - ) - else: - self.ui.status_err(_("updating reference %s\n") % ref) - else: - self.ui.debug( - "unchanged reference %s::%s => GIT:%s\n" - % (remote_name, ref, new_sha[0:8]) - ) - - self.update_remote_branches(remote_name, new_refs) - if old_refs == new_refs: - self.ui.status_err(_("no changes found\n")) - ret = None - elif len(new_refs) > len(old_refs): - ret = 1 + (len(new_refs) - len(old_refs)) - elif len(old_refs) > len(new_refs): - ret = -1 - (len(new_refs) - len(old_refs)) - else: - ret = 1 - return ret - - def clear(self): - mapfile = self.vfs.join(self.map_file) - if self.ui.configbool("hggit", "indexedlognodemap", False): - shutil.rmtree(mapfile + "-log") - - 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: - rev = pycompat.encodeutf8(rev) - for n in (b"refs/heads/" + rev, b"refs/tags/" + rev): - if n in refs: - reqrefs[n] = refs[n] - else: - reqrefs = refs - - commits = [bin(c) for c in self.get_git_incoming(reqrefs).commits] - - b = overlayrepo(self, commits, refs) - - return (b, commits, lambda: None) - - # CHANGESET CONVERSION METHODS - - def export_git_objects(self): - self.ui.note(_("finding hg commits to export\n")) - repo = self.repo - clnode = repo.changelog.node - clparents = repo.changelog.parentrevs - - # Starting at the heads, walk back and find any commits that aren't in - # the git/hg mapping. - pending = [] - if len(repo) > 0: - # repo.heads() returns the nullrev in an empty repo - pending = list(repo.headrevs()) - exportrevs = set() - while pending: - rev = pending.pop() - node = clnode(rev) - if self._map.lookupbysecond(node) is None: - exportrevs.add(rev) - for parentrev in clparents(rev): - if parentrev != nullrev and parentrev not in exportrevs: - pending.append(parentrev) - # Sorting here is important, because the below code expects to process - # these in topological order. - to_export = list(repo[r] for r in sorted(exportrevs)) - - todo_total = len(exportrevs) - pos = 0 - export = [] - with progress.bar( - repo.ui, "find commits to export", "commits", todo_total - ) as prog: - for ctx in to_export: - item = hex(ctx.node()) - pos += 1 - prog.value = (pos, item) - if ctx.extra().get("hg-git", None) != "octopus": - export.append(ctx) - - total = len(export) - if not total: - return - - self.ui.note(_("exporting hg objects to git\n")) - - # By only exporting deltas, the assertion is that all previous objects - # for all other changesets are already present in the Git repository. - # This assertion is necessary to prevent redundant work. Here, nodes, - # and therefore export, is in topological order. By definition, - # export[0]'s parents must be present in Git, so we start the - # incremental exporter from there. - pctx = export[0].p1() - pnode = pctx.node() - if pnode == nullid: - gitcommit = None - else: - gitnode = self._map.lookupbysecond(pnode) - if gitnode is None: - raise KeyError(hex(pnode)) - gitsha = hex(gitnode) - try: - gitcommit = self.git[pycompat.encodeutf8(gitsha)] - except KeyError: - raise error.Abort( - _("Parent SHA-1 not present in Git " "repo: %s") % gitsha - ) - - exporter = hg2git.IncrementalChangesetExporter( - self.repo, pctx, self.git.object_store, gitcommit - ) - - mapsavefreq = compat.config(self.ui, "int", "hggit", "mapsavefrequency") - with progress.bar(self.ui, _("exporting"), total=total) as prog: - for i, ctx in enumerate(export): - prog.value = i - self.export_hg_commit(ctx.node(), exporter) - if mapsavefreq and i % mapsavefreq == 0: - self.ui.debug("saving mapfile\n") - self.save_map(self.map_file) - - def set_commiter_from_author(self, commit): - commit.committer = commit.author - commit.commit_time = commit.author_time - commit.commit_timezone = commit.author_timezone - - # 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, exporter): - 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() - # work around to bad timezone offets - dulwich does not handle - # sub minute based timezones. In the one known case, it was a - # manual edit that led to the unusual value. Based on that, - # there is no reason to round one way or the other, so do the - # simplest and round down. - timezone -= timezone % 60 - commit.author = pycompat.encodeutf8( - self.get_git_author(ctx), errors="surrogateescape" - ) - commit.author_time = int(time) - commit.author_timezone = -timezone - - if "committer" in extra: - try: - # fixup timezone - (name, timestamp, timezone) = extra["committer"].rsplit(" ", 2) - commit.committer = pycompat.encodeutf8(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 - except Exception: # extra is essentially user-supplied; be careful - self.set_commiter_from_author(commit) - else: - self.set_commiter_from_author(commit) - - commit.parents = [] - for parent in self.get_git_parents(ctx): - hgsha = hex(parent.node()) - git_sha = self.map_git_get(hgsha) - if git_sha: - git_sha = pycompat.encodeutf8(git_sha) - if git_sha not in self.git.object_store: - raise error.Abort( - _("Parent SHA-1 not present in Git " "repo: %s") - % pycompat.decodeutf8(git_sha) - ) - - commit.parents.append(git_sha) - - commit.message, extra = self.get_git_message_and_extra(ctx) - commit.extra.extend(extra) - - if b"encoding" in extra: - commit.encoding = pycompat.encodeutf8(extra["encoding"]) - - for obj, nodeid in exporter.update_changeset(ctx): - # In theory we should check if the object exists before adding it, - # but in practice it's unlikely to exist, and scanning all the packs - # to determine that is expensive. - self.git.object_store.add_object(obj) - - tree_sha = exporter.root_tree_sha - - if tree_sha not in self.git.object_store: - raise error.Abort(_("Tree SHA-1 not present in Git repo: %s") % tree_sha) - - commit.tree = tree_sha - - if commit.id not in self.git.object_store: - self.git.object_store.add_object(commit) - self.map_set(pycompat.decodeutf8(commit.id), ctx.hex()) - - self.swap_out_encoding(oldenc) - return commit.id - - def get_valid_git_username_email(self, name): - r"""Sanitize usernames and emails to fit git's restrictions. - - The following is taken from the man page of git's fast-import - command: - - [...] Likewise LF means one (and only one) linefeed [...] - - committer - The committer command indicates who made this commit, - and when they made it. - - Here is the person's display name (for example - "Com M Itter") and is the person's email address - ("cm@example.com[1]"). LT and GT are the literal - less-than (\x3c) and greater-than (\x3e) symbols. These - are required to delimit the email address from the other - fields in the line. Note that and are - free-form and may contain any sequence of bytes, except - LT, GT and LF. is typically UTF-8 encoded. - - Accordingly, this function makes sure that there are none of the - characters <, >, or \n in any string which will be used for - a git username or email. Before this, it first removes left - angle brackets and spaces from the beginning, and right angle - brackets and spaces from the end, of this string, to convert - such things as " " to "john@doe.com" for - convenience. - - TESTS: - - >>> from collections import namedtuple - >>> from edenscm.mercurial.ui import ui - >>> mockrepo = namedtuple('localrepo', ['sharedvfs']) - >>> mockrepo.sharedvfs = '' - >>> g = GitHandler(mockrepo, ui()).get_valid_git_username_email - >>> g('John Doe') - 'John Doe' - >>> g('john@doe.com') - 'john@doe.com' - >>> g(' ') - 'john@doe.com' - >>> g(' > > ') - 'random???garbage?' - >>> g('Typo in hgrc >but.hg-git@handles.it.gracefully>') - 'Typo in hgrc ?but.hg-git@handles.it.gracefully' - """ - return RE_GIT_SANITIZE_AUTHOR.sub("?", name.lstrip("< ").rstrip("> ")) - - def get_git_author(self, ctx): - # hg authors might not have emails - author = ctx.user() - - # see if a translation exists - author = self.author_map.get(author, author) - - # check for git author pattern compliance - a = RE_GIT_AUTHOR.match(author) - - if a: - name = self.get_valid_git_username_email(a.group(1)) - email = self.get_valid_git_username_email(a.group(2)) - if a.group(3) is not None and len(a.group(3)) != 0: - name += " ext:(" + hgutil.urlreq.quote(a.group(3)) + ")" - author = "%s <%s>" % ( - self.get_valid_git_username_email(name), - self.get_valid_git_username_email(email), - ) - elif "@" in author: - author = "%s <%s>" % ( - self.get_valid_git_username_email(author), - self.get_valid_git_username_email(author), - ) - else: - author = self.get_valid_git_username_email(author) + " " - - if "author" in ctx.extra(): - author = pycompat.decodeutf8( - b"".join( - apply_delta( - pycompat.encodeutf8(author), - pycompat.encodeutf8( - ctx.extra()["author"], errors="surrogateescape" - ), - ) - ), - errors="surrogateescape", - ) - - return author - - def get_git_parents(self, ctx): - def is_octopus_part(ctx): - olist = ("octopus", "octopus-done") - return ctx.extra().get("hg-git", None) in olist - - 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 ctx.extra().get("hg-git", None) != "octopus" - parents.append(p1) - part = p2 - parents.append(p2) - else: - parents = ctx.parents() - - return parents - - def get_git_message_and_extra(self, ctx): - extra = ctx.extra() - - message = pycompat.encodeutf8(ctx.description()) + b"\n" - if "message" in extra: - message = b"".join( - apply_delta( - message, - pycompat.encodeutf8(extra["message"], errors="surrogateescape"), - ) - ) - - # HG EXTRA INFORMATION - - # test only -- do not document this! - extra_in_message = compat.config(self.ui, "bool", "git", "debugextrainmessage") - extra_message = "" - git_extra = [] - if ctx.branch() != "default": - # we always store the branch in the extra message - extra_message += "branch : " + ctx.branch() + "\n" - - # Git native extra items always come first, followed by hg renames, - # followed by hg extra keys - git_extraitems = [] - for key, value in extra.items(): - m = RE_GIT_EXTRA_KEY.match(key) - if m is not None: - git_extraitems.append((int(m.group(1)), m.group(2), value)) - del extra[key] - - git_extraitems.sort() - for i, field, value in git_extraitems: - git_extra.append( - ( - pycompat.encodeutf8(hgutil.urlreq.unquote(field)), - pycompat.encodeutf8(hgutil.urlreq.unquote(value)), - ) - ) - - if extra.get("hg-git-rename-source", None) != "git": - 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: - for oldfile, newfile in renames: - if extra_in_message: - extra_message += "rename : " + oldfile + " => " + newfile + "\n" - else: - spec = "%s:%s" % ( - hgutil.urlreq.quote(oldfile), - hgutil.urlreq.quote(newfile), - ) - git_extra.append((b"HG:rename", pycompat.encodeutf8(spec))) - - # hg extra items always go at the end - extraitems = list(extra.items()) - extraitems.sort() - for key, value in extraitems: - if key in ( - "author", - "committer", - "encoding", - "message", - "branch", - "hg-git", - "hg-git-rename-source", - ): - continue - else: - if extra_in_message: - extra_message += ( - "extra : " + key + " : " + hgutil.urlreq.quote(value) + "\n" - ) - else: - spec = "%s:%s" % ( - hgutil.urlreq.quote(key), - hgutil.urlreq.quote(value), - ) - git_extra.append((b"HG:extra", pycompat.encodeutf8(spec))) - - if extra_message: - message += pycompat.encodeutf8("\n--HG--\n" + extra_message) - - if ( - extra.get("hg-git-rename-source", None) != "git" - and not extra_in_message - and not git_extra - and extra_message == "" - ): - # We need to store this if no other metadata is stored. This - # indicates that when reimporting the commit into Mercurial we'll - # know not to detect renames. - git_extra.append((b"HG:rename-source", b"hg")) - - return message, git_extra - - def get_git_incoming(self, refs): - return git2hg.find_incoming(self.git.object_store, self._map, refs) - - def import_git_objects(self, refs, limit=None): - result = self.get_git_incoming(refs) - commits = result.commits - commit_cache = result.commit_cache - # import each of the commits, oldest first - total = len(commits) - if total: - self.ui.status_err(_("importing git objects into hg\n")) - else: - self.ui.status_err(_("no changes found\n")) - - importcount = total - if limit is not None: - importcount = min(total, limit) - - mapsavefreq = compat.config(self.ui, "int", "hggit", "mapsavefrequency") - with progress.bar( - self.ui, _("importing"), "commits", total=importcount - ) as prog: - icommits = enumerate(itertools.islice(commits, limit)) - while True: - isubcommits = list(itertools.islice(icommits, mapsavefreq or 1)) - if not isubcommits: - break - - with self.repo.transaction("git import"): - for i, csha in isubcommits: - prog.value = i - commit = commit_cache[csha] - self.import_git_commit(commit) - self.ui.debug("committing transaction\n") - - if mapsavefreq: - self.ui.debug("saving mapfile\n") - self.save_map(self.map_file) - - # TODO if the tags cache is used, remove any dangling tag references - return importcount - - def import_git_commit(self, commit): - self.ui.debug("importing: %s\n" % commit.id) - - commitid = pycompat.decodeutf8(commit.id) - commitencoding = ( - pycompat.decodeutf8(commit.encoding) if commit.encoding else None - ) - commitcommitter = pycompat.decodeutf8(commit.committer) - - detect_renames = False - (strip_message, hg_renames, hg_branch, extra) = git2hg.extract_hg_metadata( - commit.message, commit.extra - ) - - # Store the original git commit hash in the Mercurial extras. This - # breaks bidirectionality, but makes it possible for a Mercurial client - # to compute the git/hg mapping without having the entire git repo. - # "convert_revision" was chosen to match the hgsubversion and hg convert - # extra field. - extra["convert_revision"] = commitid - - if hg_renames is None: - detect_renames = True - # We have to store this unconditionally, even if there are no - # renames detected from Git. This is because we export an extra - # 'HG:rename-source' Git parameter when this isn't set, which will - # break bidirectionality. - extra["hg-git-rename-source"] = "git" - else: - renames = hg_renames - - gparents = list(map(self.map_hg_get, commit.parents)) - - for parent in gparents: - if parent not in self.repo: - raise error.Abort( - _("you appear to have run strip - " "please run hg git-cleanup") - ) - - # get a list of the changed, added, removed files and gitlinks - files, gitlinks, git_renames = self.get_files_changed(commit, detect_renames) - - # If we need to skip a commit because the contents are problematic, - # let's still write the commit, so we have something to map to from git, - # but leave it empty. - if commitid in self.ui.configlist("hggit", "skipgithashes", []): - self.ui.warn(_("forcing git commit %s to be empty\n") % commitid) - files = {} - gitlinks = {} - git_renames = {} - - if detect_renames: - renames = git_renames - - date = (commit.author_time, -commit.author_timezone) - text = strip_message - - origtext = text - try: - text.decode("utf-8") - except UnicodeDecodeError: - text = self.decode_guess(text, commitencoding) - - text = b"\n".join([l.rstrip() for l in text.splitlines()]).strip(b"\n") - if text + b"\n" != origtext: - extra["message"] = pycompat.decodeutf8( - create_delta(text + b"\n", origtext), - errors="surrogateescape", - ) - - text = pycompat.decodeutf8(text) - - author = commit.author - - # convert extra data back to the end - if b" ext:" in author: - m = RE_GIT_AUTHOR_EXTRA.match(author) - if m: - name = m.group(1) - ex = pycompat.encodeutf8( - hgutil.urlreq.unquote(pycompat.decodeutf8(m.group(2))) - ) - email = m.group(3) - author = name + b" <" + email + b">" + ex - - if b" " in author: - author = author[:-12] - - try: - decodedauthor = author.decode("utf-8") - if sys.version_info[0] == 3: - author = decodedauthor - except UnicodeDecodeError: - origauthor = author - author = self.decode_guess(author, commitencoding) - extra["author"] = pycompat.decodeutf8( - create_delta(author, origauthor), errors="surrogateescape" - ) - author = pycompat.decodeutf8(author) - - 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 pycompat.iteritems(manifest1) - if path not in files and manifest2.get(path, node1) != node1 - ] - - def getfilectx(repo, memctx, f): - info = files.get(f) - if info is not None: - # it's a file reported as modified from Git - delete, mode, sha = info - if delete: - if getattr(memctx, "_returnnoneformissingfiles", False): - return None - else: # Mercurial < 3.2 - raise IOError - - if not sha: # indicates there's no git counterpart - e = "" - copied_path = None - else: - data = self.git[sha].data - copied_path = 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 = None - copied = fc.renamed() - if copied: - copied_path = copied[0] - - try: - return context.memfilectx( - self.repo, - memctx, - f, - data, - islink="l" in e, - isexec="x" in e, - copied=copied_path, - ) - except TypeError: - try: - return context.memfilectx( - self.repo, - f, - data, - islink="l" in e, - isexec="x" in e, - copied=copied_path, - ) - except TypeError: - return context.memfilectx( - f, data, islink="l" in e, isexec="x" in e, copied=copied_path - ) - - 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() - - # if named branch, add to extra - if hg_branch: - extra["branch"] = hg_branch - else: - extra["branch"] = "default" - - # 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" % ( - commitcommitter, - commit.commit_time, - -commit.commit_timezone, - ) - - if commitencoding: - extra["encoding"] = commitencoding - - if octopus: - extra["hg-git"] = "octopus-done" - - 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(commitid, cs) - - # PACK UPLOADING AND FETCHING - - def upload_pack(self, remote, revs, force): - client, path = self.get_transport_and_path(remote) - old_refs = {} - change_totals = {} - - def changed(refs): - self.ui.status_err(_("searching for changes\n")) - old_refs.update(refs) - all_exportable = self.get_exportable() - if revs is None: - exportable = all_exportable - else: - exportable = {} - for rev in (hex(r) for r in revs): - if rev not in all_exportable: - raise error.Abort( - "revision %s cannot be pushed since" - " it doesn't have a bookmark" % self.repo[rev] - ) - exportable[rev] = all_exportable[rev] - return self.get_changed_refs(refs, exportable, force) - - def genpack(have, want, progress=None, ofs_delta=True): - commits = [] - for mo in self.git.object_store.find_missing_objects(have, want): - (sha, name) = mo - o = self.git.object_store[sha] - t = type(o) - change_totals[t] = change_totals.get(t, 0) + 1 - if isinstance(o, Commit): - commits.append(sha) - commit_count = len(commits) - self.ui.note(_("%d commits found\n") % commit_count) - if commit_count > 0: - self.ui.debug("list of commits:\n") - for commit in commits: - self.ui.debug("%s\n" % commit) - self.ui.status_err(_("adding objects\n")) - genpack = getattr(self.git.object_store, "generate_pack_data", None) - if genpack is not None: - # dulwich >= 0.19 has generate_pack_data - return genpack(have, want, progress=None, ofs_delta=True) - else: - # dulwich < 0.19 has generate_pack_contents - return self.git.object_store.generate_pack_contents(have, want) - - def callback(remote_info): - # dulwich (perhaps git?) wraps remote output at a fixed width but - # signifies the end of transmission with a double new line - global CALLBACK_BUFFER - if remote_info and not remote_info.endswith(b"\n\n"): - CALLBACK_BUFFER += remote_info - return - - remote_info = CALLBACK_BUFFER + remote_info - CALLBACK_BUFFER = b"" - if not remote_info: - remote_info = b"\n" - - for line in remote_info[:-1].split(b"\n"): - self.ui.status_err(_("remote: %s\n") % line) - - try: - new_refs = client.send_pack(path, changed, genpack, progress=callback) - if len(change_totals) > 0: - self.ui.status_err( - _("added %d commits with %d trees" " and %d blobs\n") - % ( - change_totals.get(Commit, 0), - change_totals.get(Tree, 0), - change_totals.get(Blob, 0), - ) - ) - return old_refs, new_refs - except (HangupException, GitProtocolError) as e: - raise error.Abort(_("git remote error: ") + str(e)) - - def get_changed_refs(self, refs, exportable, force): - new_refs = refs.copy() - - # The remote repo is empty and the local one doesn't have - # bookmarks/tags - # - # (older dulwich versions return the proto-level - # capabilities^{} key when the dict should have been - # empty. That check can probably be removed at some point in - # the future.) - if not refs or list(refs.keys())[0] == b"capabilities^{}": - if not exportable: - tip = self.repo.lookup("tip") - if tip != nullid: - if b"capabilities^{}" in new_refs: - del new_refs[b"capabilities^{}"] - tip = hex(tip) - try: - commands.bookmark( - self.ui, self.repo, "master", rev=tip, force=True - ) - except NameError: - bookmarks.bookmark( - self.ui, self.repo, "master", rev=tip, force=True - ) - try: - bookmarks.activate(self.repo, "master") - except AttributeError: - # hg < 3.5 - bookmarks.setcurrent(self.repo, "master") - new_refs[b"refs/heads/master"] = pycompat.encodeutf8( - self.map_git_get(tip) - ) - - # mapped nodes might be hidden - unfiltered = self.repo - for rev, rev_refs in pycompat.iteritems(exportable): - ctx = self.repo[rev] - if not rev_refs: - raise error.Abort( - "revision %s cannot be pushed since" - " it doesn't have a bookmark" % 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 ref in rev_refs.tags: - # Check tag. - if ref not 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 ref in rev_refs: - ref = pycompat.encodeutf8(ref) - if ref not in refs: - new_refs[ref] = pycompat.encodeutf8(self.map_git_get(ctx.hex())) - elif self._map.lookupbyfirst(bin(new_refs[ref])) is not None: - rctx = unfiltered[self.map_hg_get(new_refs[ref])] - if rctx.ancestor(ctx) == rctx or force: - new_refs[ref] = pycompat.encodeutf8(self.map_git_get(ctx.hex())) - else: - raise error.Abort( - "pushing %s overwrites %s" % (pycompat.decodeutf8(ref), ctx) - ) - elif ref in uptodate_annotated_tags: - # we already have the annotated tag. - pass - else: - raise error.Abort( - "branch '%s' changed on the server, " - "please pull and merge before pushing" - % pycompat.decodeutf8(ref) - ) - - return new_refs - - def fetch_pack(self, uri, heads=None): - localclient, path = self.get_transport_and_path(uri) - - # The dulwich default walk only checks refs/heads/. We also want to - # consider remotes when doing discovery, so we build our own list. We - # can't just do 'refs/' here because the tag class doesn't have a - # parents function for walking, and older versions of dulwich don't like - # that. - haveheads = list(self.git.refs.as_dict(b"refs/remotes/").values()) - haveheads.extend(self.git.refs.as_dict(b"refs/heads/").values()) - graphwalker = self.git.get_graph_walker(heads=haveheads) - - def determine_wants(refs): - if refs is None: - return None - filteredrefs = self.filter_refs(refs, heads) - return [x for x in pycompat.itervalues(filteredrefs) if x not in self.git] - - try: - with progress.bar(self.ui, "") as prog: - gitprogress = GitProgress(self.ui, prog) - f = pycompat.stringio() - - # monkey patch dulwich's read_pkt_refs so that we can determine - # on clone which bookmark to activate - client.read_pkt_refs = compat.read_pkt_refs - ret = localclient.fetch_pack( - path, determine_wants, graphwalker, f.write, gitprogress.progress - ) - if f.tell() != 0: - f.seek(0) - self.git.object_store.add_thin_pack(f.read, None) - - # For empty repos dulwich may give us None. Alternatively, it may - # give us an object which is normally iterable, but because of a - # bug, the empty version can raise exceptions if treated like a - # sequence. In either case, replace it with an empty iterable. - if ret is None or getattr(ret, "refs", ()) is None: - ret = {} - return ret - except (HangupException, GitProtocolError) as e: - raise error.Abort(_("git remote error: ") + str(e)) - - # REFERENCES HANDLING - - def filter_refs(self, refs, heads): - """For a dictionary of refs: shas, if heads is None then return refs - that match the heads. Otherwise, return refs that are heads or tags. - - """ - filteredrefs = [] - if heads is not None: - # contains pairs of ('refs/(heads|tags|...)/foo', 'foo') - # if ref is just '', then we get ('foo', 'foo') - stripped_refs = [(r, r[r.find(b"/", r.find(b"/") + 1) + 1 :]) for r in refs] - for h in heads: - h = pycompat.encodeutf8(h) - if h.endswith(b"/*"): - prefix = h[:-1] # include the / but not the * - r = [ - pair[0] for pair in stripped_refs if pair[1].startswith(prefix) - ] - r.sort() - filteredrefs.extend(r) - else: - r = [pair[0] for pair in stripped_refs if pair[1] == h] - if not r: - raise error.Abort("ref %s not found on remote server" % h) - elif len(r) == 1: - filteredrefs.append(r[0]) - else: - raise error.Abort("ambiguous reference %s: %r" % (h, r)) - else: - for ref, sha in pycompat.iteritems(refs): - if not ref.endswith(b"^{}") and ( - ref.startswith(b"refs/heads/") or ref.startswith(b"refs/tags/") - ): - filteredrefs.append(ref) - filteredrefs.sort() - - # the choice of OrderedDict vs plain dict has no impact on stock - # hg-git, but allows extensions to customize the order in which refs - # are returned - return util.OrderedDict((r, refs[r]) for r in filteredrefs) - - def filter_min_date(self, refs): - """filter refs by minimum date - - This only works for refs that are available locally.""" - min_date = compat.config(self.ui, "string", "git", "mindate") - if min_date is None: - return refs - - # filter refs older than min_timestamp - min_timestamp, min_offset = hgutil.parsedate(min_date) - - def check_min_time(obj): - if isinstance(obj, Tag): - return obj.tag_time >= min_timestamp - else: - return obj.commit_time >= min_timestamp - - return util.OrderedDict( - (ref, sha) - for ref, sha in pycompat.iteritems(refs) - if check_min_time(self.git[sha]) - ) - - def update_references(self): - exportable = self.get_exportable() - - # Create a local Git branch name for each - # Mercurial bookmark. - for hg_sha, refs in pycompat.iteritems(exportable): - for git_ref in refs.heads: - git_sha = self.map_git_get(hg_sha) - if git_sha: - self.git.refs[pycompat.encodeutf8(git_ref)] = pycompat.encodeutf8( - git_sha - ) - - def _filter_for_bookmarks(self, bms): - if not self.branch_bookmark_suffix: - return [(bm, bm) for bm in bms] - else: - - def _filter_bm(bm): - if bm.endswith(self.branch_bookmark_suffix): - return bm[0 : -(len(self.branch_bookmark_suffix))] - else: - return bm - - return [(_filter_bm(bm), bm) for bm in bms] - - def get_exportable(self): - class heads_tags(object): - def __init__(self): - self.heads = set() - self.tags = set() - - def __iter__(self): - return itertools.chain(self.heads, self.tags) - - def __nonzero__(self): - return bool(self.heads) or bool(self.tags) - - __bool__ = __nonzero__ - - res = collections.defaultdict(heads_tags) - - bms = self.repo._bookmarks - for filtered_bm, bm in self._filter_for_bookmarks(bms): - res[hex(bms[bm])].heads.add("refs/heads/" + filtered_bm) - for tag, sha in pycompat.iteritems(self.tags): - res[sha].tags.add("refs/tags/" + tag) - return res - - def update_hg_bookmarks(self, refs): - try: - bms = self.repo._bookmarks - - heads = dict( - [ - (ref[11:], refs[ref]) - for ref in refs - if ref.startswith(b"refs/heads/") - ] - ) - - suffix = self.branch_bookmark_suffix or "" - changes = [] - for head, sha in pycompat.iteritems(heads): - # refs contains all the refs in the server, not just - # the ones we are pulling - hgsha = self.map_hg_get(sha) - if hgsha is None: - continue - hgsha = bin(hgsha) - head = pycompat.decodeutf8(head) - if head not in bms: - # new branch - changes.append((head + suffix, hgsha)) - else: - bm = self.repo[bms[head]] - if bm.ancestor(self.repo[hgsha]) == bm: - # fast forward - changes.append((head + suffix, hgsha)) - - if heads: - util.updatebookmarks(self.repo, changes) - - except AttributeError: - self.ui.warn( - _("creating bookmarks failed, do you have" " bookmarks enabled?\n") - ) - - def update_remote_branches(self, remote_name, refs): - remote_refs = self.remote_refs - # since we re-write all refs for this remote each time, prune - # all entries matching this remote from our refs list now so - # that we avoid any stale refs hanging around forever - for t in list(remote_refs): - if t.startswith(remote_name + "/"): - del remote_refs[t] - for ref_name, sha in pycompat.iteritems(refs): - if ref_name.startswith(b"refs/heads"): - hgsha = self.map_hg_get(sha) - if hgsha is None or hgsha not in self.repo: - continue - head = pycompat.decodeutf8(ref_name[11:]) - remote_refs["/".join((remote_name, head))] = bin(hgsha) - # TODO(durin42): what is this doing? - new_ref = pycompat.encodeutf8( - "refs/remotes/%s/%s" % (remote_name, head) - ) - self.git.refs[new_ref] = sha - elif ref_name.startswith(b"refs/tags") and not ref_name.endswith(b"^{}"): - self.git.refs[ref_name] = sha - - # UTILITY FUNCTIONS - - def convert_git_int_mode(self, mode): - # TODO: make these into constants - convert = {0o100644: "", 0o100755: "x", 0o120000: "l"} - if mode in convert: - return convert[mode] - return "" - - 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, detect_renames): - tree = commit.tree - btree = None - - if commit.parents: - btree = self.git[commit.parents[0]].tree - - files = {} - gitlinks = {} - renames = None - rename_detector = None - if detect_renames: - renames = {} - rename_detector = self._rename_detector - - # this set is unused if rename detection isn't enabled -- that makes - # the code below simpler - renamed_out = set() - - changes = diff_tree.tree_changes( - self.git.object_store, btree, tree, rename_detector=rename_detector - ) - - for change in changes: - oldfile, oldmode, oldsha = change.old - newfile, newmode, newsha = change.new - if oldfile: - oldfile = pycompat.decodeutf8(oldfile) - if newfile: - newfile = pycompat.decodeutf8(newfile) - # actions are described by the following table ('no' means 'does - # not exist'): - # old new | action - # no file | record file - # no gitlink | record gitlink - # file no | delete file - # file file | record file - # file gitlink | delete file and record gitlink - # gitlink no | delete gitlink - # gitlink file | delete gitlink and record file - # gitlink gitlink | record gitlink - # - # There's an edge case here -- symlink <-> regular file transitions - # are returned by dulwich as separate deletes and adds, not - # modifications. The order of those results is unspecified and - # could be either way round. Handle both cases: delete first, then - # add -- delete stored in 'old = file' case, then overwritten by - # 'new = file' case. add first, then delete -- record stored in - # 'new = file' case, then membership check fails in 'old = file' - # case so is not overwritten there. This is not an issue for - # gitlink <-> {symlink, regular file} transitions because they - # write to separate dictionaries. - # - # There's a similar edge case when rename detection is enabled: if - # a file is renamed and then replaced by a symlink (typically to - # the new location), it is returned by dulwich as an add and a - # rename. The order of those results is unspecified. Handle both - # cases: rename first, then add -- delete stored in 'new = file' - # case with renamed_out, then renamed_out check passes in 'old = - # file' case so is overwritten. add first, then rename -- add - # stored in 'old = file' case, then membership check fails in 'new - # = file' case so is overwritten. - if newmode == 0o160000: - # new = gitlink - gitlinks[newfile] = newsha - if change.type == diff_tree.CHANGE_RENAME: - # don't record the rename because only file -> file renames - # make sense in Mercurial - gitlinks[oldfile] = None - if oldmode is not None and oldmode != 0o160000: - # file -> gitlink - files[oldfile] = True, None, None - continue - if oldmode == 0o160000 and newmode != 0o160000: - # gitlink -> no/file (gitlink -> gitlink is covered above) - gitlinks[oldfile] = None - continue - if newfile is not None: - self.audit_hg_path(newfile) - # new = file - files[newfile] = False, newmode, newsha - if renames is not None and newfile != oldfile: - renames[newfile] = oldfile - renamed_out.add(oldfile) - # the membership check is explained in a comment above - if change.type == diff_tree.CHANGE_RENAME and oldfile not in files: - files[oldfile] = True, None, None - else: - # old = file - # files renamed_out | action - # no * | write - # yes no | ignore - # yes yes | write - if oldfile not in files or oldfile in renamed_out: - files[oldfile] = True, None, None - - return files, gitlinks, renames - - @hgutil.propertycache - def _rename_detector(self): - # disabled by default to avoid surprises - similarity = compat.config(self.ui, "int", "git", "similarity") - if similarity < 0 or similarity > 100: - raise error.Abort(_("git.similarity must be between 0 and 100")) - if similarity == 0: - return None - - # default is borrowed from Git - max_files = compat.config(self.ui, "int", "git", "renamelimit") - if max_files < 0: - raise error.Abort(_("git.renamelimit must be non-negative")) - if max_files == 0: - max_files = None - - find_copies_harder = compat.config(self.ui, "bool", "git", "findcopiesharder") - return diff_tree.RenameDetector( - self.git.object_store, - rename_threshold=similarity, - max_files=max_files, - find_copies_harder=find_copies_harder, - ) - - def parse_gitmodules(self, tree_obj): - """Parse .gitmodules from a git tree specified by tree_obj - - :return: list of tuples (submodule path, url, name), - where name is quoted part of the section's name, or - empty list if nothing found - """ - rv = [] - try: - unused_mode, gitmodules_sha = tree_obj[".gitmodules"] - except KeyError: - return rv - gitmodules_content = self.git[gitmodules_sha].data - fo = pycompat.stringio(gitmodules_content) - tt = dul_config.ConfigFile.from_file(fo) - for section in tt.keys(): - section_kind, section_name = section - if section_kind == "submodule": - sm_path = tt.get(section, "path") - sm_url = tt.get(section, "url") - rv.append((sm_path, sm_url, section_name)) - return rv - - def git_file_readlines(self, tree_obj, fname): - """Read content of a named entry from the git commit tree - - :return: list of lines - """ - if fname in tree_obj: - unused_mode, sha = tree_obj[fname] - content = self.git[sha].data - return content.splitlines() - return [] - - def remote_name(self, remote): - names = [name for name, path in self.paths if path == remote] - if names: - return names[0] - - def audit_hg_path(self, path): - if ".hg" in path.split(os.path.sep): - if compat.config(self.ui, "bool", "git", "blockdothg"): - raise error.Abort( - ("Refusing to import problematic path %r" % path), - hint=( - "Mercurial cannot check out paths inside nested " - + "repositories; if you need to continue, then set " - + "'[git] blockdothg = false' in your hgrc." - ), - ) - self.ui.warn( - ( - "warning: path %r is within a nested repository, " - + "which Mercurial cannot check out.\n" - ) - % path - ) - - # Stolen from hgsubversion - def swap_out_encoding(self, new_encoding="UTF-8"): - try: - from edenscm.mercurial import encoding - - old = encoding.encoding - encoding.encoding = new_encoding - except (AttributeError, 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): - """Method that sets up the transport (either ssh or http(s)) - - Tests: - - >>> from collections import namedtuple - >>> from dulwich.client import HttpGitClient, SSHGitClient - >>> from edenscm.mercurial.ui import ui - >>> mockrepo = namedtuple('localrepo', ['sharedvfs']) - >>> mockrepo.sharedvfs = '' - >>> g = GitHandler(mockrepo, ui()) - >>> client, url = g.get_transport_and_path('http://fqdn.com/test.git') - >>> print isinstance(client, HttpGitClient) - True - >>> print url - http://fqdn.com/test.git - >>> client, url = g.get_transport_and_path('git@fqdn.com:user/repo.git') - >>> print isinstance(client, SSHGitClient) - True - >>> print url - user/repo.git - >>> print client.host - git@fqdn.com - """ - # 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) - - # test for raw git ssh uri here so that we can reuse the logic below - if util.isgitsshuri(uri): - uri = "git+ssh://" + uri - - git_match = RE_GIT_URI.match(uri) - if git_match: - res = git_match.groupdict() - host, port, sepr = res["host"], res["port"], res["sepr"] - transport = client.TCPGitClient - if "ssh" in res["scheme"]: - util.checksafessh(host) - transport = client.SSHGitClient - path = res["path"] - if sepr == "/" and not path.startswith("~"): - path = "/" + path - # strip trailing slash for heroku-style URLs - # ssh+git://git@heroku.com:project.git/ - if sepr == ":" and path.endswith(".git/"): - path = path.rstrip("/") - if port: - client.port = port - - return transport(host, port=port), path - - if uri.startswith("git+http://") or uri.startswith("git+https://"): - uri = uri[4:] - - if uri.startswith("http://") or uri.startswith("https://"): - pmgr = compat.passwordmgr(self.ui) - auth = hgutil.urlreq.HTTPBasicAuthHandler(pmgr) - - opener = hgutil.urlreq.build_opener(auth) - ua = "git/20x6 (hg-git ; uses dulwich and hg ; like git-core)" - opener.addheaders = [("User-Agent", ua)] - try: - return client.HttpGitClient(uri, opener=opener), uri - except TypeError as e: - if e.message.find("unexpected keyword argument 'opener'") >= 0: - # Dulwich 0.9.4, which is the latest version that ships - # with Ubuntu 14.04, doesn't support the 'opener' keyword. - # Try without authentication. - return client.HttpGitClient(uri), uri - else: - raise - - # if its not git or git+ssh, try a local url.. - return client.SubprocessGitClient(), uri - - -class GitMap(object): - def __init__(self, content): - mapgit = {} - maphg = {} - for line in content: - # format is <40 hex digits> <40 hex digits>\n - if len(line) != 82: - raise ValueError( - _("corrupt mapfile: incorrect line length %d %s") - % (len(line), content) - ) - gitnode = bin(line[:40]) - hgnode = bin(line[41:81]) - mapgit[gitnode] = hgnode - maphg[hgnode] = gitnode - self._mapgit = mapgit - self._maphg = maphg - - def lookupbyfirst(self, gitnode): - return self._mapgit.get(gitnode) - - def lookupbysecond(self, hgnode): - return self._maphg.get(hgnode) - - def add(self, gitnode, hgnode): - self._mapgit[gitnode] = hgnode - self._maphg[hgnode] = gitnode - - def items(self): - return self._mapgit.items() diff --git a/eden/scm/edenscm/hgext/hggit/gitrepo.py b/eden/scm/edenscm/hgext/hggit/gitrepo.py deleted file mode 100644 index 2e33b5492d..0000000000 --- a/eden/scm/edenscm/hgext/hggit/gitrepo.py +++ /dev/null @@ -1,116 +0,0 @@ -from edenscm.mercurial import error, pycompat, util -from edenscm.mercurial.error import RepoError - -from .util import isgitsshuri - - -peerapi = False -try: - from edenscm.mercurial.repository import peer as peerrepository - - peerapi = True -except ImportError: - # pyre-fixme[21]: Could not find name `peerrepository` in `edenscm.mercurial.peer`. - from edenscm.mercurial.peer import peerrepository - - -class gitrepo(peerrepository): - def __init__(self, ui, path, create): - if create: # pragma: no cover - raise error.Abort("Cannot create a git repository.") - self._ui = ui - self.path = path - self.localrepo = None - - _peercapabilities = ["lookup"] - - def _capabilities(self): - return self._peercapabilities - - def capabilities(self): - return self._peercapabilities - - @property - def ui(self): - return self._ui - - def url(self): - return self.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): - if namespace == "namespaces": - return {"bookmarks": ""} - elif namespace == "bookmarks": - if self.localrepo is not None: - handler = self.localrepo.githandler - refs = handler.fetch_pack(self.path, heads=[]) - # map any git shas that exist in hg to hg shas - stripped_refs = dict( - [ - ( - pycompat.decodeutf8(ref[11:]), - handler.map_hg_get(refs[ref]) or refs[ref], - ) - for ref in refs.keys() - if ref.startswith(b"refs/heads/") - ] - ) - return stripped_refs - return {} - - def pushkey(self, namespace, key, old, new): - return False - - if peerapi: - - def branchmap(self): - raise NotImplementedError - - def canpush(self): - return True - - def close(self): - pass - - def debugwireargs(self): - raise NotImplementedError - - def getbundle(self): - raise NotImplementedError - - def iterbatch(self): - raise NotImplementedError - - def known(self): - raise NotImplementedError - - def peer(self): - return self - - def stream_out(self, shallow=False): - raise NotImplementedError - - def unbundle(self): - raise NotImplementedError - - -instance = gitrepo - - -def islocal(path): - if isgitsshuri(path): - return True - - u = util.url(path) - return not u.scheme or u.scheme == "file" diff --git a/eden/scm/edenscm/hgext/hggit/help/git.rst b/eden/scm/edenscm/hgext/hggit/help/git.rst deleted file mode 100644 index 596f7ff1a7..0000000000 --- a/eden/scm/edenscm/hgext/hggit/help/git.rst +++ /dev/null @@ -1,78 +0,0 @@ -Basic Use ---------- - -You can clone a Git repository from Hg by running `hg clone [dest]`. -For example, if you were to run:: - - $ hg clone git://github.com/schacon/hg-git.git - -Hg-Git would clone the repository and convert it to an Hg repository for -you. There are a number of different protocols that can be used for Git -repositories. Examples of Git repository URLs include:: - - https://github.com/schacon/hg-git.git - http://code.google.com/p/guava-libraries - ssh://git@github.com:schacon/hg-git.git - git://github.com/schacon/hg-git.git - ../hg-git (local file path) - -For the HTTP, HTTPS, and SSH protocols, it isn't clear based solely on -the URL whether the remote repository should be treated as a Mercurial -repository or a Git repository. Thus, to specify that a URL should -use Git, prepend the URL with "git+". For example, an HTTPS URL would -start with "git+https://". Also, note that Git doesn't require the -specification of the protocol for SSH, but Mercurial does. Hg-Git -automatically detects whether file paths should be treated as Git repositories -by their contents. - -If you are starting from an existing Hg repository, you have to set up a -Git repository somewhere that you have push access to, add a path entry -for it in your .hg/hgrc file, and then run `hg push [name]` from within -your repository. 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 to the -Git server. - -Pulling new revisions into a repository is the same as from any other -Mercurial source. Within the earlier examples, the following commands are -all equivalent:: - - $ hg pull - $ hg pull default - $ hg pull git://github.com/schacon/hg-git.git - -Git branches are exposed in Hg as bookmarks, while Git remotes are exposed -as Hg local tags. See `hg help bookmarks` and `hg help tags` for further -information. - -Finding and displaying Git revisions ------------------------------------- - -For displaying the Git revision ID, Hg-Git provides a template keyword: - - :gitnode: String. The Git changeset identification hash, as a 40 hexadecimal - digit string. - -For example:: - - $ hg log --template='{rev}:{node|short}:{gitnode|short} {desc}\n' - $ hg log --template='hg: {node}\ngit: {gitnode}\n{date|isodate} {author}\n{desc}\n\n' - -For finding changesets from Git, Hg-Git extends revsets to provide two new -selectors: - - :fromgit: Select changesets that originate from Git. Takes no arguments. - :gitnode: Select changesets that originate in a specific Git revision. Takes - a revision argument. - -For example:: - - $ hg log -r 'fromgit()' - $ hg log -r 'gitnode(84f75b909fc3)' - -Revsets are accepted by several Mercurial commands for specifying revisions. -See ``hg help revsets`` for details. diff --git a/eden/scm/edenscm/hgext/hggit/hg2git.py b/eden/scm/edenscm/hgext/hggit/hg2git.py deleted file mode 100644 index 15dd051fcf..0000000000 --- a/eden/scm/edenscm/hgext/hggit/hg2git.py +++ /dev/null @@ -1,409 +0,0 @@ -# This file contains code dealing specifically with converting Mercurial -# repositories to Git repositories. Code in this file is meant to be a generic -# library and should be usable outside the context of hg-git or an hg command. - -import os -import stat - -import dulwich.objects as dulobjs -from edenscm.mercurial import pycompat, util as hgutil -from edenscm.mercurial.i18n import _ - -from . import compat, util - - -def audit_git_path(ui, path): - r"""Check for path components that case-fold to .git. - - >>> class fakeui(object): - ... def configbool(*args): - ... return False - ... def warn(self, s): - ... print s - >>> u = fakeui() - >>> audit_git_path(u, 'foo/git~100/wat') - warning: path 'foo/git~100/wat' contains a dangerous path component. - It may not be legal to check out in Git. - It may also be rejected by some git server configurations. - - >>> audit_git_path(u, u'foo/.gi\u200ct'.encode('utf-8')) - warning: path 'foo/.gi\xe2\x80\x8ct' contains a dangerous path component. - It may not be legal to check out in Git. - It may also be rejected by some git server configurations. - - >>> audit_git_path(u, 'this/is/safe') - """ - dangerous = False - for c in path.split(os.path.sep): - if compat.hfsignoreclean(c) == ".git": - dangerous = True - break - elif "~" in c: - base, tail = c.split("~", 1) - if tail.isdigit() and base.upper().startswith("GIT"): - dangerous = True - break - if dangerous: - if compat.config(ui, "bool", "git", "blockdotgit"): - raise hgutil.Abort( - _("Refusing to export likely-dangerous path %r") % path, - hint=_( - "If you need to continue, read about CVE-2014-9390 and " - "then set '[git] blockdotgit = false' in your hgrc." - ), - ) - ui.warn( - _( - "warning: path %r contains a dangerous path component.\n" - "It may not be legal to check out in Git.\n" - "It may also be rejected by some git server configurations.\n" - ) - % path - ) - - -class GitTreeDict(object): - """A mutable structure pretending to be a fullpath->tree dictionary of all the trees - in the given commit. - - Trees are lazily loaded as needed, and any path that is set has its parents - automatically loaded/created as well. - """ - - def __init__(self, store, commit): - self.store = store - self.trees = {} - self.trees[""] = store[commit.tree] if commit is not None else dulobjs.Tree() - - def __getitem__(self, path): - assert isinstance(path, str) - value = self.get(path) - if value is None: - raise KeyError("no path %s" % path) - return value - - def get(self, path, default=None): - assert isinstance(path, str) - value = self.trees.get(path) - if value is None: - # It's not in our cache, so let's find the parent so we can add this - # entry. - if path == "": - raise KeyError("missing required '' root") - base, name = os.path.split(path) - parent = self.get(base) - name = pycompat.encodeutf8(name) - if parent is None or name not in parent: - return default - - # Load the missing child tree - child_mode, child_id = parent[name] - if child_mode != stat.S_IFDIR: - raise KeyError("trying to set non-tree child %s" % path) - - value = self.store[child_id] - self.trees[path] = value - - return value - - def __setitem__(self, path, value): - assert isinstance(path, str) - base, name = os.path.split(path) - parent = self.get(base) - if parent is None: - # Empty trees will be filled during finalization (see comment below) - self[base] = dulobjs.Tree() - # In an ideal world we would assign the child to the parent here, but - # parents store a reference to the child's id which we don't have since - # the tree is still being mutated. Instead we create empty parents where - # needed, and later in _populate_tree_entries we attach all the children - # to parents bottom-up. - self.trees[path] = value - - def __delitem__(self, path): - assert isinstance(path, str) - if path == "": - raise KeyError("cannot delete root path") - del self.trees[path] - - def setdefault(self, path, default): - assert isinstance(path, str) - value = self.get(path) - if value is None: - value = default - self[path] = value - - return value - - -class IncrementalChangesetExporter(object): - """Incrementally export Mercurial changesets to Git trees. - - The purpose of this class is to facilitate Git tree export that is more - optimal than brute force. - - A "dumb" implementations of Mercurial to Git export would iterate over - every file present in a Mercurial changeset and would convert each to - a Git blob and then conditionally add it to a Git repository if it didn't - yet exist. This is suboptimal because the overhead associated with - obtaining every file's raw content and converting it to a Git blob is - not trivial! - - This class works around the suboptimality of brute force export by - leveraging the information stored in Mercurial - the knowledge of what - changed between changesets - to only export Git objects corresponding to - changes in Mercurial. In the context of converting Mercurial repositories - to Git repositories, we only export objects Git (possibly) hasn't seen yet. - This prevents a lot of redundant work and is thus faster. - - Callers instantiate an instance of this class against a mercurial.localrepo - instance. They then associate it with a specific changesets by calling - update_changeset(). On each call to update_changeset(), the instance - computes the difference between the current and new changesets and emits - Git objects that haven't yet been encountered during the lifetime of the - class instance. In other words, it expresses Mercurial changeset deltas in - terms of Git objects. Callers then (usually) take this set of Git objects - and add them to the Git repository. - - This class only emits Git blobs and trees, not commits. - - The tree calculation part of this class is essentially a reimplementation - of dulwich.index.commit_tree. However, since our implementation reuses - Tree instances and only recalculates SHA-1 when things change, we are - more efficient. - """ - - def __init__(self, hg_repo, start_ctx, git_store, git_commit): - """Create an instance against a mercurial.localrepo. - - start_ctx: the context for a Mercurial commit that has a Git - equivalent, passed in as git_commit. The incremental - computation will be started from this commit. - git_store: the Git object store the commit comes from. - - start_ctx can be repo[nullid], in which case git_commit should be None. - """ - self._hg = hg_repo - - # Our current revision's context. - self._ctx = start_ctx - - # Path to dulwich.objects.Tree. - self._dirs = GitTreeDict(git_store, git_commit) - - # Mercurial file nodeid to Git blob SHA-1. Used to prevent redundant - # blob calculation. - self._blob_cache = {} - - @property - def root_tree_sha(self): - """The SHA-1 of the root Git tree. - - This is needed to construct a Git commit object. - """ - return self._dirs[""].id - - def update_changeset(self, newctx): - """Set the tree to track a new Mercurial changeset. - - This is a generator of 2-tuples. The first item in each tuple is a - dulwich object, either a Blob or a Tree. The second item is the - corresponding Mercurial nodeid for the item, if any. Only blobs will - have nodeids. Trees do not correspond to a specific nodeid, so it does - not make sense to emit a nodeid for them. - - When exporting trees from Mercurial, callers typically write the - returned dulwich object to the Git repo via the store's add_object(). - - Some emitted objects may already exist in the Git repository. This - class does not know about the Git repository, so it's up to the caller - to conditionally add the object, etc. - - Emitted objects are those that have changed since the last call to - update_changeset. If this is the first call to update_chanageset, all - objects in the tree are emitted. - """ - # Our general strategy is to accumulate dulwich.objects.Blob and - # dulwich.objects.Tree instances for the current Mercurial changeset. - # We do this incremental by iterating over the Mercurial-reported - # changeset delta. We rely on the behavior of Mercurial to lazy - # calculate a Tree's SHA-1 when we modify it. This is critical to - # performance. - - # In theory we should be able to look at changectx.files(). This is - # *much* faster. However, it may not be accurate, especially with older - # repositories, which may not record things like deleted files - # explicitly in the manifest (which is where files() gets its data). - # The only reliable way to get the full set of changes is by looking at - # the full manifest. And, the easy way to compare two manifests is - # localrepo.status(). - modified, added, removed = self._hg.status(self._ctx, newctx)[0:3] - - # We track which directories/trees have modified in this update and we - # only export those. - dirty_trees = set() - - for path in removed: - self._remove_path(path, dirty_trees) - - # For every file that changed or was added, we need to calculate the - # corresponding Git blob and its tree entry. We emit the blob - # immediately and update trees to be aware of its presence. - for path in set(modified) | set(added): - audit_git_path(self._hg.ui, path) - d = os.path.dirname(path) - tree = self._dirs.setdefault(d, dulobjs.Tree()) - dirty_trees.add(d) - - fctx = newctx[path] - - func = IncrementalChangesetExporter.tree_entry - entry, blob = func(fctx, self._blob_cache) - if blob is not None: - yield (blob, fctx.filenode()) - - tree.add(*entry) - - # Now that all the trees represent the current changeset, recalculate - # the tree IDs and emit them. Note that we wait until now to calculate - # tree SHA-1s. This is an important difference between us and - # dulwich.index.commit_tree(), which builds new Tree instances for each - # series of blobs. - for obj in self._populate_tree_entries(dirty_trees): - yield (obj, None) - - self._ctx = newctx - - def _remove_path(self, path, dirty_trees): - """Remove a path (file or git link) from the current changeset. - - If the tree containing this path is empty, it might be removed.""" - d = os.path.dirname(path) - tree = self._dirs.get(d, dulobjs.Tree()) - - del tree[pycompat.encodeutf8(os.path.basename(path))] - dirty_trees.add(d) - - # If removing this file made the tree empty, we should delete this - # tree. This could result in parent trees losing their only child - # and so on. - if not len(tree): - self._remove_tree(d) - else: - self._dirs[d] = tree - - def _remove_tree(self, path): - """Remove a (presumably empty) tree from the current changeset. - - A now-empty tree may be the only child of its parent. So, we traverse - up the chain to the root tree, deleting any empty trees along the way. - """ - try: - del self._dirs[path] - except KeyError: - return - - # Now we traverse up to the parent and delete any references. - if path == "": - return - - basename = os.path.basename(path) - parent = os.path.dirname(path) - while True: - tree = self._dirs.get(parent, None) - - # No parent entry. Nothing to remove or update. - if tree is None: - return - - try: - del tree[pycompat.encodeutf8(basename)] - except KeyError: - return - - if len(tree): - return - - if parent == "": - return - - # The parent tree is empty. Se, we can delete it. - del self._dirs[parent] - - basename = os.path.basename(parent) - parent = os.path.dirname(parent) - - def _populate_tree_entries(self, dirty_trees): - self._dirs.setdefault("", dulobjs.Tree()) - - for dirty in list(dirty_trees): - parent = os.path.dirname(dirty) - - while parent != "": - if parent in dirty_trees: - break - - dirty_trees.add(parent) - parent = os.path.dirname(parent) - - # The root tree is always dirty but doesn't always get updated. - dirty_trees.add("") - - # We only need to recalculate and export dirty trees. - for d in sorted(dirty_trees, key=len, reverse=True): - # Only happens for deleted directories. - try: - tree = self._dirs[d] - except KeyError: - continue - - yield tree - - if d == "": - continue - - parent_tree = self._dirs[os.path.dirname(d)] - - # Accessing the tree's ID is what triggers SHA-1 calculation and is - # the expensive part (at least if the tree has been modified since - # the last time we retrieved its ID). Also, assigning an entry to a - # tree (even if it already exists) invalidates the existing tree - # and incurs SHA-1 recalculation. So, it's in our interest to avoid - # invalidating trees. Since we only update the entries of dirty - # trees, this should hold true. - parent_tree[pycompat.encodeutf8(os.path.basename(d))] = ( - stat.S_IFDIR, - tree.id, - ) - - @staticmethod - def tree_entry(fctx, blob_cache): - """Compute a dulwich TreeEntry from a filectx. - - A side effect is the TreeEntry is stored in the passed cache. - - Returns a 2-tuple of (dulwich.objects.TreeEntry, dulwich.objects.Blob). - """ - blob_id = blob_cache.get(fctx.filenode(), None) - blob = None - - if blob_id is None: - blob = dulobjs.Blob.from_string(fctx.data()) - blob_id = blob.id - blob_cache[fctx.filenode()] = blob_id - - flags = fctx.flags() - - if "l" in flags: - mode = 0o120000 - elif "x" in flags: - mode = 0o100755 - else: - mode = 0o100644 - - return ( - dulobjs.TreeEntry( - pycompat.encodeutf8(os.path.basename(fctx.path())), mode, blob_id - ), - blob, - ) diff --git a/eden/scm/edenscm/hgext/hggit/hgrepo.py b/eden/scm/edenscm/hgext/hggit/hgrepo.py deleted file mode 100644 index 7a4d7f239b..0000000000 --- a/eden/scm/edenscm/hgext/hggit/hgrepo.py +++ /dev/null @@ -1,52 +0,0 @@ -# Copyright (c) Facebook, Inc. and its affiliates. -# -# This software may be used and distributed according to the terms of the -# GNU General Public License version 2. - -from edenscm.mercurial import localrepo, pycompat, util as hgutil -from edenscm.mercurial.node import bin - -from . import util -from .git_handler import GitHandler -from .gitrepo import gitrepo - - -def generate_repo_subclass(baseclass): - class hgrepo(baseclass): - @util.transform_notgit - def findoutgoing(self, remote, base=None, heads=None, force=False): - if isinstance(remote, gitrepo): - base, heads = self.githandler.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() - - for tag, rev in pycompat.iteritems(self.githandler.tags): - if isinstance(tag, pycompat.unicode): - tag = tag.encode("utf-8") - tags[tag] = bin(rev) - tagtypes[tag] = "git" - for tag, rev in pycompat.iteritems(self.githandler.remote_refs): - if isinstance(tag, pycompat.unicode): - tag = tag.encode("utf-8") - tags[tag] = rev - tagtypes[tag] = "git-remote" - tags.update(self.githandler.remote_refs) - return (tags, tagtypes) - - @hgutil.propertycache - def githandler(self): - """get the GitHandler for an hg repo - - This only makes sense if the repo talks to at least one git remote. - """ - return GitHandler(self, self.ui) - - def tags(self): - return {} - - return hgrepo diff --git a/eden/scm/edenscm/hgext/hggit/overlay.py b/eden/scm/edenscm/hgext/hggit/overlay.py deleted file mode 100644 index 30f06dbb18..0000000000 --- a/eden/scm/edenscm/hgext/hggit/overlay.py +++ /dev/null @@ -1,548 +0,0 @@ -# overlay classes for repositories -# unifies access to unimported git objects and committed hg objects -# designed to support incoming -# -# incomplete, implemented on demand - -from edenscm.mercurial import ( - ancestor, - bookmarks, - changelog, - context, - manifest, - match as matchmod, - pycompat, - util, -) -from edenscm.mercurial.node import bin, hex, nullid -from edenscm.mercurial.pycompat import basestring - - -def _maybehex(n): - if len(n) == 20: - return hex(n) - return n - - -class overlaymanifest(object): - def __init__(self, repo, sha): - self.repo = repo - self.tree = repo.handler.git.get_object(sha) - self._map = None - self._flags = None - - def withflags(self): - self.load() - return set( - [path for path, flag in pycompat.iteritems(self._flags) if flag != ""] - ) - - def copy(self): - return overlaymanifest(self.repo, self.tree.id) - - def keys(self): - self.load() - return self._map.keys() - - def iterkeys(self): - return iter(self.keys()) - - def load(self): - if self._map is not None: - return - - self._map = {} - self._flags = {} - - def hgflag(gitflag): - if gitflag & 0o100: - return "x" - elif gitflag & 0o20000: - return "l" - else: - return "" - - def addtree(tree, dirname): - for entry in pycompat.iteritems(tree): - if entry.mode & 0o40000: - # expand directory - subtree = self.repo.handler.git.get_object(entry.sha) - addtree(subtree, dirname + pycompat.decodeutf8(entry.path) + "/") - else: - path = dirname + pycompat.decodeutf8(entry.path) - self._map[path] = bin(entry.sha) - self._flags[path] = hgflag(entry.mode) - - addtree(self.tree, "") - - def matches(self, match): - """generate a new manifest filtered by the match argument""" - if match.always(): - return self.copy() - - mf = self.copy() - for fn in mf.keys(): - if not match(fn): - del mf[fn] - return mf - - def iteritems(self): - self.load() - return pycompat.iteritems(self._map) - - items = iteritems - - def __iter__(self): - self.load() - return self._map.__iter__() - - def __getitem__(self, path): - self.load() - return self._map[path] - - def __contains__(self, path): - self.load() - return path in self._map - - def get(self, path, default=None): - self.load() - return self._map.get(path, default) - - def diff(self, m2, matcher=None): - # Older mercurial clients used diff(m2, clean=False). If a caller failed - # to specify clean as a keyword arg, it might get passed as match here. - assert not isinstance(matcher, bool), "match must inherit from basematcher" - - self.load() - if isinstance(m2, overlaymanifest): - m2.load() - - # below code copied from manifest.py:manifestdict.diff - diff = {} - - try: - m2flagget = m2.flags - except AttributeError: - # Mercurial <= 3.3 - m2flagget = m2._flags.get - - if matcher is None: - matcher = matchmod.always("", "") - for fn, n1 in pycompat.iteritems(self): - if not matcher(fn): - continue - fl1 = self._flags.get(fn, "") - n2 = m2.get(fn, None) - fl2 = m2flagget(fn, "") - if n2 is None: - fl2 = "" - if n1 != n2 or fl1 != fl2: - diff[fn] = ((n1, fl1), (n2, fl2)) - - for fn, n2 in pycompat.iteritems(m2): - if fn not in self: - if not matcher(fn): - continue - fl2 = m2flagget(fn, "") - diff[fn] = ((None, ""), (n2, fl2)) - - return diff - - def __delitem__(self, path): - del self._map[path] - - -def wrapmanifestdictdiff(orig, self, m2, matcher=None): - """avoid calling into lazymanifest code if m2 is an overlaymanifest""" - # Older mercurial clients used diff(m2, clean=False). If a caller failed - # to specify clean as a keyword arg, it might get passed as match here. - assert not isinstance(matcher, bool), "match must inherit from basematcher" - - kwargs = {} - # Older versions of mercurial don't support the match arg, so only add it if - # it exists. - if matcher is not None: - kwargs["matcher"] = matcher - if isinstance(m2, overlaymanifest): - diff = m2.diff(self, **kwargs) - # since we calculated the diff with m2 vs m1, flip it around - for fn in diff: - c1, c2 = diff[fn] - diff[fn] = c2, c1 - return diff - else: - return orig(self, m2, **kwargs) - - -class overlayfilectx(object): - def __init__(self, repo, path, fileid=None): - self._repo = repo - self._path = path - self.fileid = fileid - - def repo(self): - return self._repo - - # this is a hack to skip copy detection - def ancestors(self): - return [self, self] - - def filenode(self): - return nullid - - 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(_maybehex(self.fileid)) - return blob.data - - def isbinary(self): - return util.binary(self.data()) - - -class overlaychangectx(context.changectx): - def __init__(self, repo, sha): - # Can't store this in self._repo because the base class uses that field - self._hgrepo = repo - if not isinstance(sha, basestring): - sha = sha.hex() - self.commit = repo.handler.git.get_object(_maybehex(sha)) - self._overlay = getattr(repo, "gitoverlay", repo) - self._node = bin(self.commit.id) - - def repo(self): - return self._hgrepo - - def node(self): - # type: () -> bytes - return self._node - - def rev(self): - # type: () -> int - return self._rev - - def date(self): - return self.commit.author_time, self.commit.author_timezone - - def branch(self): - return "default" - - def user(self): - return pycompat.decodeutf8(self.commit.author) - - def files(self): - return [] - - def extra(self): - return {} - - def description(self): - return pycompat.decodeutf8(self.commit.message) - - def parents(self): - cl = self._hgrepo.changelog - parents = cl.parents(cl.node(self._rev)) - if not parents: - return [self._hgrepo["null"]] - if parents[1] == nullid: - parents = parents[:-1] - return [self._hgrepo[sha] for sha in parents] - - def manifestnode(self): - # type: () -> bytes - return bin(self.commit.tree) - - def hex(self): - # type: () -> str - return pycompat.decodeutf8(self.commit.id) - - def tags(self): - return [] - - def bookmarks(self): - return [] - - def manifest(self): - return overlaymanifest(self._overlay, self.commit.tree) - - def filectx(self, path, filelog=None): - mf = self.manifest() - return overlayfilectx(self._overlay, path, mf[path]) - - def flags(self, path): - mf = self.manifest() - return mf.flags(path) - - def __nonzero__(self): - return True - - __bool__ = __nonzero__ - - def phase(self): - # type: () -> int - try: - from edenscm.mercurial import phases - - return phases.draft - except (AttributeError, ImportError): - return 1 - - def totuple(self): - return ( - self.commit.tree, - self.user(), - self.date(), - self.files(), - self.description(), - self.extra(), - ) - - -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 gitrev is None: - # we've reached a revision we have - return self.base.parents(n) - commit = self.repo.handler.git.get_object(_maybehex(n)) - - if not commit.parents: - return [nullid, nullid] - - 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 ancestor(self, a, b): - anode = self.repo.nodemap.get(a) - bnode = self.repo.nodemap.get(b) - if anode is None and bnode is None: - return self.base.ancestor(a, b) - ancs = ancestor.ancestors(self.parentrevs, a, b) - if ancs: - return min(map(self.node, ancs)) - return nullid - - 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 __len__(self): - return len(self.repo.handler.repo) + len(self.repo.revmap) - - -class overlayoldmanifestlog(overlayrevlog): - def read(self, sha): - if sha == nullid: - return manifest.manifestdict() - return overlaymanifest(self.repo, sha) - - def __getitem__(self, sha): - return overlaymanifestctx(self.repo, sha) - - -class overlaymanifestrevlog(overlayrevlog): - pass - - -class overlaymanifestctx(object): - def __init__(self, repo, node): - self._repo = repo - self._node = node - - def read(self): - return overlaymanifest(self._repo, self._node) - - -try: - - class overlaymanifestlog(manifest.manifestlog): - def __init__(self, repo): - self._repo = repo - - # Needed for 4.0, since __getitem__ did not redirect to get() in that - # release. - def __getitem__(self, node): - return self.get("", node) - - def get(self, dir, node): - if dir: - raise RuntimeError("hggit doesn't support treemanifests") - if node == nullid: - return manifest.memmanifestctx(self) - return overlaymanifestctx(self._repo, node) - - -except AttributeError: - # manifestlog did not exist prior to 4.0 - pass - - -class overlaychangelog(overlayrevlog): - def read(self, sha): - if isinstance(sha, int): - sha = self.node(sha) - if sha == nullid: - return (nullid, "", (0, 0), [], "", {}) - try: - return self.base.read(sha) - except LookupError: - return overlaychangectx(self.repo, sha).totuple() - - def changelogrevision(self, noderev): - values = self.read(noderev) - return changelog._changelogrevision( - manifest=values[0], - user=values[1], - date=values[2], - files=values[3], - description=values[4], - extra=values[5], - ) - - -class overlayrepo(object): - def __init__(self, handler, commits, refs): - self.handler = handler - - self.changelog = overlaychangelog(self, handler.repo.changelog) - if util.safehasattr(handler.repo, "manifest"): - self.manifest = overlayoldmanifestlog(self, handler.repo.manifest) - # new as of mercurial 3.9+ - self.manifestlog = self.manifest - else: - # no more manifest class as of 4.1 - self.manifestlog = overlaymanifestlog(self) - - # for incoming -p - self.root = handler.repo.root - self.getcwd = handler.repo.getcwd - # self.status = handler.repo.status - self.ui = handler.repo.ui - self.sharedvfs = self.handler.repo.sharedvfs - self.localvfs = self.handler.repo.localvfs - self.svfs = self.handler.repo.svfs - - self.revmap = None - self.nodemap = None - self.refmap = None - self.tagmap = None - - self._makemaps(commits, refs) - - try: - # Mercurial >= 3.3 - from edenscm.mercurial import namespaces - - self.names = namespaces.namespaces(self) - except (AttributeError, ImportError): - pass - - def _constructmanifest(self): - return overlaymanifestrevlog(self, self.handler.repo._constructmanifest()) - - def __getitem__(self, n): - if n not in self.revmap: - return self.handler.repo[n] - return overlaychangectx(self, n) - - def _handlerhack(self, method, *args, **kwargs): - nothing = object() - r = self.handler.repo - oldhandler = getattr(r, "handler", nothing) - oldoverlay = getattr(r, "gitoverlay", nothing) - r.handler = self.handler - r.gitoverlay = self - try: - return getattr(r, method)(*args, **kwargs) - finally: - if oldhandler is nothing: - del r.handler - else: - r.handler = oldhandler - if oldoverlay is nothing: - del r.gitoverlay - else: - r.gitoverlay = oldoverlay - - def status(self, *args, **kwargs): - return self._handlerhack("status", *args, **kwargs) - - def node(self, n): - """Returns an Hg or Git hash for the specified Git hash""" - if bin(n) in self.revmap: - return n - return self.handler.map_hg_get(n) - - def nodebookmarks(self, n): - return list(pycompat.decodeutf8(r) for r in 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 unfiltered(self): - return self.handler.repo - - 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(b"refs/heads/"): - refname = ref[11:] - self.refmap.setdefault(bin(refs[ref]), []).append(refname) - elif ref.startswith(b"refs/tags/"): - tagname = ref[10:] - self.tagmap.setdefault(bin(refs[ref]), []).append(tagname) - - @util.propertycache - def _remotenames(self): - remotenames = bookmarks.remotenames(self) - remotenames["bookmarks"] = {} - return remotenames diff --git a/eden/scm/edenscm/hgext/hggit/util.py b/eden/scm/edenscm/hgext/hggit/util.py deleted file mode 100644 index e36b2edf8a..0000000000 --- a/eden/scm/edenscm/hgext/hggit/util.py +++ /dev/null @@ -1,118 +0,0 @@ -"""compatibility functions for old Mercurial versions and other utility -functions.""" -import re - -from dulwich import errors -from edenscm.mercurial import error, lock as lockmod, pycompat, util as hgutil -from edenscm.mercurial.i18n import _ - - -try: - from collections import OrderedDict -except ImportError: - # pyre-fixme[21]: Could not find `ordereddict`. - from ordereddict import OrderedDict - - -gitschemes = ("git", "git+ssh", "git+http", "git+https") - - -def serialize_hgsub(data): - """Produces a string from OrderedDict hgsub content""" - return "".join(["%s = %s\n" % (n, v) for n, v in pycompat.iteritems(data)]) - - -def transform_notgit(f): - """use as a decorator around functions that call into dulwich""" - - def inner(*args, **kwargs): - try: - return f(*args, **kwargs) - except errors.NotGitRepository: - raise hgutil.Abort("not a git repository") - - return inner - - -def isgitsshuri(uri): - """Method that returns True if a uri looks like git-style uri - - Tests: - - >>> print isgitsshuri('http://fqdn.com/hg') - False - >>> print isgitsshuri('http://fqdn.com/test.git') - False - >>> print isgitsshuri('git@github.com:user/repo.git') - True - >>> print isgitsshuri('github-123.com:user/repo.git') - True - >>> print isgitsshuri('git@127.0.0.1:repo.git') - True - >>> print isgitsshuri('git@[2001:db8::1]:repository.git') - True - """ - for scheme in gitschemes: - if uri.startswith("%s://" % scheme): - return False - - if uri.startswith("http:") or uri.startswith("https:"): - return False - - m = re.match(r"(?:.+@)*([\[]?[\w\d\.\:\-]+[\]]?):(.*)", uri) - if m: - # here we're being fairly conservative about what we consider to be git - # urls - giturl, repopath = m.groups() - # definitely a git repo - if repopath.endswith(".git"): - return True - # use a simple regex to check if it is a fqdn regex - fqdn_re = ( - r"(?=^.{4,253}$)(^((?!-)[a-zA-Z0-9-]{1,63}" r"(? beta -git add beta -fn_git_commit -m 'add beta' - -echo gamma > gamma -git add gamma -fn_git_commit -m 'add gämmâ' - -# test the commit encoding field -git config i18n.commitencoding latin-1 -echo delta > delta -git add delta -fn_git_commit -m 'add déltà' diff --git a/eden/scm/tests/hggit/testutil b/eden/scm/tests/hggit/testutil deleted file mode 100755 index d4d5d026d9..0000000000 --- a/eden/scm/tests/hggit/testutil +++ /dev/null @@ -1,72 +0,0 @@ -#!/bin/sh - -# This file holds logic that is used in many tests. -# It can be called in a test like this: -# $ . "$TESTDIR/testutil" - -# Activate extensions -echo "[extensions]" >> $HGRCPATH -echo "hggit=" >> $HGRCPATH - -# Defaults for testing against hg < 4.3 -echo '[defaults]' >> $HGRCPATH -echo 'backout = -d "0 0"' >> $HGRCPATH -echo 'commit = -d "0 0"' >> $HGRCPATH -echo 'shelve = --date "0 0"\n' >> $HGRCPATH -echo 'tag = -d "0 0"\n' >> $HGRCPATH - -# enable git subrepos -echo '[subrepos]' >> $HGRCPATH -echo 'git:allowed = true' >> $HGRCPATH - -# Standard checks for external dependencies -# We use the git command-line client and dulwich in pretty much all the tests. -# Thus, to avoid repetitively declaring that requirement in almost every test, -# we just call the checks in all tests that include this library. -hg debugpython -- -c 'import dulwich' || { - echo "skipped: missing feature: dulwich" && exit 80 -} -hg debugpython -- "$TESTDIR/hghave" git || exit 80 - -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 - -# Functions to commit and tag in Mercurial and Git in a predictable manner -count=10 - -fn_git_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` -} - -fn_hg_commit() { - HGDATE="2007-01-01 00:00:$count +0000" - hg commit -d "$HGDATE" "$@" >/dev/null || echo "hg commit error" - count=`expr $count + 1` -} - -fn_hg_commitextra() { - HGDATE="2007-01-01 00:00:$count +0000" - hg --config extensions.commitextra=$TESTDIR/hggit/commitextra.py \ - commitextra -d "$HGDATE" "$@" >/dev/null || echo "hg commit error" - count=`expr $count + 1` -} - -fn_git_tag() { - GIT_AUTHOR_DATE="2007-01-01 00:00:$count +0000" - GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE" - git tag "$@" >/dev/null || echo "git tag error" - count=`expr $count + 1` -} - -fn_hg_tag() { - HGDATE="2007-01-01 00:00:$count +0000" - hg tag -d "$HGDATE" "$@" >/dev/null || echo "hg tag error" - count=`expr $count + 1` -} diff --git a/eden/scm/tests/test-check-code.t b/eden/scm/tests/test-check-code.t index 86858cf064..98a46cd19d 100644 --- a/eden/scm/tests/test-check-code.t +++ b/eden/scm/tests/test-check-code.t @@ -21,7 +21,6 @@ New errors are not allowed. Warnings are strongly discouraged. Skipping edenscm/mercurial/statprof.py it has no-che?k-code (glob) edenscm/hgext/extlib/phabricator/graphql.py:*: use foobar, not foo_bar naming --> ca_bundle = repo.ui.configpath("web", "cacerts") (glob) edenscm/hgext/extlib/phabricator/graphql.py:*: use foobar, not foo_bar naming --> def scmquery_log( (glob) - edenscm/hgext/hggit/git_handler.py:*: use foobar, not foo_bar naming --> git_renames = {} (glob) @commands in debugcommands.py should be in alphabetical order. diff --git a/eden/scm/tests/test-gitlookup-index.t b/eden/scm/tests/test-gitlookup-index.t deleted file mode 100644 index 8d90aa2537..0000000000 --- a/eden/scm/tests/test-gitlookup-index.t +++ /dev/null @@ -1,107 +0,0 @@ -#require py2 -#chg-compatible -#require git - -Test the gitlookup.useindex=True feature for fast git -> hg commit translation. - -Repos: -- gitrepo: the source git repo -- hgrepo: sync from the hgrepo -- hgclient: a dummy repo that talks to hgrepo - -Prepare the git repo: - - $ . "$TESTDIR/hggit/testutil" - - $ git init --quiet gitrepo - $ cd gitrepo - $ echo alpha > alpha - $ git add alpha - $ fn_git_commit -m 'add alpha' - - $ git checkout --quiet -b beta - $ echo beta > beta - $ git add beta - $ fn_git_commit -m 'add beta' - - $ cd $TESTTMP - -Prepare the hg repo: - - $ hg clone gitrepo hgrepo - importing git objects into hg - updating to branch default - 2 files updated, 0 files merged, 0 files removed, 0 files unresolved - $ cd hgrepo - $ enable gitlookup - $ setconfig gitlookup.useindex=True gitlookup.mapfile=$TESTTMP/hgrepo/.hg/git-mapfile - $ hg log -Gr 'all()' -T '{node} {gitnode} {bookmarks}' - @ 3bb02b6794ddc0b498cdc15f59f2e6724cabfa2f 9497a4ee62e16ee641860d7677cdb2589ea15554 beta - │ - o 69982ec78c6dd2f24b3b62f3e2baaa79ab48ed93 7eeab2ea75ec1ac0ff3d500b5b6f8a3447dd7c03 master - -The gitlookup interface is exposed at the wireproto layer. Use another repo to test it: - - $ newrepo hgclient - $ hg pull -r _gitlookup_git_7eeab2ea75ec1ac0ff3d500b5b6f8a3447dd7c03 $TESTTMP/hgrepo - pulling from $TESTTMP/hgrepo - importing git nodemap from flat mapfile - building git nodemap for 2 commits - adding changesets - adding manifests - adding file changes - added 1 changesets with 1 changes to 1 files - adding remote bookmark master - $ hg pull -r _gitlookup_git_9497a4ee62e16ee641860d7677cdb2589ea15554 $TESTTMP/hgrepo - pulling from $TESTTMP/hgrepo - searching for changes - adding changesets - adding manifests - adding file changes - added 1 changesets with 1 changes to 1 files - adding remote bookmark beta - -Add new commits to test the index can be incrementally built: - - $ cd $TESTTMP/gitrepo - $ echo segma > segma - $ git add segma - $ fn_git_commit -m 'add segma' - -Sync git to hg: - - $ cd $TESTTMP/hgrepo - $ hg pull - pulling from $TESTTMP/gitrepo - importing git objects into hg - $ hg log -Gr 'all()' -T '{node} {gitnode} {bookmarks}' - o 146e4a0c333d21c93eefe6bf5c01a8d51c5918ab b6d676108afa31dc39efc9c5eb57f19ecbad837b beta - │ - @ 3bb02b6794ddc0b498cdc15f59f2e6724cabfa2f 9497a4ee62e16ee641860d7677cdb2589ea15554 - │ - o 69982ec78c6dd2f24b3b62f3e2baaa79ab48ed93 7eeab2ea75ec1ac0ff3d500b5b6f8a3447dd7c03 master - - -Query the new commits: - - $ cd $TESTTMP/hgclient - $ hg pull -r _gitlookup_git_b6d676108afa31dc39efc9c5eb57f19ecbad837b $TESTTMP/hgrepo - pulling from $TESTTMP/hgrepo - building git nodemap for 1 commits - searching for changes - adding changesets - adding manifests - adding file changes - added 1 changesets with 1 changes to 1 files - updating bookmark beta - -Test the debugbuildgitnodemap command. This runs the build explicitly instead of on-demand: - - $ cd $TESTTMP/hgrepo - $ hg debugbuildgitnodemap - 0 new commits are indexed - $ rm -rf .hg/git-nodemap .hg/git-nodemap-lastrev - $ hg debugbuildgitnodemap - importing git nodemap from flat mapfile - building git nodemap for 3 commits - 3 new commits are indexed diff --git a/eden/scm/tests/test-help.t b/eden/scm/tests/test-help.t index abfb307df1..ac8e5668dd 100644 --- a/eden/scm/tests/test-help.t +++ b/eden/scm/tests/test-help.t @@ -330,7 +330,6 @@ Test extension help: grepdiff (no help text available) grpcheck check if the user is in specified groups hgevents publishes state-enter and state-leave events to Watchman - hggit push and pull from a Git server hgsql sync hg repos with MySQL highlight syntax highlighting for hgweb (requires Pygments) histedit interactive history editing diff --git a/eden/scm/tests/test-hggit-bookmark-workflow.t b/eden/scm/tests/test-hggit-bookmark-workflow.t deleted file mode 100644 index 52bab2cbf6..0000000000 --- a/eden/scm/tests/test-hggit-bookmark-workflow.t +++ /dev/null @@ -1,221 +0,0 @@ - $ disable treemanifest -This test demonstrates how Hg works with remote Hg bookmarks compared with -remote branches via Hg-Git. Ideally, they would behave identically. In -practice, some differences are unavoidable, but we should try to minimize -them. - -This test should not bother testing the behavior of bookmark creation, -deletion, activation, deactivation, etc. These behaviors, while important to -the end user, don't vary at all when Hg-Git is in use. Only the synchonization -of bookmarks should be considered "under test", and mutation of bookmarks -locally is only to provide a test fixture. - -Load commonly used test logic - $ . "$TESTDIR/hggit/testutil" - - $ gitcount=10 - $ gitcommit() - > { - > GIT_AUTHOR_DATE="2007-01-01 00:00:$gitcount +0000" - > GIT_COMMITTER_DATE="$GIT_AUTHOR_DATE" - > git commit "$@" >/dev/null 2>/dev/null || echo "git commit error" - > gitcount=`expr $gitcount + 1` - > } - $ hgcount=10 - $ hgcommit() - > { - > HGDATE="2007-01-01 00:00:$hgcount +0000" - > hg commit -u "test " -d "$HGDATE" "$@" >/dev/null 2>/dev/null || echo "hg commit error" - > hgcount=`expr $hgcount + 1` - > } - $ gitstate() - > { - > git log --format=" %h \"%s\" refs:%d" $@ | sed 's/HEAD, //' - > } - $ hgstate() - > { - > hg log --template " {node|short} \"{desc}\" bookmarks: [{bookmarks}]\n" $@ - > } - $ hggitstate() - > { - > hg log --template " {node|short} {gitnode|short} \"{desc}\" bookmarks: [{bookmarks}]\n" $@ - > } - -Initialize remote hg and git repos with equivalent initial contents - $ hg init hgremoterepo - $ cd hgremoterepo - $ hg bookmark master - $ for f in alpha beta gamma delta; do - > echo $f > $f; hg add $f; hgcommit -m "add $f" - > done - $ hg bookmark -r 1 b1 - $ hgstate - fc2664cac217 "add delta" bookmarks: [master] - d85ced7ae9d6 "add gamma" bookmarks: [] - 7bcd915dc873 "add beta" bookmarks: [b1] - 3442585be8a6 "add alpha" bookmarks: [] - $ cd .. - $ git init -q gitremoterepo - $ cd gitremoterepo - $ for f in alpha beta gamma delta; do - > echo $f > $f; git add $f; gitcommit -m "add $f" - > done - $ git branch b1 9497a4e - $ gitstate - 55b133e "add delta" refs: (*master) (glob) - d338971 "add gamma" refs: - 9497a4e "add beta" refs: (b1) - 7eeab2e "add alpha" refs: - $ cd .. - -Cloning transfers all bookmarks from remote to local - $ hg clone -q hgremoterepo purehglocalrepo - $ cd purehglocalrepo - $ hgstate - fc2664cac217 "add delta" bookmarks: [master] - d85ced7ae9d6 "add gamma" bookmarks: [] - 7bcd915dc873 "add beta" bookmarks: [b1] - 3442585be8a6 "add alpha" bookmarks: [] - $ cd .. - $ hg clone -q gitremoterepo hggitlocalrepo --config hggit.usephases=True - $ cd hggitlocalrepo - $ hggitstate - 3783f3cdb535 55b133e1d558 "add delta" bookmarks: [master] - 1221213928d3 d338971a96e2 "add gamma" bookmarks: [] - 3bb02b6794dd 9497a4ee62e1 "add beta" bookmarks: [b1] - 69982ec78c6d 7eeab2ea75ec "add alpha" bookmarks: [] - -TODO: Write remotenames instead of local bookmarks to fix phase handling. - $ hg phase -r master - 3783f3cdb535321db1dbf622958d68d051c73218: draft - $ cd .. - -No changes - $ cd purehglocalrepo - $ hg incoming -B - comparing with $TESTTMP/hgremoterepo - searching for changed bookmarks - no changed bookmarks found - [1] - $ hg outgoing - comparing with $TESTTMP/hgremoterepo - searching for changes - no changes found - [1] - $ hg outgoing -B - comparing with $TESTTMP/hgremoterepo - searching for changed bookmarks - no changed bookmarks found - [1] - $ hg push - pushing to $TESTTMP/hgremoterepo - searching for changes - no changes found - [1] - $ cd .. - $ cd hggitlocalrepo - $ hg incoming -B - comparing with $TESTTMP/gitremoterepo - searching for changed bookmarks - no changed bookmarks found - [1] - $ hg outgoing - comparing with $TESTTMP/gitremoterepo - no changes found - [1] - $ hg outgoing -B - comparing with $TESTTMP/gitremoterepo - searching for changed bookmarks - no changed bookmarks found - [1] - $ hg push - pushing to $TESTTMP/gitremoterepo - searching for changes - no changes found - [1] - $ cd .. - -Bookmarks on existing revs: -- change b1 on local repo -- introduce b2 on local repo -- introduce b3 on remote repo -Bookmarks on new revs -- introduce b4 on a new rev on the remote - $ cd hgremoterepo - $ hg bookmark -r master b3 - $ hg bookmark -r master b4 - $ hg update -q b4 - $ echo epsilon > epsilon; hg add epsilon; hgcommit -m 'add epsilon' - $ hgstate - d979bb8e0fbb "add epsilon" bookmarks: [b4] - fc2664cac217 "add delta" bookmarks: [b3 master] - d85ced7ae9d6 "add gamma" bookmarks: [] - 7bcd915dc873 "add beta" bookmarks: [b1] - 3442585be8a6 "add alpha" bookmarks: [] - $ cd .. - $ cd purehglocalrepo - $ hg bookmark -fr 2 b1 - $ hg bookmark -r 0 b2 - $ hgstate - fc2664cac217 "add delta" bookmarks: [master] - d85ced7ae9d6 "add gamma" bookmarks: [b1] - 7bcd915dc873 "add beta" bookmarks: [] - 3442585be8a6 "add alpha" bookmarks: [b2] - $ hg incoming -B - comparing with $TESTTMP/hgremoterepo - searching for changed bookmarks - b3 fc2664cac217 - b4 d979bb8e0fbb - $ hg outgoing - comparing with $TESTTMP/hgremoterepo - searching for changes - no changes found - [1] -As of 2.3, Mercurial's outgoing -B doesn't actually show changed bookmarks -It only shows "new" bookmarks. Thus, b1 doesn't show up. -This changed in 3.4 to start showing changed and deleted bookmarks again. - $ hg outgoing -B | egrep -v -w 'b1|b3|b4' - comparing with $TESTTMP/hgremoterepo - searching for changed bookmarks - b2 3442585be8a6 - $ cd .. - - $ cd gitremoterepo - $ git branch b3 master - $ git checkout -b b4 master - Switched to a new branch 'b4' - $ echo epsilon > epsilon - $ git add epsilon - $ gitcommit -m 'add epsilon' - $ gitstate - fcfd2c0 "add epsilon" refs: (*b4) (glob) - 55b133e "add delta" refs: (master, b3) - d338971 "add gamma" refs: - 9497a4e "add beta" refs: (b1) - 7eeab2e "add alpha" refs: - $ cd .. - $ cd hggitlocalrepo - $ hg bookmark -fr 2 b1 - $ hg bookmark -r 0 b2 - $ hgstate - 3783f3cdb535 "add delta" bookmarks: [master] - 1221213928d3 "add gamma" bookmarks: [b1] - 3bb02b6794dd "add beta" bookmarks: [] - 69982ec78c6d "add alpha" bookmarks: [b2] - $ hg incoming -B - comparing with $TESTTMP/gitremoterepo - searching for changed bookmarks - b3 3783f3cdb535 - b4 fcfd2c0262db - $ hg outgoing - comparing with $TESTTMP/gitremoterepo - no changes found - [1] -As of 2.3, Mercurial's outgoing -B doesn't actually show changed bookmarks -It only shows "new" bookmarks. Thus, b1 doesn't show up. -This changed in 3.4 to start showing changed and deleted bookmarks again. - $ hg outgoing -B | egrep -v -w 'b1|b3|b4' - comparing with $TESTTMP/gitremoterepo - searching for changed bookmarks - b2 69982ec78c6d - $ cd .. diff --git a/eden/scm/tests/test-hggit-clone.t b/eden/scm/tests/test-hggit-clone.t deleted file mode 100644 index 657c1c9199..0000000000 --- a/eden/scm/tests/test-hggit-clone.t +++ /dev/null @@ -1,86 +0,0 @@ -Load commonly used test logic - $ . "$TESTDIR/hggit/testutil" - - $ git init -q gitrepo - $ cd gitrepo - $ echo alpha > alpha - $ git add alpha - $ fn_git_commit -m 'add alpha' - - $ git checkout -b beta - Switched to a new branch 'beta' - $ echo beta > beta - $ git add beta - $ fn_git_commit -m 'add beta' - - - $ cd .. - -clone a branch - $ hg clone -r beta gitrepo hgrepo-b 2>&1 | grep -v '^updating' - importing git objects into hg - 2 files updated, 0 files merged, 0 files removed, 0 files unresolved - $ hg -R hgrepo-b log --graph - @ commit: 3bb02b6794dd - │ bookmark: beta - │ user: test - │ date: Mon Jan 01 00:00:11 2007 +0000 - │ summary: add beta - │ - o commit: 69982ec78c6d - bookmark: master - user: test - date: Mon Jan 01 00:00:10 2007 +0000 - summary: add alpha - -Make sure this is still draft since we didn't pull remote's HEAD - $ hg -R hgrepo-b phase -r beta - 3bb02b6794ddc0b498cdc15f59f2e6724cabfa2f: draft - -clone with mapsavefreq set - $ rm -rf hgrepo-b - $ hg clone -r beta gitrepo hgrepo-b --config hggit.mapsavefrequency=1 --debug 2>&1 | egrep "(saving|committing)" - committing files: - committing manifest - committing changelog - committing transaction - saving mapfile - committing files: - committing manifest - committing changelog - committing transaction - saving mapfile - -Make sure that a deleted .hgsubstate does not confuse hg-git - - $ cd gitrepo - $ echo 'HASH random' > .hgsubstate - $ git add .hgsubstate - $ fn_git_commit -m 'add bogus .hgsubstate' - $ git rm -q .hgsubstate - $ fn_git_commit -m 'remove bogus .hgsubstate' - $ cd .. - - $ hg clone -r beta gitrepo hgrepo-c - importing git objects into hg - updating to branch default - 2 files updated, 0 files merged, 0 files removed, 0 files unresolved - $ hg --cwd hgrepo-c status - -clone empty repo - $ git init -q empty - $ hg clone empty emptyhg - updating to branch default - 0 files updated, 0 files merged, 0 files removed, 0 files unresolved - -Ensure hggit.disallowinitbare blocks initting .hg/git - $ hg init nogitbare - $ cd nogitbare - $ cat >> .hg/hgrc < [hggit] - > disallowinitbare=True - > EOF - $ hg pull ../empty - pulling from ../empty - abort: missing .hg/git repo - [255] diff --git a/eden/scm/tests/test-hggit-conflict-1.t b/eden/scm/tests/test-hggit-conflict-1.t deleted file mode 100644 index 480d32ce7a..0000000000 --- a/eden/scm/tests/test-hggit-conflict-1.t +++ /dev/null @@ -1,72 +0,0 @@ -Load commonly used test logic - $ . "$TESTDIR/hggit/testutil" - - $ 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 -r'desc(origin)' - 1 files updated, 0 files merged, 0 files removed, 0 files unresolved - $ echo C > afile - $ hg ci -m "A->C" - - $ hg merge -r7205e83b5a3fb01334c76fef35a69c912f5b2ba3 - merging afile - warning: 1 conflicts while merging afile! (edit, then use 'hg resolve --mark') - 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 - [1] -resolve using first parent - $ echo C > afile - $ hg resolve -m afile | egrep -v 'no more unresolved files' || true - $ hg ci -m "merge to C" - - $ hg log --graph --style compact - @ 6c53bc0f062f 1970-01-01 00:00 +0000 test - ├─╮ merge to C - │ │ - │ o ea82b67264a1 1970-01-01 00:00 +0000 test - │ │ A->C - │ │ - o │ 7205e83b5a3f 1970-01-01 00:00 +0000 test - ├─╯ A->B - │ - o 5d1a6b64f9d0 1970-01-01 00:00 +0000 test - origin - - - $ cd .. - - $ git init -q --bare gitrepo - - $ cd hgrepo1 - $ hg bookmark -r tip master - $ hg push -r master ../gitrepo - pushing to ../gitrepo - searching for changes - adding objects - added 4 commits with 3 trees and 3 blobs - $ cd .. - - $ hg clone gitrepo hgrepo2 | grep -v '^updating' - importing git objects into hg - 1 files updated, 0 files merged, 0 files removed, 0 files unresolved -expect the same revision ids as above - $ hg -R hgrepo2 log --graph --style compact - @ [master] b70d5f2ec3c4 1970-01-01 00:00 +0000 test - ├─╮ merge to C - │ │ - │ o 47fc555571b8 1970-01-01 00:00 +0000 test - │ │ A->B - │ │ - o │ 8ec5b459b86e 1970-01-01 00:00 +0000 test - ├─╯ A->C - │ - o fd5eb788c3a1 1970-01-01 00:00 +0000 test - origin - diff --git a/eden/scm/tests/test-hggit-conflict-2.t b/eden/scm/tests/test-hggit-conflict-2.t deleted file mode 100644 index 6d75eeccae..0000000000 --- a/eden/scm/tests/test-hggit-conflict-2.t +++ /dev/null @@ -1,72 +0,0 @@ -Load commonly used test logic - $ . "$TESTDIR/hggit/testutil" - - $ 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 -r'desc(origin)' - 1 files updated, 0 files merged, 0 files removed, 0 files unresolved - $ echo C > afile - $ hg ci -m "A->C" - - $ hg merge -r7205e83b5a3fb01334c76fef35a69c912f5b2ba3 - merging afile - warning: 1 conflicts while merging afile! (edit, then use 'hg resolve --mark') - 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 - [1] -resolve using second parent - $ echo B > afile - $ hg resolve -m afile | egrep -v 'no more unresolved files' || true - $ hg ci -m "merge to B" - - $ hg log --graph --style compact - @ 120385945d08 1970-01-01 00:00 +0000 test - ├─╮ merge to B - │ │ - │ o ea82b67264a1 1970-01-01 00:00 +0000 test - │ │ A->C - │ │ - o │ 7205e83b5a3f 1970-01-01 00:00 +0000 test - ├─╯ A->B - │ - o 5d1a6b64f9d0 1970-01-01 00:00 +0000 test - origin - - - $ cd .. - - $ git init -q --bare gitrepo - - $ cd hgrepo1 - $ hg bookmark -r tip master - $ hg push -r master ../gitrepo - pushing to ../gitrepo - searching for changes - adding objects - added 4 commits with 3 trees and 3 blobs - $ cd .. - - $ hg clone gitrepo hgrepo2 | grep -v '^updating' - importing git objects into hg - 1 files updated, 0 files merged, 0 files removed, 0 files unresolved -expect the same revision ids as above - $ hg -R hgrepo2 log --graph --style compact - @ [master] df42911f11c1 1970-01-01 00:00 +0000 test - ├─╮ merge to B - │ │ - │ o 47fc555571b8 1970-01-01 00:00 +0000 test - │ │ A->B - │ │ - o │ 8ec5b459b86e 1970-01-01 00:00 +0000 test - ├─╯ A->C - │ - o fd5eb788c3a1 1970-01-01 00:00 +0000 test - origin - diff --git a/eden/scm/tests/test-hggit-convergedmerge.t b/eden/scm/tests/test-hggit-convergedmerge.t deleted file mode 100644 index f0e4f064dd..0000000000 --- a/eden/scm/tests/test-hggit-convergedmerge.t +++ /dev/null @@ -1,77 +0,0 @@ -Load commonly used test logic - $ . "$TESTDIR/hggit/testutil" - - $ 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 -r'desc(origin)' - 1 files updated, 0 files merged, 0 files removed, 0 files unresolved - $ echo C > afile - $ hg ci -m "A->C" - - $ hg merge -r0dbe4ac1a7586d1642016eea4781390285b7b536 - 1 files updated, 0 files merged, 0 files removed, 0 files unresolved - (branch merge, don't forget to commit) - $ hg ci -m "merge" - - $ hg log --graph --style compact - @ eaa21d002113 1970-01-01 00:00 +0000 test - ├─╮ merge - │ │ - │ o ea82b67264a1 1970-01-01 00:00 +0000 test - │ │ A->C - │ │ - o │ 0dbe4ac1a758 1970-01-01 00:00 +0000 test - │ │ B->C - │ │ - o │ 7205e83b5a3f 1970-01-01 00:00 +0000 test - ├─╯ A->B - │ - o 5d1a6b64f9d0 1970-01-01 00:00 +0000 test - origin - - - $ cd .. - - $ git init -q --bare gitrepo - - $ cd hgrepo1 - $ hg bookmark -r'desc(merge)' master - $ hg push -r master ../gitrepo - pushing to ../gitrepo - searching for changes - adding objects - added 5 commits with 3 trees and 3 blobs - $ cd .. - - $ hg clone gitrepo hgrepo2 | grep -v '^updating' - importing git objects into hg - 1 files updated, 0 files merged, 0 files removed, 0 files unresolved -expect the same revision ids as above - $ hg -R hgrepo2 log --graph --style compact - @ [master] b08a922386d5 1970-01-01 00:00 +0000 test - ├─╮ merge - │ │ - │ o 8bfd72bff163 1970-01-01 00:00 +0000 test - │ │ B->C - │ │ - │ o 47fc555571b8 1970-01-01 00:00 +0000 test - │ │ A->B - │ │ - o │ 8ec5b459b86e 1970-01-01 00:00 +0000 test - ├─╯ A->C - │ - o fd5eb788c3a1 1970-01-01 00:00 +0000 test - origin - - $ hg -R hgrepo2 gverify - verifying rev b08a922386d5 against git commit fb8c9e2afe5418cfff337eeed79fad5dd58826f0 diff --git a/eden/scm/tests/test-hggit-empty-working-tree.t b/eden/scm/tests/test-hggit-empty-working-tree.t deleted file mode 100644 index 442ad958f7..0000000000 --- a/eden/scm/tests/test-hggit-empty-working-tree.t +++ /dev/null @@ -1,34 +0,0 @@ -Load commonly used test logic - $ . "$TESTDIR/hggit/testutil" - - $ git init -q gitrepo - $ cd gitrepo - $ git commit --allow-empty -m empty - [master (root-commit) 6782568] empty - - $ cd .. - $ git init -q --bare gitrepo2 - - $ hg clone gitrepo hgrepo | grep -v '^updating' - importing git objects into hg - 0 files updated, 0 files merged, 0 files removed, 0 files unresolved - $ cd hgrepo - $ hg log -r tip --template 'files: {files}\n' - files: - $ hg gverify - verifying rev fff47be752a2 against git commit 678256865a8c85ae925bf834369264193c88f8de - - $ hg gclear - clearing out the git cache data - $ hg push ../gitrepo2 - pushing to ../gitrepo2 - searching for changes - adding objects - added 1 commits with 1 trees and 0 blobs - $ cd .. - $ git --git-dir=gitrepo2 log --pretty=medium - commit d053da5f0bb9a1a7eb0dd82f36ddc3b1cd378527 - Author: test - Date: Mon Jan 1 00:00:00 2007 +0000 - - empty diff --git a/eden/scm/tests/test-hggit-encoding.t b/eden/scm/tests/test-hggit-encoding.t deleted file mode 100644 index a98c7caf7c..0000000000 --- a/eden/scm/tests/test-hggit-encoding.t +++ /dev/null @@ -1,120 +0,0 @@ - $ disable treemanifest -# -*- coding: utf-8 -*- - -Load commonly used test logic - $ . "$TESTDIR/hggit/testutil" - - $ git init -q gitrepo - $ cd gitrepo - -utf-8 encoded commit message - $ echo alpha > alpha - $ git add alpha - $ fn_git_commit -m 'add älphà' - -Create some commits using latin1 encoding -The warning message changed in Git 1.8.0 - $ . $TESTDIR/hggit/latin-1-encoding - Warning: commit message (did|does) not conform to UTF-8. (re) - 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 (did|does) not conform to UTF-8. (re) - You may want to amend it after fixing the message, or set the config - variable i18n.commitencoding to the encoding your project uses. - - $ cd .. - $ git init -q --bare gitrepo2 - - $ hg clone gitrepo hgrepo | grep -v '^updating' - importing git objects into hg - 4 files updated, 0 files merged, 0 files removed, 0 files unresolved - $ cd hgrepo - - $ HGENCODING=utf-8 hg log --graph --debug | grep -v 'phase:' | grep -v ': *author=' | grep -v ': *message=' - @ commit: 3c284d9743de7c02ac66b8b5ce10d39efd38d7bc - │ bookmark: master - │ manifest: ea49f93388380ead5601c8fcbfa187516e7c2ed8 - │ user: tést èncödîng - │ date: Mon Jan 01 00:00:13 2007 +0000 - │ files+: delta - │ extra: branch=default - │ extra: committer=test 1167609613 0 - │ extra: convert_revision=51c509c1c7eeb8f0a5b20aa3e894e8823f39171f - │ extra: encoding=latin-1 - │ extra: hg-git-rename-source=git - │ description: - │ add déltà - │ - │ - o commit: 727e37c486803fce561d97a80721324febade37e - │ manifest: f580e7da3673c137370da2b931a1dee83590d7b4 - │ user: tést èncödîng - │ date: Mon Jan 01 00:00:12 2007 +0000 - │ files+: gamma - │ extra: branch=default - │ extra: committer=test 1167609612 0 - │ extra: convert_revision=bd576458238cbda49ffcfbafef5242e103f1bc24 - │ extra: hg-git-rename-source=git - │ description: - │ add gämmâ - │ - │ - o commit: 5408f831a4d1a1d6ecccdddbe04c5a8b888a33c1 - │ manifest: f0bd6fbafbaebe4bb59c35108428f6fce152431d - │ user: tést èncödîng - │ date: Mon Jan 01 00:00:11 2007 +0000 - │ files+: beta - │ extra: branch=default - │ extra: committer=test 1167609611 0 - │ extra: convert_revision=7a7e86fc1b24db03109c9fe5da28b352de59ce90 - │ extra: hg-git-rename-source=git - │ description: - │ add beta - │ - │ - o commit: b1884a2b1964e4881e235f33485aebc34ee61b90 - manifest: 8b8a0e87dfd7a0706c0524afa8ba67e20544cbf0 - user: test - date: Mon Jan 01 00:00:10 2007 +0000 - files+: alpha - extra: branch=default - extra: convert_revision=0530b75d8c203e10dc934292a6a4032c6e958a83 - extra: hg-git-rename-source=git - description: - add \xc3\xa4lph\xc3\xa0 (esc) - | parent: 1:(9f6268bfc9eb3956c5ab8752d7b983b0ffe57115|955b24cf6f8f293741d3f39110c6fe554c292533) (re) - - - $ hg gclear - clearing out the git cache data - $ hg push ../gitrepo2 - pushing to ../gitrepo2 - searching for changes - adding objects - added 4 commits with 4 trees and 4 blobs - - $ cd .. - $ git --git-dir=gitrepo2 log --pretty=medium - commit 21cee4094d142130e18dce6bd1e3a60accd6799b - Author: t\xe9st \xe8nc\xf6d\xeeng (esc) - Date: Mon Jan 1 00:00:13 2007 +0000 - - add d\xe9lt\xe0 (esc) - - commit 4e120a5e4b8f6440e5f4aea0da3b1ddc8960186f - Author: * (glob) - Date: Mon Jan 1 00:00:12 2007 +0000 - - add g*mm* (glob) - - commit 4840d5849378794ea269174845d7fc2ae19506a0 - Author: * (glob) - Date: Mon Jan 1 00:00:11 2007 +0000 - - add beta - - commit 075e54047ff498b9229fc127668d157095658b04 - Author: test - Date: Mon Jan 1 00:00:10 2007 +0000 - - add älphà diff --git a/eden/scm/tests/test-hggit-external-sync.t b/eden/scm/tests/test-hggit-external-sync.t deleted file mode 100644 index 49490f817c..0000000000 --- a/eden/scm/tests/test-hggit-external-sync.t +++ /dev/null @@ -1,72 +0,0 @@ -Load commonly used test logic - $ . "$TESTDIR/hggit/testutil" - $ setconfig hggit.mapsavefrequency=1 - -# Set up the git repo - - $ cd "$TESTTMP" - $ git init -q gitrepo - $ cd gitrepo - $ echo commit1 > commit1 - $ git add . - $ fn_git_commit -m 'commit1' - -Clone the repo - - $ cd "$TESTTMP" - $ hg clone -q -r master gitrepo hgrepo - -Add more commits - - $ cd "$TESTTMP/gitrepo" - $ echo commit2 > commit2 - $ git add . - $ fn_git_commit -m 'commit2' - - $ echo commit3 > commit3 - $ git add . - $ fn_git_commit -m 'commit3' - - $ echo commit4 > commit4 - $ git add . - $ fn_git_commit -m 'commit4' - -Pull one of them - - $ cd "$TESTTMP/hgrepo" - - $ hg log -r tip -T '{desc}\n' - commit1 - - $ hg external-sync "$TESTTMP/gitrepo" master 1 - importing up to 1 commits from $TESTTMP/gitrepo in master - importing git objects into hg - imported 1 commits - $ hg log -r tip -T '{desc}\n' - commit2 - -Pull the rest - - $ hg external-sync "$TESTTMP/gitrepo" master 3 - importing up to 3 commits from $TESTTMP/gitrepo in master - importing git objects into hg - imported 2 commits - $ hg log -r tip -T '{desc}\n' - commit4 - - $ hg up tip - 3 files updated, 0 files merged, 0 files removed, 0 files unresolved - (leaving bookmark master) - - $ ls - commit1 - commit2 - commit3 - commit4 - -Nothing left ot pull - - $ hg external-sync "$TESTTMP/gitrepo" master 100 - importing up to 100 commits from $TESTTMP/gitrepo in master - no changes found - imported 0 commits diff --git a/eden/scm/tests/test-hggit-extra.t b/eden/scm/tests/test-hggit-extra.t deleted file mode 100644 index 325f6121a3..0000000000 --- a/eden/scm/tests/test-hggit-extra.t +++ /dev/null @@ -1,191 +0,0 @@ -Test that extra metadata (renames, copies, and other extra metadata) roundtrips -across from hg to git - $ . "$TESTDIR/hggit/testutil" - - $ git init -q gitrepo - $ cd gitrepo - $ touch a - $ git add a - $ fn_git_commit -ma - $ git checkout -b not-master - Switched to a new branch 'not-master' - - $ cd .. - $ hg clone -q gitrepo hgrepo - $ cd hgrepo - $ hg mv a b - $ fn_hg_commit -mb - $ hg up 'desc(a)' | egrep -v '^\(leaving bookmark' - 1 files updated, 0 files merged, 1 files removed, 0 files unresolved - $ touch c - $ hg add c - $ fn_hg_commit -mc - -Rebase will add a rebase_source -(The 'rebasing' is extra output in Mercurial 3.3+) - - $ hg --config extensions.rebase= rebase -s 'desc(b)' -d 'desc(c)' | grep -v '^rebasing ' - [1] - $ hg up 'desc(b)' - 1 files updated, 0 files merged, 1 files removed, 0 files unresolved - -Add a commit with multiple extra fields - $ hg bookmark b1 - $ touch d - $ hg add d - $ fn_hg_commitextra --field zzzzzzz=datazzz --field aaaaaaa=dataaaa - $ hg log --graph --template "{node} {desc|firstline}\n{join(extras, ' ')}\n\n" - @ f85ec44c632713d6fa812de1bf18a530e1dd6551 - │ aaaaaaa=dataaaa branch=default zzzzzzz=datazzz - │ - o f3c80cf66a137d4862c82e4df65a7c952aad36af b - │ branch=default rebase_source=26b80d272c9a2d4455e269005f4f250adc4c05b8 - │ - o 907635da058b4bd98a9594843a3bb7c61baed082 c - │ branch=default - │ - o 5b699970cd13b5f95f6af5f32781d80cfa2e813b a - branch=default convert_revision=ad4fd0de4cb839a7d2d1c2497f8a2c230a2726e9 hg-git-rename-source=git - -Make sure legacy extra (in commit message, after '--HG--') doesn't break - $ hg push -r b1 --config git.debugextrainmessage=1 - pushing to $TESTTMP/gitrepo - searching for changes - adding objects - added 3 commits with 3 trees and 0 blobs - adding reference refs/heads/b1 - - $ hg bookmark b2 - $ hg mv c c2 - $ hg mv d d2 - $ fn_hg_commitextra --field yyyyyyy=datayyy --field bbbbbbb=databbb - -Test some nutty filenames - $ hg book b3 - $ hg mv c2 'c2 => c3' - warning: filename contains '>', which is reserved on Windows: 'c2 => c3' - $ fn_hg_commit -m 'test filename with arrow' - $ hg mv 'c2 => c3' 'c3 => c4' - warning: filename contains '>', which is reserved on Windows: 'c3 => c4' - $ fn_hg_commit -m 'test filename with arrow 2' - $ hg log --graph --template "{node} {desc|firstline}\n{join(extras, ' ')}\n\n" -l 3 --config "experimental.graphstyle.missing=|" - @ decbc0c79131e24c0f01a480f068af7f0957872e test filename with arrow 2 - │ branch=default - │ - o 30e7f0dfaf1aa9bc81fe995415900b76021df952 test filename with arrow - │ branch=default - │ - o 256d56838c39ba60599eb69373038b88403ba2e4 - │ bbbbbbb=databbb branch=default yyyyyyy=datayyy - ~ - $ hg push -r b2 -r b3 - pushing to $TESTTMP/gitrepo - searching for changes - adding objects - added 3 commits with 3 trees and 0 blobs - adding reference refs/heads/b2 - adding reference refs/heads/b3 - - $ cd ../gitrepo - $ git cat-file commit b1 - tree 1b773a2eb70f29397356f8069c285394835ff85a - parent 2ab6104c03f0d6e0885470a7cc1bcd9b26f70bad - author test 1167609613 +0000 - committer test 1167609613 +0000 - - - - --HG-- - extra : aaaaaaa : dataaaa - extra : zzzzzzz : datazzz - - $ git cat-file commit b2 - tree 34ad62c6d6ad9464bfe62db5b3d2fa16aaa9fa9e - parent f554f3e7146694b2197fd3c853eef527ba264ae7 - author test 1167609614 +0000 - committer test 1167609614 +0000 - HG:rename c:c2 - HG:rename d:d2 - HG:extra bbbbbbb:databbb - HG:extra yyyyyyy:datayyy - - - - $ git cat-file commit b3 - tree e63df52695f9b06e54b37e7ef60d0c43994de620 - parent e16d81cc6d51456f445ddcd159b25361473d659c - author test 1167609616 +0000 - committer test 1167609616 +0000 - HG:rename c2%20%3D%3E%20c3:c3%20%3D%3E%20c4 - - test filename with arrow 2 - $ cd ../gitrepo - $ git checkout b1 - Switched to branch 'b1' - $ commit_sha=`git rev-parse HEAD` - $ tree_sha=`git rev-parse 'HEAD^{tree}'` - -There's no way to create a Git repo with extra metadata via the CLI. Dulwich -lets you do that, though. - - >>> from dulwich.objects import Commit - >>> from dulwich.porcelain import open_repo - >>> repo = open_repo('.') - >>> c = Commit() - >>> c.author = b'test ' - >>> c.author_time = 0 - >>> c.author_timezone = 0 - >>> c.committer = c.author - >>> c.commit_time = 0 - >>> c.commit_timezone = 0 - >>> c.parents = [b'$commit_sha'] - >>> c.tree = b'$tree_sha' - >>> c.message = b'extra commit\n' - >>> c.extra.extend([(b'zzz:zzz', b'data:zzz'), (b'aaa:aaa', b'data:aaa'), - ... (b'HG:extra', b'hgaaa:dataaaa'), - ... (b'HG:extra', b'hgzzz:datazzz')]) - >>> repo.object_store.add_object(c) - >>> repo.refs.set_if_equals(b'refs/heads/master', None, c.id) - True - - $ git cat-file commit master - tree 1b773a2eb70f29397356f8069c285394835ff85a - parent f554f3e7146694b2197fd3c853eef527ba264ae7 - author test 0 +0000 - committer test 0 +0000 - zzz:zzz data:zzz - aaa:aaa data:aaa - HG:extra hgaaa:dataaaa - HG:extra hgzzz:datazzz - - extra commit - - $ cd .. - $ hg clone -q gitrepo hgrepo2 - $ cd hgrepo2 - $ hg up -q 'desc("arrow 2")' - $ hg log --graph --template "{node} {desc|firstline}\n{join(extras, ' ')}\n\n" - @ 193fc708cfa16eb942a0dde3017d52c6743a43ae test filename with arrow 2 - │ branch=default convert_revision=fb079f663e17f780a63855d7116b0b4f867b2371 - │ - o 1cc3fc4cf203075484b5dbb141d4eb91bd205dc1 test filename with arrow - │ branch=default convert_revision=e16d81cc6d51456f445ddcd159b25361473d659c - │ - o f1aecb2ae22f40a9369287f87d5f987eeae1f25e - │ bbbbbbb=databbb branch=default convert_revision=acd860f8f036a235465c7d5e003ce9f28383b5f2 yyyyyyy=datayyy - │ - │ o 0d9e73e512aa715e73f9f37be9c4dec4224d2615 extra commit - ├─╯ GIT0-zzz%3Azzz=data%3Azzz GIT1-aaa%3Aaaa=data%3Aaaa branch=default convert_revision=0f7316e5c44bf7af9199e8c728938ba3daf058cb hgaaa=dataaaa hgzzz=datazzz - │ - o f9541591947764cf1c54ec8331b0618b710807bc - │ aaaaaaa=dataaaa branch=default convert_revision=f554f3e7146694b2197fd3c853eef527ba264ae7 zzzzzzz=datazzz - │ - o 4e11085eb947c77f6de15ee7a64d2752cb12b399 b - │ branch=default convert_revision=2ab6104c03f0d6e0885470a7cc1bcd9b26f70bad rebase_source=26b80d272c9a2d4455e269005f4f250adc4c05b8 - │ - o 1ec8735a89979fc3cb5e8edf1c03d6b61de3176b c - │ branch=default convert_revision=8728d16f575a12b85c99ddf5763972c3740515d9 hg-git-rename-source=git - │ - o 5b699970cd13b5f95f6af5f32781d80cfa2e813b a - branch=default convert_revision=ad4fd0de4cb839a7d2d1c2497f8a2c230a2726e9 hg-git-rename-source=git - diff --git a/eden/scm/tests/test-hggit-file-removal.t b/eden/scm/tests/test-hggit-file-removal.t deleted file mode 100644 index 9799658c09..0000000000 --- a/eden/scm/tests/test-hggit-file-removal.t +++ /dev/null @@ -1,276 +0,0 @@ -Load commonly used test logic - $ . "$TESTDIR/hggit/testutil" - - $ git init -q gitrepo - $ cd gitrepo - $ echo alpha > alpha - $ git add alpha - $ fn_git_commit -m 'add alpha' - $ echo beta > beta - $ git add beta - $ fn_git_commit -m 'add beta' - $ mkdir foo - $ echo blah > foo/bar - $ git add foo - $ fn_git_commit -m 'add foo' - $ git rm alpha - rm 'alpha' - $ fn_git_commit -m 'remove alpha' - $ git rm foo/bar - rm 'foo/bar' - $ fn_git_commit -m 'remove foo/bar' - $ ln -s beta betalink - $ git add betalink - $ fn_git_commit -m 'add symlink to beta' -replace symlink with file - $ rm betalink - $ echo betalink > betalink - $ git add betalink - $ fn_git_commit -m 'replace symlink with file' -replace file with symlink - $ rm betalink - $ ln -s beta betalink - $ git add betalink - $ fn_git_commit -m 'replace file with symlink' - $ git rm betalink - rm 'betalink' - $ fn_git_commit -m 'remove betalink' -final manifest in git is just beta - $ git ls-files - beta - $ git log --pretty=medium - commit 5ee11eeae239d6a99df5a99901ec00ffafbcc46b - Author: test - Date: Mon Jan 1 00:00:18 2007 +0000 - - remove betalink - - commit 2c7b324faeccb1acf89c35b7ad38e7956f5705fa - Author: test - Date: Mon Jan 1 00:00:17 2007 +0000 - - replace file with symlink - - commit ff0478d2ecc2571d01eb6d406ac29e4e63e5d3d5 - Author: test - Date: Mon Jan 1 00:00:16 2007 +0000 - - replace symlink with file - - commit 5492e6e410e42df527956be945286cd1ae45acb8 - Author: test - Date: Mon Jan 1 00:00:15 2007 +0000 - - add symlink to beta - - commit b991de8952c482a7cd51162674ffff8474862218 - Author: test - Date: Mon Jan 1 00:00:14 2007 +0000 - - remove foo/bar - - commit b0edaf0adac19392cf2867498b983bc5192b41dd - Author: test - Date: Mon Jan 1 00:00:13 2007 +0000 - - remove alpha - - commit f2d0d5bfa905e12dee728b509b96cf265bb6ee43 - Author: test - Date: Mon Jan 1 00:00:12 2007 +0000 - - add foo - - commit 9497a4ee62e16ee641860d7677cdb2589ea15554 - Author: test - Date: Mon Jan 1 00:00:11 2007 +0000 - - add beta - - commit 7eeab2ea75ec1ac0ff3d500b5b6f8a3447dd7c03 - Author: test - Date: Mon Jan 1 00:00:10 2007 +0000 - - add alpha - - $ cd .. - $ git init -q --bare gitrepo2 - - $ hg clone gitrepo hgrepo | grep -v '^updating' - importing git objects into hg - 1 files updated, 0 files merged, 0 files removed, 0 files unresolved - $ cd hgrepo - $ hg log --graph - @ commit: * (glob) - │ bookmark: master - │ user: test - │ date: Mon Jan 01 00:00:18 2007 +0000 - │ summary: remove betalink - │ - o commit: * (glob) - │ user: test - │ date: Mon Jan 01 00:00:17 2007 +0000 - │ summary: replace file with symlink - │ - o commit: * (glob) - │ user: test - │ date: Mon Jan 01 00:00:16 2007 +0000 - │ summary: replace symlink with file - │ - o commit: * (glob) - │ user: test - │ date: Mon Jan 01 00:00:15 2007 +0000 - │ summary: add symlink to beta - │ - o commit: * (glob) - │ user: test - │ date: Mon Jan 01 00:00:14 2007 +0000 - │ summary: remove foo/bar - │ - o commit: * (glob) - │ user: test - │ date: Mon Jan 01 00:00:13 2007 +0000 - │ summary: remove alpha - │ - o commit: * (glob) - │ user: test - │ date: Mon Jan 01 00:00:12 2007 +0000 - │ summary: add foo - │ - o commit: * (glob) - │ user: test - │ date: Mon Jan 01 00:00:11 2007 +0000 - │ summary: add beta - │ - o commit: * (glob) - user: test - date: Mon Jan 01 00:00:10 2007 +0000 - summary: add alpha - - -make sure alpha is not in this manifest - $ hg manifest -r 'desc("remove alpha")' - beta - foo/bar - -make sure that only beta is in the manifest - $ hg manifest - beta - - $ hg gclear - clearing out the git cache data - $ hg push ../gitrepo2 - pushing to ../gitrepo2 - searching for changes - adding objects - added 9 commits with 8 trees and 5 blobs - - $ cd .. - $ git --git-dir=gitrepo2 log --pretty=medium - commit 68c7019f1bfb2828f7f9200fac967921f06a1feb - Author: test - Date: Mon Jan 1 00:00:18 2007 +0000 - - remove betalink - - commit d59a3b386d681c94e5e79793b06c7333f221c443 - Author: test - Date: Mon Jan 1 00:00:17 2007 +0000 - - replace file with symlink - - commit 9c7cc15377285c52231e122d00f0e134b352b0e6 - Author: test - Date: Mon Jan 1 00:00:16 2007 +0000 - - replace symlink with file - - commit 03a89ec31682f257e820b4693e3f1b402f8c9d05 - Author: test - Date: Mon Jan 1 00:00:15 2007 +0000 - - add symlink to beta - - commit e2d4ee11209b5ad206ceffb9ce31eb076b25f52e - Author: test - Date: Mon Jan 1 00:00:14 2007 +0000 - - remove foo/bar - - commit db5085c1477a08eb9735c425f9a605f919b6d3cd - Author: test - Date: Mon Jan 1 00:00:13 2007 +0000 - - remove alpha - - commit d5e6a099c8c0f2d8a407e1f1d86367b58526c2df - Author: test - Date: Mon Jan 1 00:00:12 2007 +0000 - - add foo - - commit dbed4f6a8ff04d4d1f0a5ce79f9a07cf0f461d7f - Author: test - Date: Mon Jan 1 00:00:11 2007 +0000 - - add beta - - commit 205598a42833e532ad20d80414b8e3b85a65936e - Author: test - Date: Mon Jan 1 00:00:10 2007 +0000 - - add alpha - -test with rename detection enabled - $ hg --config git.similarity=100 clone gitrepo hgreporenames | grep -v '^updating' - importing git objects into hg - 1 files updated, 0 files merged, 0 files removed, 0 files unresolved - - $ cd hgreporenames - $ hg log --graph - @ commit: * (glob) - │ bookmark: master - │ user: test - │ date: Mon Jan 01 00:00:18 2007 +0000 - │ summary: remove betalink - │ - o commit: * (glob) - │ user: test - │ date: Mon Jan 01 00:00:17 2007 +0000 - │ summary: replace file with symlink - │ - o commit: * (glob) - │ user: test - │ date: Mon Jan 01 00:00:16 2007 +0000 - │ summary: replace symlink with file - │ - o commit: * (glob) - │ user: test - │ date: Mon Jan 01 00:00:15 2007 +0000 - │ summary: add symlink to beta - │ - o commit: * (glob) - │ user: test - │ date: Mon Jan 01 00:00:14 2007 +0000 - │ summary: remove foo/bar - │ - o commit: * (glob) - │ user: test - │ date: Mon Jan 01 00:00:13 2007 +0000 - │ summary: remove alpha - │ - o commit: * (glob) - │ user: test - │ date: Mon Jan 01 00:00:12 2007 +0000 - │ summary: add foo - │ - o commit: * (glob) - │ user: test - │ date: Mon Jan 01 00:00:11 2007 +0000 - │ summary: add beta - │ - o commit: * (glob) - user: test - date: Mon Jan 01 00:00:10 2007 +0000 - summary: add alpha - diff --git a/eden/scm/tests/test-hggit-git-clone.t b/eden/scm/tests/test-hggit-git-clone.t deleted file mode 100644 index 5cf3d60efb..0000000000 --- a/eden/scm/tests/test-hggit-git-clone.t +++ /dev/null @@ -1,59 +0,0 @@ -Load commonly used test logic - $ . "$TESTDIR/hggit/testutil" - - $ git init -q gitrepo - $ cd gitrepo - $ echo alpha > alpha - $ git add alpha - $ fn_git_commit -m 'add alpha' - $ echo beta > beta - $ git add beta - $ fn_git_commit -m 'add beta' - - $ cd .. - - $ hg clone gitrepo hgrepo | grep -v '^updating' - importing git objects into hg - 2 files updated, 0 files merged, 0 files removed, 0 files unresolved - $ hg -R hgrepo log --graph - @ commit: 3bb02b6794dd - │ bookmark: master - │ user: test - │ date: Mon Jan 01 00:00:11 2007 +0000 - │ summary: add beta - │ - o commit: 69982ec78c6d - user: test - date: Mon Jan 01 00:00:10 2007 +0000 - summary: add alpha - - -we should have some bookmarks - $ hg -R hgrepo book - * master 3bb02b6794dd - $ hg -R hgrepo gverify - verifying rev 3bb02b6794dd against git commit 9497a4ee62e16ee641860d7677cdb2589ea15554 - -test for ssh vulnerability - - $ cat >> $HGRCPATH << EOF - > [ui] - > ssh = ssh -o ConnectTimeout=1 - > EOF - - $ hg clone 'git+ssh://-oProxyCommand=rm${IFS}nonexistent/path' 2>&1 >/dev/null - abort: potentially unsafe hostname: '-oProxyCommand=rm${IFS}nonexistent' - [255] - $ hg clone 'git+ssh://%2DoProxyCommand=rm${IFS}nonexistent/path' 2>&1 >/dev/null - abort: potentially unsafe hostname: '-oProxyCommand=rm${IFS}nonexistent' - [255] - $ hg clone 'git+ssh://fakehost|rm${IFS}nonexistent/path' - destination directory: path - ssh: .* fakehost%7[Cc]rm%24%7[Bb][Ii][Ff][Ss]%7[Dd]nonexistent.* (re) - abort: git remote error: The remote server unexpectedly closed the connection. - [255] - $ hg clone 'git+ssh://fakehost%7Crm${IFS}nonexistent/path' - destination directory: path - ssh: .* fakehost%7[cC]rm%24%7[Bb][Ii][Ff][Ss]%7[Dd]nonexistent.* (re) - abort: git remote error: The remote server unexpectedly closed the connection. - [255] diff --git a/eden/scm/tests/test-hggit-git-workflow.t b/eden/scm/tests/test-hggit-git-workflow.t deleted file mode 100644 index 94d1cf1ab7..0000000000 --- a/eden/scm/tests/test-hggit-git-workflow.t +++ /dev/null @@ -1,128 +0,0 @@ - $ disable treemanifest -Load commonly used test logic - $ . "$TESTDIR/hggit/testutil" - - $ hg init hgrepo - $ cd hgrepo - $ echo alpha > alpha - $ hg add alpha - $ fn_hg_commit -m "add alpha" - $ hg log --graph --debug | grep -v phase: - @ commit: 0221c246a56712c6aa64e5ee382244d8a471b1e2 - manifest: 8b8a0e87dfd7a0706c0524afa8ba67e20544cbf0 - user: test - date: Mon Jan 01 00:00:10 2007 +0000 - files+: alpha - extra: branch=default - description: - add alpha - - - - $ cd .. - -configure for use from git - $ hg clone hgrepo gitrepo - updating to branch default - 1 files updated, 0 files merged, 0 files removed, 0 files unresolved - $ cd gitrepo - $ hg book master - $ hg up null | egrep -v '^\(leaving bookmark master\)$' - 0 files updated, 0 files merged, 1 files removed, 0 files unresolved - $ echo "[git]" >> .hg/hgrc - $ echo "intree = True" >> .hg/hgrc - $ hg gexport - -do some work - $ git config core.bare false - $ git checkout master - Already on 'master' - $ echo beta > beta - $ git add beta - $ fn_git_commit -m 'add beta' - -get things back to hg - $ hg gimport - importing git objects into hg - $ hg log --graph --debug | grep -v phase: - o commit: d294862c083a2eac3c1b31d3a3bdbdffb49a5b25 - │ bookmark: master - │ manifest: f0bd6fbafbaebe4bb59c35108428f6fce152431d - │ user: test - │ date: Mon Jan 01 00:00:11 2007 +0000 - │ files+: beta - │ extra: branch=default - │ extra: convert_revision=fef06279bff0022eee567d65729d8e795fd3efe8 - │ extra: hg-git-rename-source=git - │ description: - │ add beta - │ - │ - o commit: 0221c246a56712c6aa64e5ee382244d8a471b1e2 - manifest: 8b8a0e87dfd7a0706c0524afa8ba67e20544cbf0 - user: test - date: Mon Jan 01 00:00:10 2007 +0000 - files+: alpha - extra: branch=default - description: - add alpha - - -gimport should have updated the bookmarks as well - $ hg bookmarks - master d294862c083a - -gimport support for git.mindate - $ cat >> .hg/hgrc << EOF - > [git] - > mindate = 2014-01-02 00:00:00 +0000 - > EOF - $ echo oldcommit > oldcommit - $ git add oldcommit - $ GIT_AUTHOR_DATE="2014-03-01 00:00:00 +0000" \ - > GIT_COMMITTER_DATE="2009-01-01 00:00:00 +0000" \ - > git commit -m oldcommit > /dev/null || echo "git commit error" - $ hg gimport - no changes found - $ hg log --graph - o commit: d294862c083a - │ bookmark: master - │ user: test - │ date: Mon Jan 01 00:00:11 2007 +0000 - │ summary: add beta - │ - o commit: 0221c246a567 - user: test - date: Mon Jan 01 00:00:10 2007 +0000 - summary: add alpha - - - $ echo newcommit > newcommit - $ git add newcommit - $ GIT_AUTHOR_DATE="2014-01-01 00:00:00 +0000" \ - > GIT_COMMITTER_DATE="2014-01-02 00:00:00 +0000" \ - > git commit -m newcommit > /dev/null || echo "git commit error" - $ hg gimport - importing git objects into hg - $ hg log --graph - o commit: 3231f2356e13 - │ bookmark: master - │ user: test - │ date: Wed Jan 01 00:00:00 2014 +0000 - │ summary: newcommit - │ - o commit: 7912581b53bd - │ user: test - │ date: Sat Mar 01 00:00:00 2014 +0000 - │ summary: oldcommit - │ - o commit: d294862c083a - │ user: test - │ date: Mon Jan 01 00:00:11 2007 +0000 - │ summary: add beta - │ - o commit: 0221c246a567 - user: test - date: Mon Jan 01 00:00:10 2007 +0000 - summary: add alpha - diff --git a/eden/scm/tests/test-hggit-gitignore.t b/eden/scm/tests/test-hggit-gitignore.t deleted file mode 100644 index 1b84e41b16..0000000000 --- a/eden/scm/tests/test-hggit-gitignore.t +++ /dev/null @@ -1,111 +0,0 @@ -#require no-fsmonitor - $ hg debugpython -- -c 'from edenscm.mercurial.dirstate import rootcache' || exit 80 - -Load commonly used test logic - $ . "$TESTDIR/hggit/testutil" - - $ hg init - -We should only read .gitignore files in a hg-git repo (i.e. one with .hg/git -directory) otherwise, a rogue .gitignore could slow down a hg-only repo - - $ mkdir .hg/git - - $ touch foo - $ touch foobar - $ touch bar - $ echo 'foo*' > .gitignore - $ hg status - ? .gitignore - ? bar - - $ echo '*bar' > .gitignore - $ hg status - ? .gitignore - ? foo - - $ mkdir dir - $ touch dir/foo - $ echo 'foo' > .gitignore - $ hg status - ? .gitignore - ? bar - ? foobar - - $ echo '/foo' > .gitignore - $ hg status - ? .gitignore - ? bar - ? dir/foo - ? foobar - - $ rm .gitignore - $ echo 'foo' > dir/.gitignore - $ hg status - ? bar - ? dir/.gitignore - ? foo - ? foobar - - $ touch dir/bar - $ echo 'bar' > .gitignore - $ hg status - ? .gitignore - ? dir/.gitignore - ? foo - ? foobar - - $ echo '/bar' > .gitignore - $ hg status - ? .gitignore - ? dir/.gitignore - ? dir/bar - ? foo - ? foobar - - $ echo 'foo*' > .gitignore - $ echo '!*bar' >> .gitignore - $ hg status - ? .gitignore - ? bar - ? dir/.gitignore - ? dir/bar - ? foobar - - $ echo '.hg/' > .gitignore - $ hg status - ? .gitignore - ? bar - ? dir/.gitignore - ? dir/bar - ? foo - ? foobar - - $ echo 'dir/.hg/' > .gitignore - $ hg status - ? .gitignore - ? bar - ? dir/.gitignore - ? dir/bar - ? foo - ? foobar - - $ echo '.hg/foo' > .gitignore - $ hg status - ? .gitignore - ? bar - ? dir/.gitignore - ? dir/bar - ? foo - ? foobar - - $ touch foo.hg - $ echo 'foo.hg' > .gitignore - $ hg status - ? .gitignore - ? bar - ? dir/.gitignore - ? dir/bar - ? foo - ? foobar - $ rm foo.hg diff --git a/eden/scm/tests/test-hggit-hg-author.t b/eden/scm/tests/test-hggit-hg-author.t deleted file mode 100644 index 340b2dd40d..0000000000 --- a/eden/scm/tests/test-hggit-hg-author.t +++ /dev/null @@ -1,252 +0,0 @@ -Load commonly used test logic - $ . "$TESTDIR/hggit/testutil" - - $ git init -q gitrepo - $ cd gitrepo - $ echo alpha > alpha - $ git add alpha - $ fn_git_commit -m "add alpha" - $ git checkout -b not-master - Switched to a new branch 'not-master' - - $ cd .. - $ hg clone gitrepo hgrepo | grep -v '^updating' - importing git objects into hg - 1 files updated, 0 files merged, 0 files removed, 0 files unresolved - - $ cd hgrepo - $ hg book master - $ echo beta > beta - $ hg add beta - $ fn_hg_commit -u "test" -m 'add beta' - $ hg push - pushing to $TESTTMP/gitrepo - searching for changes - adding objects - added 1 commits with 1 trees and 1 blobs - updating reference refs/heads/master - - $ echo gamma >> beta - $ fn_hg_commit -u "test (comment)" -m 'modify beta' - $ hg push - pushing to $TESTTMP/gitrepo - searching for changes - adding objects - added 1 commits with 1 trees and 1 blobs - updating reference refs/heads/master - - $ echo gamma > gamma - $ hg add gamma - $ fn_hg_commit -u "" -m 'add gamma' - $ hg push - pushing to $TESTTMP/gitrepo - searching for changes - adding objects - added 1 commits with 1 trees and 1 blobs - updating reference refs/heads/master - - $ echo delta > delta - $ hg add delta - $ fn_hg_commit -u "name" -m 'add delta' - $ hg push - pushing to $TESTTMP/gitrepo - searching for changes - adding objects - added 1 commits with 1 trees and 1 blobs - updating reference refs/heads/master - - $ echo epsilon > epsilon - $ hg add epsilon - $ fn_hg_commit -u "name zeta - $ hg add zeta - $ fn_hg_commit -u " test " -m 'add zeta' - $ hg push - pushing to $TESTTMP/gitrepo - searching for changes - adding objects - added 1 commits with 1 trees and 1 blobs - updating reference refs/heads/master - - $ echo eta > eta - $ hg add eta - $ fn_hg_commit -u "test < test@example.com >" -m 'add eta' - $ hg push - pushing to $TESTTMP/gitrepo - searching for changes - adding objects - added 1 commits with 1 trees and 1 blobs - updating reference refs/heads/master - - $ echo theta > theta - $ hg add theta - $ fn_hg_commit -u "test >test@example.com>" -m 'add theta' - $ hg push - pushing to $TESTTMP/gitrepo - searching for changes - adding objects - added 1 commits with 1 trees and 1 blobs - updating reference refs/heads/master - - $ hg log --graph - @ commit: de0c236bcd02 - │ bookmark: master - │ user: test >test@example.com> - │ date: Mon Jan 01 00:00:18 2007 +0000 - │ summary: add theta - │ - o commit: b4ada284aa0b - │ user: test < test@example.com > - │ date: Mon Jan 01 00:00:17 2007 +0000 - │ summary: add eta - │ - o commit: be9e5ffbcff0 - │ user: test - │ date: Mon Jan 01 00:00:16 2007 +0000 - │ summary: add zeta - │ - o commit: 721ffc4d7c76 - │ user: name - │ date: Mon Jan 01 00:00:14 2007 +0000 - │ summary: add delta - │ - o commit: 10310359956b - │ user: - │ date: Mon Jan 01 00:00:13 2007 +0000 - │ summary: add gamma - │ - o commit: a6260b330211 - │ user: test (comment) - │ date: Mon Jan 01 00:00:12 2007 +0000 - │ summary: modify beta - │ - o commit: 574e2d660a7d - │ user: test - │ date: Mon Jan 01 00:00:11 2007 +0000 - │ summary: add beta - │ - o commit: 69982ec78c6d - bookmark: not-master - user: test - date: Mon Jan 01 00:00:10 2007 +0000 - summary: add alpha - - - $ cd .. - $ hg clone gitrepo hgrepo2 | grep -v '^updating' - importing git objects into hg - 8 files updated, 0 files merged, 0 files removed, 0 files unresolved - $ hg -R hgrepo2 log --graph - @ commit: 0e82f70d8365 - │ bookmark: master - │ user: test ?test@example.com - │ date: Mon Jan 01 00:00:18 2007 +0000 - │ summary: add theta - │ - o commit: 353db02be541 - │ user: test - │ date: Mon Jan 01 00:00:17 2007 +0000 - │ summary: add eta - │ - o commit: 8b7698cb629f - │ user: test - │ date: Mon Jan 01 00:00:16 2007 +0000 - │ summary: add zeta - │ - o commit: 8264dd8cdfb8 - │ user: name - │ date: Mon Jan 01 00:00:15 2007 +0000 - │ summary: add epsilon - │ - o commit: ba47c351307f - │ user: name - │ date: Mon Jan 01 00:00:14 2007 +0000 - │ summary: add delta - │ - o commit: 44bb6eac290f - │ user: - │ date: Mon Jan 01 00:00:13 2007 +0000 - │ summary: add gamma - │ - o commit: 9699c3457ee8 - │ user: test (comment) - │ date: Mon Jan 01 00:00:12 2007 +0000 - │ summary: modify beta - │ - o commit: 4272913025dd - │ user: test - │ date: Mon Jan 01 00:00:11 2007 +0000 - │ summary: add beta - │ - o commit: 69982ec78c6d - bookmark: not-master - user: test - date: Mon Jan 01 00:00:10 2007 +0000 - summary: add alpha - - $ git --git-dir=gitrepo/.git log --pretty=medium master - commit 2fe60ba69727981e6ede78be70354c3a9e30e21d - Author: test ?test@example.com - Date: Mon Jan 1 00:00:18 2007 +0000 - - add theta - - commit 9f2f7cafdbf2e467928db98de8275141001d3081 - Author: test - Date: Mon Jan 1 00:00:17 2007 +0000 - - add eta - - commit 172a6f8d8064d73dff7013e395a9fe3cfc3ff807 - Author: test - Date: Mon Jan 1 00:00:16 2007 +0000 - - add zeta - - commit 71badb8e343a7da391a9b5d98909fbd2ca7d78f2 - Author: name - Date: Mon Jan 1 00:00:15 2007 +0000 - - add epsilon - - commit 9a9ae7b7f310d4a1a3e732a747ca26f06934f8d8 - Author: name - Date: Mon Jan 1 00:00:14 2007 +0000 - - add delta - - commit e4149a32e81e380193f59aa8773349201b8ed7f7 - Author: - Date: Mon Jan 1 00:00:13 2007 +0000 - - add gamma - - commit fae95aef5889a80103c2fbd5d14ff6eb8c9daf93 - Author: test ext:(%20%28comment%29) - Date: Mon Jan 1 00:00:12 2007 +0000 - - modify beta - - commit 0f378ab6c2c6b5514bd873d3faf8ac4b8095b001 - Author: test - Date: Mon Jan 1 00:00:11 2007 +0000 - - add beta - - commit 7eeab2ea75ec1ac0ff3d500b5b6f8a3447dd7c03 - Author: test - Date: Mon Jan 1 00:00:10 2007 +0000 - - add alpha diff --git a/eden/scm/tests/test-hggit-illegal-contents.t b/eden/scm/tests/test-hggit-illegal-contents.t deleted file mode 100644 index 052c53787d..0000000000 --- a/eden/scm/tests/test-hggit-illegal-contents.t +++ /dev/null @@ -1,136 +0,0 @@ -Check for contents we should refuse to export to git repositories (or -at least warn). - -Load commonly used test logic - $ . "$TESTDIR/hggit/testutil" - - $ hg init hg - $ cd hg - $ mkdir -p .git/hooks - $ cat > .git/hooks/post-update < #!/bin/sh - > echo pwned - > EOF - -#if fsmonitor - $ hg addremove -#else - $ hg addremove - adding .git/hooks/post-update - $ hg ci -m "we should refuse to export this" - $ hg book master - $ hg gexport - abort: Refusing to export likely-dangerous path '.git/hooks/post-update' - (If you need to continue, read about CVE-2014-9390 and then set '[git] blockdotgit = false' in your hgrc.) - [255] -#endif - $ cd .. - - $ rm -rf hg - $ hg init hg - $ cd hg - $ mkdir -p nested/.git/hooks/ - $ cat > nested/.git/hooks/post-update < #!/bin/sh - > echo pwnd - > EOF - $ chmod +x nested/.git/hooks/post-update - $ hg addremove - adding nested/.git/hooks/post-update - $ hg ci -m "also refuse to export this" - $ hg book master - $ hg gexport - abort: Refusing to export likely-dangerous path 'nested/.git/hooks/post-update' - (If you need to continue, read about CVE-2014-9390 and then set '[git] blockdotgit = false' in your hgrc.) - [255] -We can override if needed: - $ hg --config git.blockdotgit=false gexport - warning: path 'nested/.git/hooks/post-update' contains a dangerous path component. - It may not be legal to check out in Git. - It may also be rejected by some git server configurations. - $ cd .. - $ git clone hg/.hg/git git - Cloning into 'git'... - done. - error: invalid path 'nested/.git/hooks/post-update' - fatal: unable to checkout working tree - warning: Clone succeeded, but checkout failed. - You can inspect what was checked out with 'git status' - and retry with 'git restore --source=HEAD :/' - - [128] - -Now check something that case-folds to .git, which might let you own -Mac users: - - $ cd .. - $ rm -rf hg - $ hg init hg - $ cd hg - $ mkdir -p .GIT/hooks/ - $ cat > .GIT/hooks/post-checkout < #!/bin/sh - > echo pwnd - > EOF - $ chmod +x .GIT/hooks/post-checkout - $ hg addremove - adding .GIT/hooks/post-checkout - $ hg ci -m "also refuse to export this" - $ hg book master - $ hg gexport - $ cd .. - -And the NTFS case: - $ cd .. - $ rm -rf hg - $ hg init hg - $ cd hg - $ mkdir -p GIT~1/hooks/ - $ cat > GIT~1/hooks/post-checkout < #!/bin/sh - > echo pwnd - > EOF - $ chmod +x GIT~1/hooks/post-checkout - $ hg addremove - adding GIT~1/hooks/post-checkout - $ hg ci -m "also refuse to export this" - $ hg book master - $ hg gexport - abort: Refusing to export likely-dangerous path 'GIT~1/hooks/post-checkout' - (If you need to continue, read about CVE-2014-9390 and then set '[git] blockdotgit = false' in your hgrc.) - [255] - $ cd .. - -Now check a Git repository containing a Mercurial repository, which -you can't check out. - - $ rm -rf hg git nested - $ git init -q git - $ hg init nested - $ mv nested git - $ cd git - $ git add nested - $ fn_git_commit -m 'add a Mercurial repository' - $ cd .. - $ hg clone git hg - importing git objects into hg - abort: Refusing to import problematic path 'nested/.hg/00changelog.i' - (Mercurial cannot check out paths inside nested repositories; if you need to continue, then set '[git] blockdothg = false' in your hgrc.) - [255] - $ hg clone --config git.blockdothg=false git hg - importing git objects into hg - warning: path 'nested/.hg/00changelog.i' is within a nested repository, which Mercurial cannot check out. - warning: path 'nested/.hg/hgrc.dynamic' is within a nested repository, which Mercurial cannot check out. - warning: path 'nested/.hg/reponame' is within a nested repository, which Mercurial cannot check out. - warning: path 'nested/.hg/requires' is within a nested repository, which Mercurial cannot check out. - warning: path 'nested/.hg/store/metalog/blobs/index2-id' is within a nested repository, which Mercurial cannot check out. - warning: path 'nested/.hg/store/metalog/blobs/log' is within a nested repository, which Mercurial cannot check out. - warning: path 'nested/.hg/store/metalog/blobs/meta' is within a nested repository, which Mercurial cannot check out. - warning: path 'nested/.hg/store/metalog/roots/index2-reverse' is within a nested repository, which Mercurial cannot check out. - warning: path 'nested/.hg/store/metalog/roots/log' is within a nested repository, which Mercurial cannot check out. - warning: path 'nested/.hg/store/metalog/roots/meta' is within a nested repository, which Mercurial cannot check out. - warning: path 'nested/.hg/store/requires' is within a nested repository, which Mercurial cannot check out. - updating to branch default - abort: path 'nested/.hg/00changelog.i' is inside nested repo 'nested' - [255] - $ cd .. diff --git a/eden/scm/tests/test-hggit-incoming.t b/eden/scm/tests/test-hggit-incoming.t deleted file mode 100644 index 601b0e4dea..0000000000 --- a/eden/scm/tests/test-hggit-incoming.t +++ /dev/null @@ -1,132 +0,0 @@ -Load commonly used test logic - $ . "$TESTDIR/hggit/testutil" - $ disable treemanifest - - $ git init -q gitrepo - $ cd gitrepo - $ echo alpha > alpha - $ git add alpha - $ fn_git_commit -m "add alpha" - - $ cd .. - $ hg init hgrepo-empty - $ hg -R hgrepo-empty incoming gitrepo 2>&1 | grep -v 'no changes found' - comparing with gitrepo - commit: 7eeab2ea75ec - bookmark: master - user: test - date: Mon Jan 01 00:00:10 2007 +0000 - summary: add alpha - - - $ hg clone gitrepo hgrepo 2>&1 | grep -v '^updating' - importing git objects into hg - 1 files updated, 0 files merged, 0 files removed, 0 files unresolved - - $ hg -R hgrepo incoming 2>&1 | grep -v 'no changes found' - comparing with $TESTTMP/gitrepo - - $ cd gitrepo - $ echo beta > beta - $ git add beta - $ fn_git_commit -m 'add beta' - $ cd .. - - $ hg -R hgrepo incoming 2>&1 | grep -v 'no changes found' - comparing with $TESTTMP/gitrepo - commit: 9497a4ee62e1 - bookmark: master - user: test - date: Mon Jan 01 00:00:11 2007 +0000 - summary: add beta - - - $ cd gitrepo - $ git checkout -b b1 'HEAD^' - Switched to a new branch 'b1' - $ mkdir d - $ echo gamma > d/gamma - $ git add d/gamma - $ fn_git_commit -m'add d/gamma' - $ git tag t1 - - $ echo gamma 2 >> d/gamma - $ git add d/gamma - $ fn_git_commit -m'add d/gamma line 2' - $ cd ../hgrepo - $ hg incoming -p 2>&1 | grep -v 'no changes found' - comparing with $TESTTMP/gitrepo - commit: 9497a4ee62e1 - bookmark: master - user: test - date: Mon Jan 01 00:00:11 2007 +0000 - summary: add beta - - diff -r 69982ec78c6d -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 - - commit: 9865e289be73 - user: test - date: Mon Jan 01 00:00:12 2007 +0000 - summary: add d/gamma - - diff -r 69982ec78c6d -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 - - commit: 5202f48c20c9 - bookmark: b1 - user: test - 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 - $ hg incoming -r master 2>&1 | grep -v 'no changes found' - comparing with $TESTTMP/gitrepo - commit: 9497a4ee62e1 - bookmark: master - user: test - date: Mon Jan 01 00:00:11 2007 +0000 - summary: add beta - - $ hg incoming -r b1 2>&1 | grep -v 'no changes found' - comparing with $TESTTMP/gitrepo - commit: 9865e289be73 - user: test - date: Mon Jan 01 00:00:12 2007 +0000 - summary: add d/gamma - - commit: 5202f48c20c9 - bookmark: b1 - user: test - date: Mon Jan 01 00:00:13 2007 +0000 - summary: add d/gamma line 2 - - $ hg incoming -r t1 2>&1 | grep -v 'no changes found' - comparing with $TESTTMP/gitrepo - commit: 9865e289be73 - user: test - date: Mon Jan 01 00:00:12 2007 +0000 - summary: add d/gamma - - -nothing incoming after pull -"adding remote bookmark" message was added in Mercurial 2.3 - $ hg pull 2>&1 | grep -v "adding remote bookmark" - pulling from $TESTTMP/gitrepo - importing git objects into hg - $ hg incoming 2>&1 | grep -v 'no changes found' - comparing with $TESTTMP/gitrepo diff --git a/eden/scm/tests/test-hggit-keywords.t b/eden/scm/tests/test-hggit-keywords.t deleted file mode 100644 index ecbd6246c0..0000000000 --- a/eden/scm/tests/test-hggit-keywords.t +++ /dev/null @@ -1,58 +0,0 @@ -Load commonly used test logic - $ . "$TESTDIR/hggit/testutil" - - $ git init -q gitrepo - $ cd gitrepo - $ echo alpha > alpha - $ git add alpha - $ fn_git_commit -m 'add alpha' - $ echo beta > beta - $ git add beta - $ fn_git_commit -m 'add beta' - -This commit is called gamma10 so that its hash will have the same initial digit -as commit alpha. This lets us test ambiguous abbreviated identifiers. - - $ echo gamma10 > gamma10 - $ git add gamma10 - $ fn_git_commit -m 'add gamma10' - - $ cd .. - - $ hg clone gitrepo hgrepo | grep -v '^updating' - importing git objects into hg - 3 files updated, 0 files merged, 0 files removed, 0 files unresolved - $ cd hgrepo - $ echo gamma > gamma - $ hg add gamma - $ hg commit -m 'add gamma' - -Remove the mapfile so we can ensure the gitnode is from the extras not the mapfile. - - $ mv .hg/git-mapfile .hg/git-mapfile-bak - $ hg log --template "{node} {node|short} {gitnode} {gitnode|short}\n" - f5172ebb976873f9e41d2958e3b665a985128b00 f5172ebb9768 - fedf4edd982fb98273f2255d6b97c892ec208427 fedf4edd982f 7e2a5465ff4e3b992c429bb87a392620a0ac97b7 7e2a5465ff4e - 3bb02b6794ddc0b498cdc15f59f2e6724cabfa2f 3bb02b6794dd 9497a4ee62e16ee641860d7677cdb2589ea15554 9497a4ee62e1 - 69982ec78c6dd2f24b3b62f3e2baaa79ab48ed93 69982ec78c6d 7eeab2ea75ec1ac0ff3d500b5b6f8a3447dd7c03 7eeab2ea75ec - $ mv .hg/git-mapfile-bak .hg/git-mapfile - $ hg log --template "fromgit {node}\n" --rev "fromgit()" - fromgit 69982ec78c6dd2f24b3b62f3e2baaa79ab48ed93 - fromgit 3bb02b6794ddc0b498cdc15f59f2e6724cabfa2f - fromgit fedf4edd982fb98273f2255d6b97c892ec208427 - $ hg log --template "gitnode_existsA {node}\n" --rev "gitnode(9497a4ee62e16ee641860d7677cdb2589ea15554)" - gitnode_existsA 3bb02b6794ddc0b498cdc15f59f2e6724cabfa2f - $ hg log --template "gitnode_existsB {node}\n" --rev "gitnode(7eeab)" - gitnode_existsB 69982ec78c6dd2f24b3b62f3e2baaa79ab48ed93 - $ hg log --rev "gitnode(7e)" - abort: git-mapfile@7e: ambiguous identifier! - [255] - $ hg log --template "gitnode_notexists {node}\n" --rev "gitnode(1234567890ab)" - -Try other extensioins that provide "{gitnode}": - $ hg log -r 'tip^' --template "{gitnode}\n" - 7e2a5465ff4e3b992c429bb87a392620a0ac97b7 - $ hg log -r 'tip^' --template "{gitnode}\n" --config extensions.fbscmquery= - 7e2a5465ff4e3b992c429bb87a392620a0ac97b7 - $ hg log -r 'tip^' --template "{gitnode}\n" --config extensions.gitrevset= - 7e2a5465ff4e3b992c429bb87a392620a0ac97b7 diff --git a/eden/scm/tests/test-hggit-merge.t b/eden/scm/tests/test-hggit-merge.t deleted file mode 100644 index 4a462446b1..0000000000 --- a/eden/scm/tests/test-hggit-merge.t +++ /dev/null @@ -1,84 +0,0 @@ -Load commonly used test logic - $ . "$TESTDIR/hggit/testutil" - - $ git init -q gitrepo - $ cd gitrepo - $ echo alpha > alpha - $ git add alpha - $ fn_git_commit -m 'add alpha' - - $ git checkout -b beta - Switched to a new branch 'beta' - $ echo beta > beta - $ git add beta - $ fn_git_commit -m 'add beta' - - $ git checkout master - Switched to branch 'master' - $ echo gamma > gamma - $ git add gamma - $ fn_git_commit -m 'add gamma' - -clean merge - $ git merge beta - Merge made by the 'recursive' strategy. - beta | 1 + - 1 file changed, 1 insertion(+) - create mode 100644 beta - - $ cd .. - $ git init -q --bare gitrepo2 - - $ hg clone gitrepo hgrepo | grep -v '^updating' - importing git objects into hg - 3 files updated, 0 files merged, 0 files removed, 0 files unresolved - $ cd hgrepo - -clear the cache to be sure it is regenerated correctly - $ hg gclear - clearing out the git cache data - $ hg push ../gitrepo2 - pushing to ../gitrepo2 - searching for changes - adding objects - added 4 commits with 4 trees and 3 blobs - - $ cd .. -git log in repo pushed from hg - $ git --git-dir=gitrepo2 log --pretty=medium master - commit fdbdf0eb28dbc846a66f8bf458c5aa8ebfc87412 - Merge: 3ab4bf1 dbed4f6 - Author: test - Date: Mon Jan 1 00:00:12 2007 +0000 - - Merge branch 'beta' - - commit 3ab4bf1785d6dbdb82467bf09e6aa1450312968d - Author: test - Date: Mon Jan 1 00:00:12 2007 +0000 - - add gamma - - commit dbed4f6a8ff04d4d1f0a5ce79f9a07cf0f461d7f - Author: test - Date: Mon Jan 1 00:00:11 2007 +0000 - - add beta - - commit 205598a42833e532ad20d80414b8e3b85a65936e - Author: test - Date: Mon Jan 1 00:00:10 2007 +0000 - - add alpha - $ git --git-dir=gitrepo2 log --pretty=medium beta - commit dbed4f6a8ff04d4d1f0a5ce79f9a07cf0f461d7f - Author: test - Date: Mon Jan 1 00:00:11 2007 +0000 - - add beta - - commit 205598a42833e532ad20d80414b8e3b85a65936e - Author: test - Date: Mon Jan 1 00:00:10 2007 +0000 - - add alpha diff --git a/eden/scm/tests/test-hggit-nodemap.t b/eden/scm/tests/test-hggit-nodemap.t deleted file mode 100644 index e0ab3123b3..0000000000 --- a/eden/scm/tests/test-hggit-nodemap.t +++ /dev/null @@ -1,63 +0,0 @@ -Load commonly used test logic - $ . "$TESTDIR/hggit/testutil" - -set up a git repo - $ git init -q gitrepo - $ cd gitrepo - $ echo alpha > alpha - $ git add alpha - $ fn_git_commit -m 'add alpha' - $ git checkout -qb beta - $ echo beta > beta - $ git add beta - $ fn_git_commit -m 'add beta' - $ cd .. - -pull a branch with the old mapfile - $ hg init hgrepo - $ cd hgrepo - $ echo "[paths]" >> .hg/hgrc - $ echo "default=$TESTTMP/gitrepo" >> .hg/hgrc - $ hg pull -r master - pulling from $TESTTMP/gitrepo - importing git objects into hg - $ ls -d .hg/git-mapfile* - .hg/git-mapfile - $ hg log -r tip -T '{gitnode}\n' - 7eeab2ea75ec1ac0ff3d500b5b6f8a3447dd7c03 - -pull more commits with the new nodemap - $ setconfig hggit.indexedlognodemap=True - $ hg pull -r beta - pulling from $TESTTMP/gitrepo - importing git objects into hg - $ ls -d .hg/git-mapfile* - .hg/git-mapfile - .hg/git-mapfile-log - $ hg log -r 'tip^::tip' -T '{gitnode}\n' - 7eeab2ea75ec1ac0ff3d500b5b6f8a3447dd7c03 - 9497a4ee62e16ee641860d7677cdb2589ea15554 - -can still get the mapping without the old map file - $ mv .hg/git-mapfile .hg/git-mapfile.old - $ hg log -r 'tip^::tip' -T '{gitnode}\n' - 7eeab2ea75ec1ac0ff3d500b5b6f8a3447dd7c03 - 9497a4ee62e16ee641860d7677cdb2589ea15554 - $ mv .hg/git-mapfile.old .hg/git-mapfile - -can still get the mapping without the nodemap - $ mv .hg/git-mapfile-log .hg/git-mapfile-log.old - $ hg log -r 'tip^::tip' -T '{gitnode}\n' - 7eeab2ea75ec1ac0ff3d500b5b6f8a3447dd7c03 - 9497a4ee62e16ee641860d7677cdb2589ea15554 - $ mv .hg/git-mapfile-log.old .hg/git-mapfile-log - -git cleanup cleans nodemap - $ hg bundle -r tip --base 'tip^' ../mybundle.hg - 1 changesets found - $ hg debugstrip -r tip --no-backup - $ hg git-cleanup - git commit map cleaned - $ hg unbundle -q ../mybundle.hg - $ hg log -r tip -T '{gitnode}\n' - 9497a4ee62e16ee641860d7677cdb2589ea15554 diff --git a/eden/scm/tests/test-hggit-octopus.t b/eden/scm/tests/test-hggit-octopus.t deleted file mode 100644 index 330f4f330c..0000000000 --- a/eden/scm/tests/test-hggit-octopus.t +++ /dev/null @@ -1,163 +0,0 @@ -Load commonly used test logic - $ . "$TESTDIR/hggit/testutil" - - $ git init -q gitrepo - $ cd gitrepo - $ echo alpha > alpha - $ git add alpha - $ fn_git_commit -m 'add alpha' - - $ git checkout -b branch1 - Switched to a new branch 'branch1' - $ echo beta > beta - $ git add beta - $ fn_git_commit -m 'add beta' - - $ git checkout -b branch2 master - Switched to a new branch 'branch2' - $ echo gamma > gamma - $ git add gamma - $ fn_git_commit -m 'add gamma' - - $ git checkout -b branch3 master - Switched to a new branch 'branch3' - $ echo epsilon > epsilon - $ git add epsilon - $ fn_git_commit -m 'add epsilon' - - $ git checkout -b branch4 master - Switched to a new branch 'branch4' - $ echo zeta > zeta - $ git add zeta - $ fn_git_commit -m 'add zeta' - - $ git checkout master - Switched to branch 'master' - $ echo delta > delta - $ git add delta - $ fn_git_commit -m 'add delta' - - $ git merge branch1 branch2 - Trying simple merge with branch1 - Trying simple merge with branch2 - Merge made by the 'octopus' strategy. - beta | 1 + - gamma | 1 + - 2 files changed, 2 insertions(+) - create mode 100644 beta - create mode 100644 gamma - - $ git merge branch3 branch4 - Trying simple merge with branch3 - Trying simple merge with branch4 - Merge made by the 'octopus' strategy. - epsilon | 1 + - zeta | 1 + - 2 files changed, 2 insertions(+) - create mode 100644 epsilon - create mode 100644 zeta - - $ cd .. - $ git init -q --bare gitrepo2 - - $ hg clone gitrepo hgrepo | grep -v '^updating' - importing git objects into hg - 6 files updated, 0 files merged, 0 files removed, 0 files unresolved - $ cd hgrepo - $ hg log --graph --style compact - @ [master] 49ab838a9c6d 2007-01-01 00:00 +0000 test - ├─╮ Merge branches 'branch3' and 'branch4' - │ │ - │ o 772137582d44 2007-01-01 00:00 +0000 test - │ ├─╮ Merge branches 'branch3' and 'branch4' - │ │ │ - o │ │ 605318eb3cbf 2007-01-01 00:00 +0000 test - ├─────╮ Merge branches 'branch1' and 'branch2' - │ │ │ │ - │ │ │ o c37d2773086b 2007-01-01 00:00 +0000 test - │ │ │ ├─╮ Merge branches 'branch1' and 'branch2' - │ │ │ │ │ - o │ │ │ │ e70767a0294a 2007-01-01 00:00 +0000 test - │ │ │ │ │ add delta - │ │ │ │ │ - │ │ o │ │ [branch4] 8b150650bbba 2007-01-01 00:00 +0000 test - ├───╯ │ │ add zeta - │ │ │ │ - │ o │ │ [branch3] b869fdf3e852 2007-01-01 00:00 +0000 test - ├─╯ │ │ add epsilon - │ │ │ - │ │ o [branch2] 328de8a94600 2007-01-01 00:00 +0000 test - ├───────╯ add gamma - │ │ - │ o [branch1] 3bb02b6794dd 2007-01-01 00:00 +0000 test - ├─────╯ add beta - │ - o 69982ec78c6d 2007-01-01 00:00 +0000 test - add alpha - - $ hg gverify -r 'max(desc(Merge))' - verifying rev 49ab838a9c6d against git commit b32ff845df61df998206b630e4370a44f9b36845 - $ hg gverify -r 772137582d44293df8e61e0f3b99ced712235bba - abort: no git commit found for rev 772137582d44 - (if this is an octopus merge, verify against the last rev) - [255] - - $ hg gclear - clearing out the git cache data - $ hg push ../gitrepo2 - pushing to ../gitrepo2 - searching for changes - adding objects - added 8 commits with 8 trees and 6 blobs - $ cd .. - - $ git --git-dir=gitrepo2 log --pretty=medium - commit 2359e57d541911d60d80549ad41462b220d10c65 - Merge: f37a7b7 7ceac1d 692cf8a - Author: test - Date: Mon Jan 1 00:00:15 2007 +0000 - - Merge branches 'branch3' and 'branch4' - - commit f37a7b7b4969612fd5ab85b6d31d6465c25fef0b - Merge: 47293d4 dbed4f6 3ab4bf1 - Author: test - Date: Mon Jan 1 00:00:15 2007 +0000 - - Merge branches 'branch1' and 'branch2' - - commit 47293d46a21e55863c4a47f168731a2b9f95712b - Author: test - Date: Mon Jan 1 00:00:15 2007 +0000 - - add delta - - commit 692cf8ab35262a87694759a7668700632ca52c47 - Author: test - Date: Mon Jan 1 00:00:14 2007 +0000 - - add zeta - - commit 7ceac1da981d4d67a88c662cc1c27e5e40c95884 - Author: test - Date: Mon Jan 1 00:00:13 2007 +0000 - - add epsilon - - commit 3ab4bf1785d6dbdb82467bf09e6aa1450312968d - Author: test - Date: Mon Jan 1 00:00:12 2007 +0000 - - add gamma - - commit dbed4f6a8ff04d4d1f0a5ce79f9a07cf0f461d7f - Author: test - Date: Mon Jan 1 00:00:11 2007 +0000 - - add beta - - commit 205598a42833e532ad20d80414b8e3b85a65936e - Author: test - Date: Mon Jan 1 00:00:10 2007 +0000 - - add alpha diff --git a/eden/scm/tests/test-hggit-outgoing.t b/eden/scm/tests/test-hggit-outgoing.t deleted file mode 100644 index bdee33e927..0000000000 --- a/eden/scm/tests/test-hggit-outgoing.t +++ /dev/null @@ -1,135 +0,0 @@ -Load commonly used test logic - $ . "$TESTDIR/hggit/testutil" - - $ git init -q gitrepo - $ cd gitrepo - $ echo alpha > alpha - $ git add alpha - $ fn_git_commit -m "add alpha" - $ git branch alpha - $ git show-ref - 7eeab2ea75ec1ac0ff3d500b5b6f8a3447dd7c03 refs/heads/alpha - 7eeab2ea75ec1ac0ff3d500b5b6f8a3447dd7c03 refs/heads/master - - $ cd .. - $ hg clone gitrepo hgrepo | grep -v '^updating' - importing git objects into hg - 1 files updated, 0 files merged, 0 files removed, 0 files unresolved - - $ cd hgrepo - $ hg update -q master - $ echo beta > beta - $ hg add beta - $ fn_hg_commit -m 'add beta' - - - $ echo gamma > gamma - $ hg add gamma - $ fn_hg_commit -m 'add gamma' - - $ hg book -r 574e2d660a7d7bbaf97251f694c8c8327f0db957 beta - - $ hg outgoing | grep -v 'searching for changes' - comparing with */gitrepo (glob) - commit: 574e2d660a7d - bookmark: beta - user: test - date: Mon Jan 01 00:00:11 2007 +0000 - summary: add beta - - commit: 49480a0fbf45 - bookmark: master - user: test - date: Mon Jan 01 00:00:12 2007 +0000 - summary: add gamma - - $ hg outgoing -r beta | grep -v 'searching for changes' - comparing with */gitrepo (glob) - commit: 574e2d660a7d - bookmark: beta - user: test - date: Mon Jan 01 00:00:11 2007 +0000 - summary: add beta - - $ hg outgoing -r master | grep -v 'searching for changes' - comparing with */gitrepo (glob) - commit: 574e2d660a7d - bookmark: beta - user: test - date: Mon Jan 01 00:00:11 2007 +0000 - summary: add beta - - commit: 49480a0fbf45 - bookmark: master - user: test - date: Mon Jan 01 00:00:12 2007 +0000 - summary: add gamma - - - $ cd .. - -some more work on master from git - $ cd gitrepo - -Check state of refs after outgoing - $ git show-ref - 7eeab2ea75ec1ac0ff3d500b5b6f8a3447dd7c03 refs/heads/alpha - 7eeab2ea75ec1ac0ff3d500b5b6f8a3447dd7c03 refs/heads/master - - $ git checkout master - Already on 'master' - $ echo delta > delta - $ git add delta - $ fn_git_commit -m "add delta" - - $ cd .. - - $ cd hgrepo -this will fail # maybe we should try to make it work - $ hg outgoing - comparing with */gitrepo (glob) - abort: branch 'refs/heads/master' changed on the server, please pull and merge before pushing - [255] -let's pull and try again - $ hg pull 2>&1 | grep -v 'divergent bookmark' - pulling from */gitrepo (glob) - importing git objects into hg - $ hg outgoing | grep -v 'searching for changes' - comparing with */gitrepo (glob) - commit: 574e2d660a7d - bookmark: beta - user: test - date: Mon Jan 01 00:00:11 2007 +0000 - summary: add beta - - commit: 49480a0fbf45 - bookmark: master - user: test - date: Mon Jan 01 00:00:12 2007 +0000 - summary: add gamma - - $ hg outgoing -r beta | grep -v 'searching for changes' - comparing with */gitrepo (glob) - commit: 574e2d660a7d - bookmark: beta - user: test - date: Mon Jan 01 00:00:11 2007 +0000 - summary: add beta - - $ hg outgoing -r master | grep -v 'searching for changes' - comparing with */gitrepo (glob) - commit: 574e2d660a7d - bookmark: beta - user: test - date: Mon Jan 01 00:00:11 2007 +0000 - summary: add beta - - commit: 49480a0fbf45 - bookmark: master - user: test - date: Mon Jan 01 00:00:12 2007 +0000 - summary: add gamma - - - - $ cd .. diff --git a/eden/scm/tests/test-hggit-pull-after-strip.t b/eden/scm/tests/test-hggit-pull-after-strip.t deleted file mode 100644 index 085aa68715..0000000000 --- a/eden/scm/tests/test-hggit-pull-after-strip.t +++ /dev/null @@ -1,88 +0,0 @@ -Load commonly used test logic - $ . "$TESTDIR/hggit/testutil" - - $ git init -q gitrepo - $ cd gitrepo - $ echo alpha > alpha - $ git add alpha - $ fn_git_commit -m 'add alpha' - - $ git tag alpha - - $ git checkout -b beta - Switched to a new branch 'beta' - $ echo beta > beta - $ git add beta - $ fn_git_commit -m 'add beta' - - - $ cd .. -clone a tag - $ hg clone -r alpha gitrepo hgrepo-a 2>&1 | grep -v '^updating' - importing git objects into hg - 1 files updated, 0 files merged, 0 files removed, 0 files unresolved - $ hg -R hgrepo-a log --graph - @ commit: 69982ec78c6d - bookmark: master - user: test - date: Mon Jan 01 00:00:10 2007 +0000 - summary: add alpha - -clone a branch - $ hg clone -r beta gitrepo hgrepo-b 2>&1 | grep -v '^updating' - importing git objects into hg - 2 files updated, 0 files merged, 0 files removed, 0 files unresolved - $ hg -R hgrepo-b log --graph - @ commit: 3bb02b6794dd - │ bookmark: beta - │ user: test - │ date: Mon Jan 01 00:00:11 2007 +0000 - │ summary: add beta - │ - o commit: 69982ec78c6d - bookmark: master - user: test - date: Mon Jan 01 00:00:10 2007 +0000 - summary: add alpha - - $ cd gitrepo - $ echo beta line 2 >> beta - $ git add beta - $ fn_git_commit -m 'add to beta' - - $ cd .. - $ cd hgrepo-b - $ hg debugstrip tip 2>&1 2>&1 | grep -v saving 2>&1 | grep -v backup - 0 files updated, 0 files merged, 1 files removed, 0 files unresolved - $ hg pull -r beta - pulling from $TESTTMP/gitrepo - importing git objects into hg - abort: you appear to have run strip - please run hg git-cleanup - [255] - $ hg git-cleanup - git commit map cleaned -pull works after 'hg git-cleanup' -"adding remote bookmark" message was added in Mercurial 2.3 - $ hg pull -r beta 2>&1 | grep -v "adding remote bookmark" - pulling from $TESTTMP/gitrepo - importing git objects into hg - $ hg log --graph - o commit: 3db9bf9073b5 - │ bookmark: beta - │ user: test - │ date: Mon Jan 01 00:00:12 2007 +0000 - │ summary: add to beta - │ - o commit: 3bb02b6794dd - │ user: test - │ date: Mon Jan 01 00:00:11 2007 +0000 - │ summary: add beta - │ - @ commit: 69982ec78c6d - bookmark: master - user: test - date: Mon Jan 01 00:00:10 2007 +0000 - summary: add alpha - - - $ cd .. diff --git a/eden/scm/tests/test-hggit-pull.t b/eden/scm/tests/test-hggit-pull.t deleted file mode 100644 index ec522a47b4..0000000000 --- a/eden/scm/tests/test-hggit-pull.t +++ /dev/null @@ -1,369 +0,0 @@ -Load commonly used test logic - $ . "$TESTDIR/hggit/testutil" - -set up a git repo with some commits, branches and a tag - $ git init -q gitrepo - $ cd gitrepo - $ echo alpha > alpha - $ git add alpha - $ fn_git_commit -m 'add alpha' - $ git checkout -qB t_alpha - $ git checkout -qb beta - $ echo beta > beta - $ git add beta - $ fn_git_commit -m 'add beta' - $ git checkout -qb delta master - $ echo delta > delta - $ git add delta - $ fn_git_commit -m 'add delta' - $ cd .. - -pull a tag - $ hg init hgrepo - $ echo "[paths]" >> hgrepo/.hg/hgrc - $ echo "default=$TESTTMP/gitrepo" >> hgrepo/.hg/hgrc - $ hg -R hgrepo pull -r t_alpha - pulling from $TESTTMP/gitrepo - importing git objects into hg - $ hg -R hgrepo update t_alpha - 1 files updated, 0 files merged, 0 files removed, 0 files unresolved - (activating bookmark t_alpha) - $ hg -R hgrepo log --graph - @ commit: 69982ec78c6d - bookmark: master - bookmark: t_alpha - user: test - date: Mon Jan 01 00:00:10 2007 +0000 - summary: add alpha - - -pull via ssh -# dummyssh doesn't actually work with Git, but it gets far enough to prove that -# the connection succeeded and git was invoked. - $ hg -R hgrepo pull --config paths.default=git+ssh://user@dummy/gitrepo --config ui.ssh="$(dummysshcmd)" - pulling from git+ssh://user@dummy/gitrepo - fatal: '/gitrepo' does not appear to be a git repository - abort: git remote error: The remote server unexpectedly closed the connection. - [255] - -no-op pull - $ hg -R hgrepo pull -r t_alpha - pulling from $TESTTMP/gitrepo - no changes found - -no-op pull with added bookmark - $ cd gitrepo - $ git checkout -qb epsilon t_alpha - $ cd .. - $ hg -R hgrepo pull -r epsilon - pulling from $TESTTMP/gitrepo - no changes found - -pull a branch - $ hg -R hgrepo pull -r beta - pulling from $TESTTMP/gitrepo - importing git objects into hg - $ hg -R hgrepo log --graph - o commit: 3bb02b6794dd - │ bookmark: beta - │ user: test - │ date: Mon Jan 01 00:00:11 2007 +0000 - │ summary: add beta - │ - @ commit: 69982ec78c6d - bookmark: epsilon - bookmark: master - bookmark: t_alpha - user: test - date: Mon Jan 01 00:00:10 2007 +0000 - summary: add alpha - -add another commit and tag to the git repo - $ cd gitrepo - $ git checkout -q beta - $ git tag t_beta - $ git checkout -q master - $ echo gamma > gamma - $ git add gamma - $ fn_git_commit -m 'add gamma' - $ cd .. - -pull everything else - $ hg -R hgrepo pull - pulling from $TESTTMP/gitrepo - importing git objects into hg - $ hg -R hgrepo log --graph - o commit: 78f47553e70d - │ bookmark: master - │ user: test - │ date: Mon Jan 01 00:00:13 2007 +0000 - │ summary: add gamma - │ - │ o commit: 0a22250873dd - ├─╯ bookmark: delta - │ user: test - │ date: Mon Jan 01 00:00:12 2007 +0000 - │ summary: add delta - │ - │ o commit: 3bb02b6794dd - ├─╯ bookmark: beta - │ user: test - │ date: Mon Jan 01 00:00:11 2007 +0000 - │ summary: add beta - │ - @ commit: 69982ec78c6d - bookmark: epsilon - bookmark: t_alpha - user: test - date: Mon Jan 01 00:00:10 2007 +0000 - summary: add alpha - -add a merge to the git repo - $ cd gitrepo - $ git merge beta | sed 's/| */| /' - Merge made by the 'recursive' strategy. - beta | 1 + - 1 file changed, 1 insertion(+) - create mode 100644 beta - $ cd .. - -pull the merge - $ hg -R hgrepo pull - pulling from $TESTTMP/gitrepo - importing git objects into hg - $ hg -R hgrepo log --graph - o commit: 10c1db28cc89 - ├─╮ bookmark: master - │ │ user: test - │ │ date: Mon Jan 01 00:00:13 2007 +0000 - │ │ summary: Merge branch 'beta' - │ │ - │ o commit: 78f47553e70d - │ │ user: test - │ │ date: Mon Jan 01 00:00:13 2007 +0000 - │ │ summary: add gamma - │ │ - │ │ o commit: 0a22250873dd - │ ├─╯ bookmark: delta - │ │ user: test - │ │ date: Mon Jan 01 00:00:12 2007 +0000 - │ │ summary: add delta - │ │ - o │ commit: 3bb02b6794dd - ├─╯ bookmark: beta - │ user: test - │ date: Mon Jan 01 00:00:11 2007 +0000 - │ summary: add beta - │ - @ commit: 69982ec78c6d - bookmark: epsilon - bookmark: t_alpha - user: test - date: Mon Jan 01 00:00:10 2007 +0000 - summary: add alpha - -pull with wildcards - $ cd gitrepo - $ git checkout -qb releases/v1 master - $ echo zeta > zeta - $ git add zeta - $ fn_git_commit -m 'add zeta' - $ git checkout -qb releases/v2 master - $ echo eta > eta - $ git add eta - $ fn_git_commit -m 'add eta' - $ git checkout -qb notreleases/v1 master - $ echo theta > theta - $ git add theta - $ fn_git_commit -m 'add theta' - -ensure that releases/v1 and releases/v2 are pulled but not notreleases/v1 - $ cd .. - $ hg -R hgrepo pull -r 'releases/*' - pulling from $TESTTMP/gitrepo - importing git objects into hg - $ hg -R hgrepo log --graph - o commit: 47d709856ce8 - │ bookmark: releases/v2 - │ user: test - │ date: Mon Jan 01 00:00:15 2007 +0000 - │ summary: add eta - │ - │ o commit: e09a50abb1b1 - ├─╯ bookmark: releases/v1 - │ user: test - │ date: Mon Jan 01 00:00:14 2007 +0000 - │ summary: add zeta - │ - o commit: 10c1db28cc89 - ├─╮ bookmark: master - │ │ user: test - │ │ date: Mon Jan 01 00:00:13 2007 +0000 - │ │ summary: Merge branch 'beta' - │ │ - │ o commit: 78f47553e70d - │ │ user: test - │ │ date: Mon Jan 01 00:00:13 2007 +0000 - │ │ summary: add gamma - │ │ - │ │ o commit: 0a22250873dd - │ ├─╯ bookmark: delta - │ │ user: test - │ │ date: Mon Jan 01 00:00:12 2007 +0000 - │ │ summary: add delta - │ │ - o │ commit: 3bb02b6794dd - ├─╯ bookmark: beta - │ user: test - │ date: Mon Jan 01 00:00:11 2007 +0000 - │ summary: add beta - │ - @ commit: 69982ec78c6d - bookmark: epsilon - bookmark: t_alpha - user: test - date: Mon Jan 01 00:00:10 2007 +0000 - summary: add alpha - - -add old and new commits to the git repo -- make sure we're using the commit date -and not the author date - $ cat >> $HGRCPATH < [git] - > mindate = 2014-01-02 00:00:00 +0000 - > EOF - $ cd gitrepo - $ git checkout -q master - $ echo oldcommit > oldcommit - $ git add oldcommit - $ GIT_AUTHOR_DATE="2014-03-01 00:00:00 +0000" \ - > GIT_COMMITTER_DATE="2009-01-01 00:00:00 +0000" \ - > git commit -m oldcommit > /dev/null || echo "git commit error" -also add an annotated tag - $ git checkout -q 'master^' - $ echo oldtag > oldtag - $ git add oldtag - $ GIT_AUTHOR_DATE="2014-03-01 00:00:00 +0000" \ - > GIT_COMMITTER_DATE="2009-01-01 00:00:00 +0000" \ - > git commit -m oldtag > /dev/null || echo "git commit error" - $ GIT_COMMITTER_DATE="2009-02-01 00:00:00 +0000" \ - > git tag -a -m 'tagging oldtag' oldtag - $ cd .. - $ hg -R hgrepo pull - pulling from $TESTTMP/gitrepo - no changes found - $ hg -R hgrepo log -r master - commit: 10c1db28cc89 - bookmark: master - user: test - date: Mon Jan 01 00:00:13 2007 +0000 - summary: Merge branch 'beta' - - - $ cd gitrepo - $ git checkout -q master - $ echo newcommit > newcommit - $ git add newcommit - $ GIT_AUTHOR_DATE="2014-01-01 00:00:00 +0000" \ - > GIT_COMMITTER_DATE="2014-01-02 00:00:00 +0000" \ - > git commit -m newcommit > /dev/null || echo "git commit error" - $ git checkout -q refs/tags/oldtag - $ GIT_COMMITTER_DATE="2014-01-02 00:00:00 +0000" \ - > git tag -a -m 'tagging newtag' newtag - $ cd .. - $ hg -R hgrepo pull - pulling from $TESTTMP/gitrepo - importing git objects into hg - $ hg -R hgrepo heads - commit: 497a89953f7c - bookmark: master - user: test - date: Wed Jan 01 00:00:00 2014 +0000 - summary: newcommit - - commit: 6809e41e5128 - user: test - date: Sat Mar 01 00:00:00 2014 +0000 - summary: oldtag - - commit: 47d709856ce8 - bookmark: releases/v2 - user: test - date: Mon Jan 01 00:00:15 2007 +0000 - summary: add eta - - commit: e09a50abb1b1 - bookmark: releases/v1 - user: test - date: Mon Jan 01 00:00:14 2007 +0000 - summary: add zeta - - commit: 0a22250873dd - bookmark: delta - user: test - date: Mon Jan 01 00:00:12 2007 +0000 - summary: add delta - - -Skip commits using hggit.skipgithashes - $ hg init skiprepo - $ cd skiprepo - $ hg pull --config extensions.hggit= --config hggit.skipgithashes=cee7863e67baaf98d4b6f3645dd9fa78fba9de0d ../gitrepo - pulling from ../gitrepo - importing git objects into hg - forcing git commit cee7863e67baaf98d4b6f3645dd9fa78fba9de0d to be empty - $ hg log -G --stat -T '{desc}' - o newcommit newcommit | 1 + - │ 1 files changed, 1 insertions(+), 0 deletions(-) - │ - o oldcommit oldcommit | 1 + - │ 1 files changed, 1 insertions(+), 0 deletions(-) - │ - │ o oldtag oldtag | 1 + - ├─╯ 1 files changed, 1 insertions(+), 0 deletions(-) - │ - o Merge branch 'beta' beta | 1 + - ├─╮ 1 files changed, 1 insertions(+), 0 deletions(-) - │ │ - │ o add beta beta | 1 + - │ │ 1 files changed, 1 insertions(+), 0 deletions(-) - │ │ - o │ add gamma - ├─╯ - o add alpha alpha | 1 + - 1 files changed, 1 insertions(+), 0 deletions(-) - - $ hg log -r 4d4019e3dd06 --stat - commit: 4d4019e3dd06 - user: test - date: Mon Jan 01 00:00:13 2007 +0000 - summary: add gamma - - -test for ssh vulnerability - - $ cat >> $HGRCPATH << EOF - > [ui] - > ssh = ssh -o ConnectTimeout=1 - > EOF - - $ hg init a - $ cd a - $ hg pull 'git+ssh://-oProxyCommand=rm${IFS}nonexistent/path' 2>&1 >/dev/null - pulling from git+ssh://-oProxyCommand%3Drm%24%7BIFS%7Dnonexistent/path - abort: potentially unsafe hostname: '-oProxyCommand=rm${IFS}nonexistent' - [255] - $ hg pull 'git+ssh://-oProxyCommand=rm%20nonexistent/path' 2>&1 >/dev/null - pulling from git+ssh://-oProxyCommand%3Drm%20nonexistent/path - abort: potentially unsafe hostname: '-oProxyCommand=rm nonexistent' - [255] - $ hg pull 'git+ssh://fakehost|shellcommand/path' 2>&1 >/dev/null - pulling from git+ssh://fakehost%7Cshellcommand/path - ssh: .* fakehost%7[Cc]shellcommand.* (re) - abort: git remote error: The remote server unexpectedly closed the connection. - [255] - $ hg pull 'git+ssh://fakehost%7Cshellcommand/path' 2>&1 >/dev/null - pulling from git+ssh://fakehost%7Cshellcommand/path - ssh: .* fakehost%7[Cc]shellcommand.* (re) - abort: git remote error: The remote server unexpectedly closed the connection. - [255] diff --git a/eden/scm/tests/test-hggit-push-r.t b/eden/scm/tests/test-hggit-push-r.t deleted file mode 100644 index b1ddd2aa9f..0000000000 --- a/eden/scm/tests/test-hggit-push-r.t +++ /dev/null @@ -1,139 +0,0 @@ - $ disable treemanifest -Load commonly used test logic - $ . "$TESTDIR/hggit/testutil" - - $ enable remotenames - $ hg init test - $ cd test - $ cat >>afile < 0 - > EOF - $ hg add afile - $ hg commit -m "0.0" - $ cat >>afile < 1 - > EOF - $ hg commit -m "0.1" - $ cat >>afile < 2 - > EOF - $ hg commit -m "0.2" - $ cat >>afile < 3 - > EOF - $ hg commit -m "0.3" - $ hg update -C 'desc(0.0)' - 1 files updated, 0 files merged, 0 files removed, 0 files unresolved - $ cat >>afile < 1 - > EOF - $ hg commit -m "1.1" - $ cat >>afile < 2 - > EOF - $ hg commit -m "1.2" - $ cat >fred < a line - > EOF - $ cat >>afile < 3 - > EOF - $ hg add fred - $ hg commit -m "1.3" - $ hg mv afile adifferentfile - $ hg commit -m "1.3m" - $ hg update -C 'desc(0.3)' - 1 files updated, 0 files merged, 2 files removed, 0 files unresolved - $ 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" --to master --force --create - > cd test-"$i" - > hg verify - > cd .. - > done - pushing rev f9ee2f85a263 to destination test-0 bookmark master - searching for changes - adding changesets - adding manifests - adding file changes - added 1 changesets with 1 changes to 1 files - exporting bookmark master - warning: verify does not actually check anything in this repo - pushing rev 34c2bf6b0626 to destination test-1 bookmark master - searching for changes - adding changesets - adding manifests - adding file changes - added 2 changesets with 2 changes to 1 files - exporting bookmark master - warning: verify does not actually check anything in this repo - pushing rev e38ba6f5b7e0 to destination test-2 bookmark master - searching for changes - adding changesets - adding manifests - adding file changes - added 3 changesets with 3 changes to 1 files - exporting bookmark master - warning: verify does not actually check anything in this repo - pushing rev eebf5a27f8ca to destination test-3 bookmark master - searching for changes - adding changesets - adding manifests - adding file changes - added 4 changesets with 4 changes to 1 files - exporting bookmark master - warning: verify does not actually check anything in this repo - pushing rev 095197eb4973 to destination test-4 bookmark master - searching for changes - adding changesets - adding manifests - adding file changes - added 2 changesets with 2 changes to 1 files - exporting bookmark master - warning: verify does not actually check anything in this repo - pushing rev 1bb50a9436a7 to destination test-5 bookmark master - searching for changes - adding changesets - adding manifests - adding file changes - added 3 changesets with 3 changes to 1 files - exporting bookmark master - warning: verify does not actually check anything in this repo - pushing rev 7373c1169842 to destination test-6 bookmark master - searching for changes - adding changesets - adding manifests - adding file changes - added 4 changesets with 5 changes to 2 files - exporting bookmark master - warning: verify does not actually check anything in this repo - pushing rev a6a34bfa0076 to destination test-7 bookmark master - searching for changes - adding changesets - adding manifests - adding file changes - added 5 changesets with 6 changes to 3 files - exporting bookmark master - warning: verify does not actually check anything in this repo - pushing rev aa35859c02ea to destination test-8 bookmark master - searching for changes - adding changesets - adding manifests - adding file changes - added 5 changesets with 5 changes to 2 files - exporting bookmark master - warning: verify does not actually check anything in this repo - $ cd test-8 - $ hg pull ../test-7 - pulling from ../test-7 - searching for changes - adding changesets - adding manifests - adding file changes - added 4 changesets with 2 changes to 3 files - $ hg verify - warning: verify does not actually check anything in this repo diff --git a/eden/scm/tests/test-hggit-push.t b/eden/scm/tests/test-hggit-push.t deleted file mode 100644 index 02ae30c99e..0000000000 --- a/eden/scm/tests/test-hggit-push.t +++ /dev/null @@ -1,196 +0,0 @@ -Load commonly used test logic - $ . "$TESTDIR/hggit/testutil" - - $ git init -q gitrepo - $ cd gitrepo - $ echo alpha > alpha - $ git add alpha - $ fn_git_commit -m "add alpha" - $ git checkout -b not-master - Switched to a new branch 'not-master' - - $ cd .. - $ hg clone gitrepo hgrepo | grep -v '^updating' - importing git objects into hg - 1 files updated, 0 files merged, 0 files removed, 0 files unresolved - - $ cd hgrepo - $ hg bookmark -q master - $ echo beta > beta - $ hg add beta - $ fn_hg_commit -m 'add beta' - - - $ echo gamma > gamma - $ hg add gamma - $ fn_hg_commit -m 'add gamma' - - $ hg book -r 574e2d660a7d7bbaf97251f694c8c8327f0db957 beta - $ hg push -r beta - pushing to $TESTTMP/gitrepo - searching for changes - adding objects - added 1 commits with 1 trees and 1 blobs - adding reference refs/heads/beta - - $ cd .. - -should have two different branches - $ cd gitrepo - $ git branch -v - beta 0f378ab add beta - master 7eeab2e add alpha - * not-master 7eeab2e add alpha - -some more work on master from git - $ git checkout master - Switched to branch 'master' - $ echo delta > delta - $ git add delta - $ fn_git_commit -m "add delta" - $ git checkout not-master - Switched to branch 'not-master' - - $ cd .. - - $ cd hgrepo -this should fail - $ hg push -r master - pushing to $TESTTMP/gitrepo - searching for changes - abort: branch 'refs/heads/master' changed on the server, please pull and merge before pushing - [255] - -... even with -f - $ hg push -fr master - pushing to $TESTTMP/gitrepo - searching for changes - abort: branch 'refs/heads/master' changed on the server, please pull and merge before pushing - [255] - - $ hg pull 2>&1 | grep -v 'divergent bookmark' - pulling from $TESTTMP/gitrepo - importing git objects into hg - -this should also fail - $ hg push -r master - pushing to $TESTTMP/gitrepo - searching for changes - abort: pushing refs/heads/master overwrites 49480a0fbf45 - [255] - -... but succeed with -f - $ hg push -fr master - pushing to $TESTTMP/gitrepo - searching for changes - adding objects - added 1 commits with 1 trees and 1 blobs - updating reference refs/heads/master - -this should fail, no changes to push - $ hg push -r master - pushing to $TESTTMP/gitrepo - searching for changes - no changes found - [1] - -hg-git issue103 -- directories can lose information at hg-git export time - - $ hg up master | egrep -v '^\(activating bookmark master\)$' - 0 files updated, 0 files merged, 0 files removed, 0 files unresolved - $ mkdir dir1 - $ echo alpha > dir1/alpha - $ hg add dir1/alpha - $ fn_hg_commit -m 'add dir1/alpha' - $ hg push -r master - pushing to $TESTTMP/gitrepo - searching for changes - adding objects - added 1 commits with 2 trees and 0 blobs - updating reference refs/heads/master - - $ echo beta > dir1/beta - $ hg add dir1/beta - $ fn_hg_commit -m 'add dir1/beta' - $ hg push -r master - pushing to $TESTTMP/gitrepo - searching for changes - adding objects - added 1 commits with 2 trees and 0 blobs - updating reference refs/heads/master - $ hg log -r master - commit: * (glob) - bookmark: master - user: test - date: Mon Jan 01 00:00:15 2007 +0000 - summary: add dir1/beta - - - $ cd .. - - $ hg clone gitrepo hgrepo-test - importing git objects into hg - updating to branch default - 5 files updated, 0 files merged, 0 files removed, 0 files unresolved - $ hg -R hgrepo-test log -r master - commit: * (glob) - bookmark: master - user: test - date: Mon Jan 01 00:00:15 2007 +0000 - summary: add dir1/beta - - -Push empty Hg repo to empty Git repo (issue #58) - $ hg init hgrepo2 - $ git init -q --bare gitrepo2 - $ hg -R hgrepo2 push gitrepo2 - pushing to gitrepo2 - searching for changes - no changes found - [1] - -The remote repo is empty and the local one doesn't have any bookmarks/tags - $ cd hgrepo2 - $ echo init >> test.txt - $ hg addremove - adding test.txt - $ fn_hg_commit -m init - $ hg update null - 0 files updated, 0 files merged, 1 files removed, 0 files unresolved - $ hg push ../gitrepo2 - pushing to ../gitrepo2 - searching for changes - adding objects - added 1 commits with 1 trees and 1 blobs -(the phases line was added in Mercurial 3.5) - $ hg summary | grep -Ev '^phases:' - parent: 000000000000 (no revision checked out) - commit: (clean) -Only one bookmark 'master' should be created - $ hg bookmarks - * master 8aded40be5af - -test for ssh vulnerability - - $ cat >> $HGRCPATH << EOF - > [ui] - > ssh = ssh -o ConnectTimeout=1 - > EOF - $ hg push 'git+ssh://-oProxyCommand=rm${IFS}nonexistent/path' 2>&1 >/dev/null - pushing to git+ssh://-oProxyCommand%3Drm%24%7BIFS%7Dnonexistent/path - abort: potentially unsafe hostname: '-oProxyCommand=rm${IFS}nonexistent' - [255] - $ hg push 'git+ssh://-oProxyCommand=rm%20nonexistent/path' 2>&1 >/dev/null - pushing to git+ssh://-oProxyCommand%3Drm%20nonexistent/path - abort: potentially unsafe hostname: '-oProxyCommand=rm nonexistent' - [255] - $ hg push 'git+ssh://fakehost|rm%20nonexistent/path' 2>&1 >/dev/null - pushing to git+ssh://fakehost%7Crm%20nonexistent/path - ssh: .* fakehost%7[Cc]rm%20nonexistent.* (re) - abort: git remote error: The remote server unexpectedly closed the connection. - [255] - $ hg push 'git+ssh://fakehost%7Crm%20nonexistent/path' 2>&1 >/dev/null - pushing to git+ssh://fakehost%7Crm%20nonexistent/path - ssh: .* fakehost%7[Cc]rm%20nonexistent.* (re) - abort: git remote error: The remote server unexpectedly closed the connection. - [255] diff --git a/eden/scm/tests/test-hggit-renames.t b/eden/scm/tests/test-hggit-renames.t deleted file mode 100644 index 1952fa9e21..0000000000 --- a/eden/scm/tests/test-hggit-renames.t +++ /dev/null @@ -1,561 +0,0 @@ -Test that rename detection works - $ . "$TESTDIR/hggit/testutil" - - $ cat >> $HGRCPATH < [diff] - > git = True - > [git] - > similarity = 50 - > EOF - - $ git init -q gitrepo - $ cd gitrepo - $ for i in 1 2 3 4 5 6 7 8 9 10; do echo $i >> alpha; done - $ git add alpha - $ fn_git_commit -malpha - -Rename a file - $ git mv alpha beta - $ echo 11 >> beta - $ git add beta - $ fn_git_commit -mbeta - -Copy a file - $ cp beta gamma - $ echo 12 >> beta - $ echo 13 >> gamma - $ git add beta gamma - $ fn_git_commit -mgamma - -Add a submodule (gitlink) and move it to a different spot: - $ cd .. - $ git init -q gitsubmodule - $ cd gitsubmodule - $ touch subalpha - $ git add subalpha - $ fn_git_commit -msubalpha - $ cd ../gitrepo - - $ git submodule add ../gitsubmodule - Cloning into * (glob) - done. - $ fn_git_commit -m 'add submodule' - $ sed -e 's/path = gitsubmodule/path = gitsubmodule2/' .gitmodules > .gitmodules-new - $ mv .gitmodules-new .gitmodules - $ mv gitsubmodule gitsubmodule2 - -Previous versions of git did not produce any output but 2.14 changed the output -to warn the user about submodules - - $ git add .gitmodules gitsubmodule2 2>/dev/null - $ git rm --cached gitsubmodule - rm 'gitsubmodule' - $ fn_git_commit -m 'move submodule' - -Rename a file elsewhere and replace it with a symlink: - - $ git mv beta beta-new - $ ln -s beta-new beta - $ git add beta - $ fn_git_commit -m 'beta renamed' - -Rename the file back: - - $ git rm beta - rm 'beta' - $ git mv beta-new beta - $ fn_git_commit -m 'beta renamed back' - -Rename a file elsewhere and replace it with a submodule: - - $ git mv gamma gamma-new - $ git submodule add ../gitsubmodule gamma 2>&1 - Cloning into * (glob) - done. - $ fn_git_commit -m 'rename and add submodule' - -Remove the submodule and rename the file back: - - $ grep 'submodule "gitsubmodule"' -A2 .gitmodules > .gitmodules-new - $ mv .gitmodules-new .gitmodules - $ git add .gitmodules - $ git rm --cached gamma - rm 'gamma' - $ rm -rf gamma - $ git mv gamma-new gamma - $ fn_git_commit -m 'remove submodule and rename back' - - $ git checkout -f -b not-master 2>&1 - Switched to a new branch 'not-master' - - $ cd .. - $ hg clone -q gitrepo hgrepo - $ cd hgrepo - $ hg book master -q - $ hg log -p --graph --template "{node} {desc|firstline}\n{join(extras, ' ')}\n\n" - @ 144790f182a8d92e4134a20b0f8698854a9638b1 remove submodule and rename back - │ branch=default convert_revision=50d116676a308b7c22935137d944e725d2296f2a hg-git-rename-source=git - │ - │ diff --git a/.gitmodules b/.gitmodules - │ --- a/.gitmodules - │ +++ b/.gitmodules - │ @@ -1,6 +1,3 @@ - │ [submodule "gitsubmodule"] - │ path = gitsubmodule2 - │ url = ../gitsubmodule - │ -[submodule "gamma"] - │ - path = gamma - │ - url = ../gitsubmodule - │ diff --git a/gamma-new b/gamma - │ rename from gamma-new - │ rename to gamma - │ - o f49a0c6fd69faeac5e247b5b37b8e7ce1b443e04 rename and add submodule - │ branch=default convert_revision=59fb8e82ea18f79eab99196f588e8948089c134f hg-git-rename-source=git - │ - │ diff --git a/.gitmodules b/.gitmodules - │ --- a/.gitmodules - │ +++ b/.gitmodules - │ @@ -1,3 +1,6 @@ - │ [submodule "gitsubmodule"] - │ path = gitsubmodule2 - │ url = ../gitsubmodule - │ +[submodule "gamma"] - │ + path = gamma - │ + url = ../gitsubmodule - │ diff --git a/gamma b/gamma-new - │ rename from gamma - │ rename to gamma-new - │ - o 2d38f1131e0beb3b73451640bb27e0df3cf3684e beta renamed back - │ branch=default convert_revision=f95497455dfa891b4cd9b524007eb9514c3ab654 hg-git-rename-source=git - │ - │ diff --git a/beta b/beta - │ old mode 120000 - │ new mode 100644 - │ --- a/beta - │ +++ b/beta - │ @@ -1,1 +1,12 @@ - │ -beta-new - │ \ No newline at end of file - │ +1 - │ +2 - │ +3 - │ +4 - │ +5 - │ +6 - │ +7 - │ +8 - │ +9 - │ +10 - │ +11 - │ +12 - │ diff --git a/beta-new b/beta-new - │ deleted file mode 100644 - │ --- a/beta-new - │ +++ /dev/null - │ @@ -1,12 +0,0 @@ - │ -1 - │ -2 - │ -3 - │ -4 - │ -5 - │ -6 - │ -7 - │ -8 - │ -9 - │ -10 - │ -11 - │ -12 - │ - o 024a72621ccff3ace020e03019c323d49c718be8 beta renamed - │ branch=default convert_revision=055f482277da6cd3dd37c7093d06983bad68f782 hg-git-rename-source=git - │ - │ diff --git a/beta b/beta - │ old mode 100644 - │ new mode 120000 - │ --- a/beta - │ +++ b/beta - │ @@ -1,12 +1,1 @@ - │ -1 - │ -2 - │ -3 - │ -4 - │ -5 - │ -6 - │ -7 - │ -8 - │ -9 - │ -10 - │ -11 - │ -12 - │ +beta-new - │ \ No newline at end of file - │ diff --git a/beta b/beta-new - │ copy from beta - │ copy to beta-new - │ - o b48620502e8b403e9d92f8ff353ee139e4e22bf8 move submodule - │ branch=default convert_revision=d7f31298f27df8a9226eddb1e4feb96922c46fa5 hg-git-rename-source=git - │ - │ diff --git a/.gitmodules b/.gitmodules - │ --- a/.gitmodules - │ +++ b/.gitmodules - │ @@ -1,3 +1,3 @@ - │ [submodule "gitsubmodule"] - │ - path = gitsubmodule - │ + path = gitsubmodule2 - │ url = ../gitsubmodule - │ - o ea94d2142cbfdaceacb94bedfe29add896c49e47 add submodule - │ branch=default convert_revision=c610256cb6959852d9e70d01902a06726317affc hg-git-rename-source=git - │ - │ diff --git a/.gitmodules b/.gitmodules - │ new file mode 100644 - │ --- /dev/null - │ +++ b/.gitmodules - │ @@ -0,0 +1,3 @@ - │ +[submodule "gitsubmodule"] - │ + path = gitsubmodule - │ + url = ../gitsubmodule - │ - o e3e6b2083b5cc4382f611b16d23df93a40a19a00 gamma - │ branch=default convert_revision=e1348449e0c3a417b086ed60fc13f068d4aa8b26 hg-git-rename-source=git - │ - │ diff --git a/beta b/beta - │ --- a/beta - │ +++ b/beta - │ @@ -9,3 +9,4 @@ - │ 9 - │ 10 - │ 11 - │ +12 - │ diff --git a/beta b/gamma - │ copy from beta - │ copy to gamma - │ --- a/beta - │ +++ b/gamma - │ @@ -9,3 +9,4 @@ - │ 9 - │ 10 - │ 11 - │ +13 - │ - o 80be639891f44172f321d555badcbc3f9d11fa87 beta - │ branch=default convert_revision=cc83241f39927232f690d370894960b0d1943a0e hg-git-rename-source=git - │ - │ diff --git a/alpha b/beta - │ rename from alpha - │ rename to beta - │ --- a/alpha - │ +++ b/beta - │ @@ -8,3 +8,4 @@ - │ 8 - │ 9 - │ 10 - │ +11 - │ - o ff861f77355d7a6aba082ff95f2bc716cf192980 alpha - branch=default convert_revision=938bb65bb322eb4a3558bec4cdc8a680c4d1794c hg-git-rename-source=git - - diff --git a/alpha b/alpha - new file mode 100644 - --- /dev/null - +++ b/alpha - @@ -0,0 +1,10 @@ - +1 - +2 - +3 - +4 - +5 - +6 - +7 - +8 - +9 - +10 - - -Make a new ordinary commit in Mercurial (no extra metadata) - $ echo 14 >> gamma - $ hg ci -m "gamma2" - -Make a new commit with a copy and a rename in Mercurial - $ hg cp gamma delta - $ echo 15 >> delta - $ hg mv beta epsilon - $ echo 16 >> epsilon - $ hg ci -m "delta/epsilon" - $ hg export . - # HG changeset patch - # User test - # Date 0 0 - # Thu Jan 01 00:00:00 1970 +0000 - # Node ID c84c4d95bbe6f146c5193dcf348fee3bb2bfb186 - # Parent edad41eac39c7332b5981d564157cc59a46759a9 - delta/epsilon - - diff --git a/gamma b/delta - copy from gamma - copy to delta - --- a/gamma - +++ b/delta - @@ -11,3 +11,4 @@ - 11 - 13 - 14 - +15 - diff --git a/beta b/epsilon - rename from beta - rename to epsilon - --- a/beta - +++ b/epsilon - @@ -10,3 +10,4 @@ - 10 - 11 - 12 - +16 - $ hg push - pushing to $TESTTMP/gitrepo - searching for changes - adding objects - added 2 commits with 2 trees and 3 blobs - updating reference refs/heads/master - - $ cd ../gitrepo - $ git log master --pretty=oneline - 5f2948d029693346043f320620af99a615930dc4 delta/epsilon - bbd2ec050f7fbc64f772009844f7d58a556ec036 gamma2 - 50d116676a308b7c22935137d944e725d2296f2a remove submodule and rename back - 59fb8e82ea18f79eab99196f588e8948089c134f rename and add submodule - f95497455dfa891b4cd9b524007eb9514c3ab654 beta renamed back - 055f482277da6cd3dd37c7093d06983bad68f782 beta renamed - d7f31298f27df8a9226eddb1e4feb96922c46fa5 move submodule - c610256cb6959852d9e70d01902a06726317affc add submodule - e1348449e0c3a417b086ed60fc13f068d4aa8b26 gamma - cc83241f39927232f690d370894960b0d1943a0e beta - 938bb65bb322eb4a3558bec4cdc8a680c4d1794c alpha - -Make sure the right metadata is stored - $ git cat-file commit "master^" - tree 0adbde18545845f3b42ad1a18939ed60a9dec7a8 - parent 50d116676a308b7c22935137d944e725d2296f2a - author test 0 +0000 - committer test 0 +0000 - HG:rename-source hg - - gamma2 - $ git cat-file commit master - tree f8f32f4e20b56a5a74582c6a5952c175bf9ec155 - parent bbd2ec050f7fbc64f772009844f7d58a556ec036 - author test 0 +0000 - committer test 0 +0000 - HG:rename gamma:delta - HG:rename beta:epsilon - - delta/epsilon - -Now make another clone and compare the hashes - - $ cd .. - $ hg clone -q gitrepo hgrepo2 - $ cd hgrepo2 - $ hg book master -qf - $ hg export master - # HG changeset patch - # User test - # Date 0 0 - # Thu Jan 01 00:00:00 1970 +0000 - # Node ID 8623d5155b015112f9ea55e0520fef982e4b488a - # Parent ae4f6d98d5bce684ec6ac796b8fd3319293b4264 - delta/epsilon - - diff --git a/gamma b/delta - copy from gamma - copy to delta - --- a/gamma - +++ b/delta - @@ -11,3 +11,4 @@ - 11 - 13 - 14 - +15 - diff --git a/beta b/epsilon - rename from beta - rename to epsilon - --- a/beta - +++ b/epsilon - @@ -10,3 +10,4 @@ - 10 - 11 - 12 - +16 - -Regenerate the Git metadata and compare the hashes - $ hg gclear - clearing out the git cache data - $ hg gexport - $ cd .hg/git - $ git log master --pretty=oneline - a8febfd5b0396340f953924ea982b4a86a26bed3 delta/epsilon - dbda9582869f680cccbaebc680edd627a8fbc000 gamma2 - 15a10a2040f8f50b2d0f4f97bbffd6f05da07675 remove submodule and rename back - 6dbd4a46e0da12500768f6963313d35fd19b8191 rename and add submodule - c2d6447a571e55aba88ed437051c81724500434d beta renamed back - 0ea26deff913d7e9701bed3726ebf4686d9cf0cc beta renamed - 8327069bf38e4ce8e8cf776a6d68fa151441916b move submodule - a49063ec760fa65a5aaf47f298a13222a0e3874d add submodule - 00d2f34d2f9e2230ed49343b2b3eb14637b16c2e gamma - e3ddc25bf9b3a6a00e4379673ee2d9d6bbef720e beta - 8557a753ca442f07736d74570a9cfebde4bf02e9 alpha - -Test findcopiesharder - - $ cd $TESTTMP - $ git init -q gitcopyharder - $ cd gitcopyharder - $ cat >> file0 << EOF - > 1 - > 2 - > 3 - > 4 - > 5 - > EOF - $ git add file0 - $ fn_git_commit -m file0 - $ cp file0 file1 - $ git add file1 - $ fn_git_commit -m file1 - $ cp file0 file2 - $ echo 6 >> file2 - $ git add file2 - $ fn_git_commit -m file2 - - $ cd .. - -Clone without findcopiesharder does not find copies from unmodified files - - $ hg clone gitcopyharder hgnocopyharder - importing git objects into hg - updating to branch default - 3 files updated, 0 files merged, 0 files removed, 0 files unresolved - $ hg -R hgnocopyharder export 'desc(file1)'::'desc(file2)' - # HG changeset patch - # User test - # Date 1167609621 0 - # Mon Jan 01 00:00:21 2007 +0000 - # Node ID 2e1fd38583278f0b6ede71d0f913f02ff3e14a36 - # Parent 3557dd9e8accc08148642bb4d8b2a4028e85f1f9 - file1 - - diff --git a/file1 b/file1 - new file mode 100644 - --- /dev/null - +++ b/file1 - @@ -0,0 +1,5 @@ - +1 - +2 - +3 - +4 - +5 - # HG changeset patch - # User test - # Date 1167609622 0 - # Mon Jan 01 00:00:22 2007 +0000 - # Node ID 6b935af41daea1bf80d299ea139fab32c937e2b0 - # Parent 2e1fd38583278f0b6ede71d0f913f02ff3e14a36 - file2 - - diff --git a/file2 b/file2 - new file mode 100644 - --- /dev/null - +++ b/file2 - @@ -0,0 +1,6 @@ - +1 - +2 - +3 - +4 - +5 - +6 - -findcopiesharder finds copies from unmodified files if similarity is met - - $ hg --config git.findcopiesharder=true clone gitcopyharder hgcopyharder0 - importing git objects into hg - updating to branch default - 3 files updated, 0 files merged, 0 files removed, 0 files unresolved - $ hg -R hgcopyharder0 export 'desc(file1)'::'desc(file2)' - # HG changeset patch - # User test - # Date 1167609621 0 - # Mon Jan 01 00:00:21 2007 +0000 - # Node ID 822f61b91c7d74a67114314c5f6b078d9de4f3ac - # Parent 3557dd9e8accc08148642bb4d8b2a4028e85f1f9 - file1 - - diff --git a/file0 b/file1 - copy from file0 - copy to file1 - # HG changeset patch - # User test - # Date 1167609622 0 - # Mon Jan 01 00:00:22 2007 +0000 - # Node ID 6827e4ffec1b7f3e8b0e96a995adcc5fce4f8e8b - # Parent 822f61b91c7d74a67114314c5f6b078d9de4f3ac - file2 - - diff --git a/file0 b/file2 - copy from file0 - copy to file2 - --- a/file0 - +++ b/file2 - @@ -3,3 +3,4 @@ - 3 - 4 - 5 - +6 - - $ hg --config git.findcopiesharder=true --config git.similarity=95 clone gitcopyharder hgcopyharder1 - importing git objects into hg - updating to branch default - 3 files updated, 0 files merged, 0 files removed, 0 files unresolved - $ hg -R hgcopyharder1 export 'desc(file1)'::'desc(file2)' - # HG changeset patch - # User test - # Date 1167609621 0 - # Mon Jan 01 00:00:21 2007 +0000 - # Node ID 822f61b91c7d74a67114314c5f6b078d9de4f3ac - # Parent 3557dd9e8accc08148642bb4d8b2a4028e85f1f9 - file1 - - diff --git a/file0 b/file1 - copy from file0 - copy to file1 - # HG changeset patch - # User test - # Date 1167609622 0 - # Mon Jan 01 00:00:22 2007 +0000 - # Node ID 481884f836b7ce63906ad6875ac53b5bc5df134c - # Parent 822f61b91c7d74a67114314c5f6b078d9de4f3ac - file2 - - diff --git a/file2 b/file2 - new file mode 100644 - --- /dev/null - +++ b/file2 - @@ -0,0 +1,6 @@ - +1 - +2 - +3 - +4 - +5 - +6 - -Config values out of range - $ hg --config git.similarity=999 clone gitcopyharder hgcopyharder2 - importing git objects into hg - abort: git.similarity must be between 0 and 100 - [255] - $ hg --config git.renamelimit=-5 clone gitcopyharder hgcopyharder2 - importing git objects into hg - abort: git.renamelimit must be non-negative - [255] diff --git a/eden/scm/tests/test-hggit-timezone.t b/eden/scm/tests/test-hggit-timezone.t deleted file mode 100644 index 78f3e35c93..0000000000 --- a/eden/scm/tests/test-hggit-timezone.t +++ /dev/null @@ -1,32 +0,0 @@ -This test shows how dulwich fails to convert a commit accepted by hg. - -In the real world case, it was a hand edit by the user to change the -timezone field in an export. However, if it is good enough for hg, we -have to make it good enough for git. - -Load commonly used test logic - $ . "$TESTDIR/hggit/testutil" - - $ hg init hgrepo - $ cd hgrepo - $ touch beta - $ hg add beta - $ fn_hg_commit -m "test commit" - $ cat >patch2 < # HG changeset patch - > # User J. User - > # Date 1337962044 25201 - > # Node ID 1111111111111111111111111111111111111111 - > # Parent 0000000000000000000000000000000000000000 - > - > Patch with sub-minute time zone - > diff --git a/alpha b/alpha - > new file mode 100644 - > --- /dev/null - > +++ b/alpha - > @@ -0,0 +1,1 @@ - > +alpha - > EOF - $ hg import patch2 - applying patch2 - $ hg gexport diff --git a/eden/scm/tests/test-hggit-tree-decomposition.t b/eden/scm/tests/test-hggit-tree-decomposition.t deleted file mode 100644 index bc10e74cb4..0000000000 --- a/eden/scm/tests/test-hggit-tree-decomposition.t +++ /dev/null @@ -1,63 +0,0 @@ -Load commonly used test logic - $ . "$TESTDIR/hggit/testutil" - - $ git init -q gitrepo - $ cd gitrepo - $ mkdir d1 - $ echo a > d1/f1 - $ echo b > d1/f2 - $ git add d1/f1 d1/f2 - $ fn_git_commit -m initial - - $ mkdir d2 - $ git mv d1/f2 d2/f2 - $ fn_git_commit -m 'rename' - - $ rm -r d1 - $ echo c > d1 - $ git add --all d1 - $ fn_git_commit -m 'replace a dir with a file' - - - $ cd .. - $ git init -q --bare gitrepo2 - - $ hg clone gitrepo hgrepo | grep -v '^updating' - importing git objects into hg - 2 files updated, 0 files merged, 0 files removed, 0 files unresolved - $ cd hgrepo - $ hg log --template 'adds: {file_adds}\ndels: {file_dels}\n' - adds: d1 - dels: d1/f1 - adds: d2/f2 - dels: d1/f2 - adds: d1/f1 d1/f2 - dels: - - $ hg gclear - clearing out the git cache data - $ hg push ../gitrepo2 - pushing to ../gitrepo2 - searching for changes - adding objects - added 3 commits with 6 trees and 3 blobs - $ cd .. - - $ git --git-dir=gitrepo2 log --pretty=medium - commit d16fb6b69bb183a673483b4d239c3ecd1c5476ec - Author: test - Date: Mon Jan 1 00:00:12 2007 +0000 - - replace a dir with a file - - commit 5b24ce288cfde71c483834f3b2b62aa5bcb05a43 - Author: test - Date: Mon Jan 1 00:00:11 2007 +0000 - - rename - - commit 9f99e4bc96145e874b20c616cd8824b6e74f9fc7 - Author: test - Date: Mon Jan 1 00:00:10 2007 +0000 - - initial diff --git a/eden/scm/tests/test-hggit-updatemeta.t b/eden/scm/tests/test-hggit-updatemeta.t deleted file mode 100644 index fb555ffa58..0000000000 --- a/eden/scm/tests/test-hggit-updatemeta.t +++ /dev/null @@ -1,65 +0,0 @@ - $ disable treemanifest - $ . "$TESTDIR/hggit/testutil" - - $ git init -q gitrepo - $ cd gitrepo - $ touch a - $ git add a - $ fn_git_commit -m a - $ echo >> a - $ fn_git_commit -am a2 - $ git log --oneline - 9da56a5 a2 - ad4fd0d a - - $ cd .. - $ hg clone -q gitrepo hgrepo - $ cd hgrepo - $ hg log -G -T '{extras % "{extra}\n"}' - @ branch=default - │ convert_revision=9da56a563fafade1a5b50ae0c01292f91cd4ce34 - │ hg-git-rename-source=git - o branch=default - convert_revision=ad4fd0de4cb839a7d2d1c2497f8a2c230a2726e9 - hg-git-rename-source=git - - $ cd .. - $ hg clone -q hgrepo hgrepo2 - -Generate git-mapfile for a fresh repo - $ cd hgrepo2 - $ test -f .hg/git-mapfile - [1] - $ hg git-updatemeta - $ cat .hg/git-mapfile | sort - 9da56a563fafade1a5b50ae0c01292f91cd4ce34 f008e266042afb83012cda1e2cd65d108a51068f - ad4fd0de4cb839a7d2d1c2497f8a2c230a2726e9 5b699970cd13b5f95f6af5f32781d80cfa2e813b - -Add a new commit to git - $ cd ../gitrepo - $ echo >> a - $ fn_git_commit -am a3 - $ git log --oneline -n 1 - 1fc117f a3 - $ cd ../hgrepo - $ hg pull -q - -Update git-mapfile for a repo - $ cd ../hgrepo2 - $ hg pull -q - $ hg git-updatemeta - $ cat .hg/git-mapfile | sort - 1fc117f64bf9ee3ae9b76e00d9cead51bce91e97 82e8585c3e4aa0dc511fc1c38c7382e4c728e58c - 9da56a563fafade1a5b50ae0c01292f91cd4ce34 f008e266042afb83012cda1e2cd65d108a51068f - ad4fd0de4cb839a7d2d1c2497f8a2c230a2726e9 5b699970cd13b5f95f6af5f32781d80cfa2e813b - -# Create a new commit, verify that git-updatemeta does not crash even though it -# does not have commit extras. - $ cd ../hgrepo2 - $ touch c - $ hg ci -Aqm c - $ hg git-updatemeta - $ cat .hg/git-mapfile | sort - 1fc117f64bf9ee3ae9b76e00d9cead51bce91e97 82e8585c3e4aa0dc511fc1c38c7382e4c728e58c - 9da56a563fafade1a5b50ae0c01292f91cd4ce34 f008e266042afb83012cda1e2cd65d108a51068f - ad4fd0de4cb839a7d2d1c2497f8a2c230a2726e9 5b699970cd13b5f95f6af5f32781d80cfa2e813b diff --git a/eden/scm/tests/test-hggit-url-parsing.py b/eden/scm/tests/test-hggit-url-parsing.py deleted file mode 100644 index 03a0131ac4..0000000000 --- a/eden/scm/tests/test-hggit-url-parsing.py +++ /dev/null @@ -1,111 +0,0 @@ -from __future__ import absolute_import - -import shutil -import sys -import tempfile - -from edenscm.mercurial import commands, hg, ui -from hghave import require - - -try: - from edenscm.hgext.hggit.git_handler import GitHandler -except ImportError: - print("skipped: missing feature: dulwich") - sys.exit(80) - - -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 assertEqual(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.assertEqual(path, "/webjam/webjam.git") - self.assertEqual(client.host, "git@github.com") - - def test_ssh_github_style_colon_number_starting_username(self): - url = "git+ssh://git@github.com:42qu/vps.git" - client, path = self.handler.get_transport_and_path(url) - self.assertEqual(path, "42qu/vps.git") - self.assertEqual(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.assertEqual(path, "webjam/webjam.git") - self.assertEqual(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.assertEqual(path, "webjam.git") - self.assertEqual(client.host, "git@heroku.com") - # also test that it works even if heroku isn't in the name - url = "git+ssh://git@compatible.com:webjam.git" - client, path = self.handler.get_transport_and_path(url) - self.assertEqual(path, "webjam.git") - self.assertEqual(client.host, "git@compatible.com") - - def test_ssh_heroku_style_with_trailing_slash(self): - # some versions of mercurial add a trailing slash even if - # the user didn't supply one. - url = "git+ssh://git@heroku.com:webjam.git/" - client, path = self.handler.get_transport_and_path(url) - self.assertEqual(path, "webjam.git") - self.assertEqual(client.host, "git@heroku.com") - - def test_heroku_style_with_port(self): - url = "git+ssh://git@heroku.com:999:webjam.git" - client, path = self.handler.get_transport_and_path(url) - self.assertEqual(path, "webjam.git") - self.assertEqual(client.host, "git@heroku.com") - self.assertEqual(client.port, "999") - - def test_gitdaemon_style(self): - url = "git://github.com/webjam/webjam.git" - client, path = self.handler.get_transport_and_path(url) - self.assertEqual(path, "/webjam/webjam.git") - try: - self.assertEqual(client._host, "github.com") - except AttributeError: - self.assertEqual(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.assertEqual(path, "/webjam/webjam.git") - self.assertEqual(client.host, "git@github.com") - self.assertEqual(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.assertEqual(path, "/webjam/webjam.git") - try: - self.assertEqual(client._host, "github.com") - except AttributeError: - self.assertEqual(client.host, "github.com") - self.assertEqual(client._port, "19418") - - -if __name__ == "__main__": - tc = TestUrlParsing() - for test in sorted([t for t in dir(tc) if t.startswith("test_")]): - tc.setUp() - getattr(tc, test)() - tc.tearDown() diff --git a/eden/scm/tests/test-hggit-url-parsing.py.out b/eden/scm/tests/test-hggit-url-parsing.py.out deleted file mode 100644 index fd3039e0e8..0000000000 --- a/eden/scm/tests/test-hggit-url-parsing.py.out +++ /dev/null @@ -1,46 +0,0 @@ -% expect '/webjam/webjam.git' -/webjam/webjam.git -% expect 'github.com' -github.com -% expect '/webjam/webjam.git' -/webjam/webjam.git -% expect 'github.com' -github.com -% expect '19418' -19418 -% expect 'webjam.git' -webjam.git -% expect 'git@heroku.com' -git@heroku.com -% expect '999' -999 -% expect 'webjam/webjam.git' -webjam/webjam.git -% expect 'git@github.com' -git@github.com -% expect '42qu/vps.git' -42qu/vps.git -% expect 'git@github.com' -git@github.com -% 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 '10022' -10022 -% expect 'webjam.git' -webjam.git -% expect 'git@heroku.com' -git@heroku.com -% expect 'webjam.git' -webjam.git -% expect 'git@compatible.com' -git@compatible.com -% expect 'webjam.git' -webjam.git -% expect 'git@heroku.com' -git@heroku.com diff --git a/eden/scm/tests/test-hggit-verify-fail.t b/eden/scm/tests/test-hggit-verify-fail.t deleted file mode 100644 index 85bfe3eab6..0000000000 --- a/eden/scm/tests/test-hggit-verify-fail.t +++ /dev/null @@ -1,64 +0,0 @@ -Other tests make sure that gverify passes. This makes sure that gverify detects -inconsistencies. Since hg-git is ostensibly correct, we artificially create -inconsistencies by placing different Mercurial and Git repos in the right spots. - - $ . "$TESTDIR/hggit/testutil" - $ git init -q gitrepo - $ cd gitrepo - $ echo normalf > normalf - $ echo missingf > missingf - $ echo differentf > differentf -(executable in git, non-executable in hg) - $ echo exef > exef - $ chmod +x exef -(symlink in hg, regular file in git) -equivalent to 'echo -n foo > linkf', but that doesn't work on OS X - $ printf foo > linkf - $ git add normalf missingf differentf exef linkf - $ fn_git_commit -m 'add files' - $ cd .. - - $ hg init hgrepo - $ cd hgrepo - $ echo normalf > normalf - $ echo differentf2 > differentf - $ echo unexpectedf > unexpectedf - $ echo exef > exef - $ ln -s foo linkf - $ hg add normalf differentf unexpectedf exef linkf - $ fn_hg_commit -m 'add files' - $ git clone --mirror ../gitrepo .hg/git - Cloning into bare repository '.hg/git'... - done. - $ echo "`cd ../gitrepo && git rev-parse HEAD` `hg log -r . --template '{node}'`" >> .hg/git-mapfile - $ hg gverify - verifying rev 3f1601c3cf54 against git commit 039c1cd9fdda382c9d1e8ec85de6b5b59518ca80 - difference in: differentf - file has different flags: exef (hg '', git 'x') - file has different flags: linkf (hg 'l', git '') - file found in git but not hg: missingf - file found in hg but not git: unexpectedf - [1] - - $ echo newf > newf - $ hg add newf - $ fn_hg_commit -m 'new hg commit' - $ hg gverify - abort: no git commit found for rev 4e582b4eb862 - (if this is an octopus merge, verify against the last rev) - [255] - -invalid git SHA - $ echo "ffffffffffffffffffffffffffffffffffffffff `hg log -r . --template '{node}'`" >> .hg/git-mapfile - $ hg gverify - abort: git equivalent ffffffffffffffffffffffffffffffffffffffff for rev 4e582b4eb862 not found! - [255] - -git SHA is not a commit - $ echo new2 >> newf - $ fn_hg_commit -m 'new hg commit 2' -this gets the tree pointed to by the commit at HEAD - $ echo "`cd ../gitrepo && git show --format=%T HEAD | head -n 1` `hg log -r . --template '{node}'`" >> .hg/git-mapfile - $ hg gverify - abort: git equivalent f477b00e4a9907617f346a529cc0fe9ba5d6f6d3 for rev 5c2eb98af3e2 is not a commit! - [255]