GithubHelp home page GithubHelp logo

frej / fast-export Goto Github PK

View Code? Open in Web Editor NEW
803.0 32.0 255.0 596 KB

A mercurial to git converter using git-fast-import

Home Page: http://repo.or.cz/w/fast-export.git

Python 73.24% Shell 26.54% Makefile 0.22%

fast-export's Introduction

hg-fast-export.sh - mercurial to git converter using git-fast-import

Legal

Most hg-* scripts are licensed under the MIT license and were written by Rocco Rutte [email protected] with hints and help from the git list and #mercurial on freenode. hg-reset.py is licensed under GPLv2 since it copies some code from the mercurial sources.

The current maintainer is Frej Drejhammar [email protected].

Support

If you have problems with hg-fast-export or have found a bug, please create an issue at the github issue tracker. Before creating a new issue, check that your problem has not already been addressed in an already closed issue. Do not contact the maintainer directly unless you want to report a security bug. That way the next person having the same problem can benefit from the time spent solving the problem the first time.

System Requirements

This project depends on Python (>=3.7) and the Mercurial package (>= 5.2). If Python is not installed, install it before proceeding. The Mercurial package can be installed with pip install mercurial.

On windows the bash that comes with "Git for Windows" is known to work well.

Usage

Using hg-fast-export is quite simple for a mercurial repository :

git init repo-git # or whatever
cd repo-git
hg-fast-export.sh -r <local-repo>
git checkout

Please note that hg-fast-export does not automatically check out the newly imported repository. You probably want to follow up the import with a git checkout-command.

Incremental imports to track hg repos is supported, too.

Using hg-reset it is quite simple within a git repository that is hg-fast-export'ed from mercurial:

hg-reset.sh -R <revision>

will give hints on which branches need adjustment for starting over again.

When a mercurial repository does not use utf-8 for encoding author strings and commit messages the -e <encoding> command line option can be used to force fast-export to convert incoming meta data from to utf-8. This encoding option is also applied to file names.

In some locales Mercurial uses different encodings for commit messages and file names. In that case, you can use --fe <encoding> command line option which overrides the -e option for file names.

As mercurial appears to be much less picky about the syntax of the author information than git, an author mapping file can be given to hg-fast-export to fix up malformed author strings. The file is specified using the -A option. The file should contain lines of the form "<key>"="<value>". Inside the key and value strings, all escape sequences understood by the python unicode_escape encoding are supported; strings are otherwise assumed to be UTF8-encoded. (Versions of fast-export prior to v171002 had a different syntax, the old syntax can be enabled by the flag --mappings-are-raw.)

The example authors.map below will translate User <garbage<tab><[email protected]> to User <[email protected]>.

-- Start of authors.map --
"User <garbage\t<[email protected]>"="User <[email protected]>"
-- End of authors.map --

If you have many Mercurial repositories, Chris J Billington's hg-export-tool allows you to batch convert them.

Tag and Branch Naming

As Git and Mercurial have differ in what is a valid branch and tag name the -B and -T options allow a mapping file to be specified to rename branches and tags (respectively). The syntax of the mapping file is the same as for the author mapping.

When the -B and -T flags are used, you will probably want to use the -n flag to disable the built-in (broken in many cases) sanitizing of branch/tag names. In the future -n will become the default, but in order to not break existing incremental conversions, the default remains with the old behavior.

By default, the default mercurial branch is renamed to the master branch on git. If your mercurial repo contains both default and master branches, you'll need to override this behavior. Use -M <newName> to specify what name to give the default branch.

Content filtering

hg-fast-export supports filtering the content of exported files. The filter is supplied to the --filter-contents option. hg-fast-export runs the filter for each exported file, pipes its content to the filter's standard input, and uses the filter's standard output in place of the file's original content. The prototypical use of this feature is to convert line endings in text files from CRLF to git's preferred LF:

-- Start of crlf-filter.sh --
#!/bin/sh
# $1 = pathname of exported file relative to the root of the repo
# $2 = Mercurial's hash of the file
# $3 = "1" if Mercurial reports the file as binary, otherwise "0"

if [ "$3" == "1" ]; then cat; else dos2unix -q; fi
# -q option in call to dos2unix allows to avoid returning an
# error code when handling non-ascii based text files (like UTF-16
# encoded text files)
-- End of crlf-filter.sh --

Plugins

hg-fast-export supports plugins to manipulate the file data and commit metadata. The plugins are enabled with the --plugin option. The value of said option is a plugin name (by folder in the plugins directory), and optionally, and equals-sign followed by an initialization string.

There is a readme accompanying each of the bundled plugins, with a description of the usage. To create a new plugin, one must simply add a new folder under the plugins directory, with the name of the new plugin. Inside, there must be an __init__.py file, which contains at a minimum:

def build_filter(args):
    return Filter(args)

class Filter:
    def __init__(self, args):
        pass
        #Or don't pass, if you want to do some init code here

Beyond the boilerplate initialization, you can see the two different defined filter methods in the dos2unix and branch_name_in_commit plugins.

commit_data = {'branch': branch, 'parents': parents, 'author': author, 'desc': desc, 'revision': revision, 'hg_hash': hg_hash, 'committer': 'committer', 'extra': extra}

def commit_message_filter(self,commit_data):

The commit_message_filter method is called for each commit, after parsing from hg, but before outputting to git. The dictionary commit_data contains the above attributes about the commit, and can be modified by any filter. The values in the dictionary after filters have been run are used to create the git commit.

file_data = {'filename':filename,'file_ctx':file_ctx,'data':file_contents}

def file_data_filter(self,file_data):

The file_data_filter method is called for each file within each commit. The dictionary file_data contains the above attributes about the file, and can be modified by any filter. file_ctx is the filecontext from the mercurial python library. After all filters have been run, the values are used to add the file to the git commit.

The file_data_filter method is also called when files are deleted, but in this case the data and file_ctx keys map to None. This is so that a filter which modifies file names can apply the same name transformations when files are deleted.

Submodules

See README-SUBMODULES.md for how to convert subrepositories into git submodules.

Notes/Limitations

hg-fast-export supports multiple branches but only named branches with exactly one head each. Otherwise commits to the tip of these heads within the branch will get flattened into merge commits. There are a few options to deal with this:

  1. Chris J Billington's hg-export-tool can help you to handle branches with duplicate heads.
  2. Use the head2branch plugin to create a new named branch from an unnamed head.
  3. You can ignore unnamed heads with the --ignore-unnamed-heads option, which is appropriate in situations such as the extra heads being close commits (abandoned, unmerged changes).

hg-fast-export will ignore any files or directories tracked by mercurial called .git, and will print a warning if it encounters one. Git cannot track such files or directories. This is not to be confused with submodules, which are described in README-SUBMODULES.md.

As each git-fast-import run creates a new pack file, it may be required to repack the repository quite often for incremental imports (especially when importing a small number of changesets per incremental import).

The way the hg API and remote access protocol is designed it is not possible to use hg-fast-export on remote repositories (http/ssh). First clone the repository, then convert it.

Design

hg-fast-export was designed in a way that doesn't require a 2-pass mechanism or any prior repository analysis: it just feeds what it finds into git-fast-import. This also implies that it heavily relies on strictly linear ordering of changesets from hg, i.e. its append-only storage model so that changesets hg-fast-export already saw never get modified.

Submitting Patches

Please create a pull request at Github to submit patches.

When submitting a patch make sure the commits in your pull request:

  • Have good commit messages

    Please read Chris Beams' blog post How to Write a Git Commit Message on how to write a good commit message. Although the article recommends at most 50 characters for the subject, up to 72 characters are frequently accepted for fast-export.

  • Adhere to good commit hygiene

    When developing a pull request for hg-fast-export, base your work on the current master branch and rebase your work if it no longer can be merged into the current master without conflicts. Never merge master into your development branch, rebase if your work needs updates from master.

    When a pull request is modified due to review feedback, please incorporate the changes into the proper commit. A good reference on how to modify history is in the Pro Git book, Section 7.6.

Please do not submit a pull request if you are not willing to spend the time required to address review comments or revise the patch until it follows the guidelines above. A take it or leave it approach to contributing wastes both your and the maintainer's time.

Frequent Problems

  • git fast-import crashes with: error: cannot lock ref 'refs/heads/...

    Branch names in git behave as file names (as they are just files and sub-directories under refs/heads/, and a path cannot name both a file and a directory, i.e. the branches a and a/b can never exist at the same time in a git repo.

    Use a mapping file to rename the troublesome branch names.

  • Branch [<branch-name>] modified outside hg-fast-export but I have not touched the repo!

    If you are running fast-export on a case-preserving but case-insensitive file system (Windows and OSX), this will make git treat A and a as the same branch. The solution is to use a mapping file to rename branches which only differ in case.

  • My mapping file does not seem to work when I rename the branch git fast-import crashes on!

    fast-export (imperfectly) mangles branch names it thinks won't be valid. The mechanism cannot be removed as it would break already existing incremental imports that expects it. When fast export mangles a name, it prints out a warning of the form Warning: sanitized branch [<unmangled>] to [<mangled>]. If git fast-import crashes on <mangled>, you need to put <unmangled> into the mapping file.

  • fast-import mangles valid git branch names which I have remapped!

    Use the -n flag to hg-fast-export.sh.

  • git status reports that all files are scheduled for deletion after the initial conversion.

    By design fast export does not touch your working directory, so to git it looks like you have deleted all files, when in fact they have never been checked out. Just do a checkout of the branch you want.

  • Error: repository has at least one unnamed head: hg r<N>

    By design, hg-fast-export cannot deal with extra heads on a branch. There are a few options depending on whether the extra heads are in-use/open or normally closed. See Notes/Limitations section for more details.

fast-export's People

Contributors

alexreg avatar barrywardell avatar chrisjbillington avatar clee avatar dpw avatar ethanfurman avatar felipec avatar frej avatar glacios avatar hanwen avatar jhenkens avatar living180 avatar mackyle avatar madmaxreach avatar mark-raymond avatar matthijsburgh avatar mossop avatar nicolas-van avatar ondrej-stanek avatar onlined avatar petercolberg avatar phargogh avatar pidelport avatar smurfix avatar sth avatar thaliaarchi avatar tronical avatar zedxxx avatar zpao avatar zr40 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fast-export's Issues

emacs autosaves

Hi,
the tool you created seems awesome, however I cannot use it properly. First because of the python3 issue that is easy solvable but then because at some in time in the repository there is a commit with an Emacs autosave file, i.e., a file that contains a hash as part of the name.

I believe the script is taking the remaining part of the file name as a comment :-( and therefore fails to find its proper attributes.

I wish I knew more python myself to fix it and provide the patch but sadly I do not even know where to start.

I hope this is an easy fix for yo guys.

Thanks and keep up the good work.

Resolve SVN code?

It seems to me that files

  • svn-archive.c
  • svn-fast-export.c
  • svn-fast-export.py
  • Makefile

are leftovers from a previous project. If they are, maybe delete them for clean-up.
There are two related entries in .gitignore as well:

  • svn-archive
  • svn-fast-export

Best, S

AttributeError: 'httprepository' object has no attribute 'changelog'

Here is the log

 [test@vm1 temp]$../fast-export/hg-fast-export.sh  -r http://www.freediameter.net/hg/freeDiameter
Traceback (most recent call last):
  File "../fast-export/hg-fast-export.py", line 427, in <module>
    options.statusfile,authors=a,sob=options.sob,force=options.force,hgtags=options.hgtags,notes=options.notes))
  File "../fast-export/hg-fast-export.py", line 336, in hg2git
    if not verify_heads(ui,repo,heads_cache,force):
  File "../fast-export/hg-fast-export.py", line 300, in verify_heads
    branches[bn] = branchtip(repo, heads)
  File "../fast-export/hg-fast-export.py", line 292, in branchtip
    if 'close' not in repo.changelog.read(h)[5]:
AttributeError: 'httprepository' object has no attribute 'changelog'
git-fast-import statistics:
---------------------------------------------------------------------
Alloc'd objects:       5000
Total objects:            0 (         0 duplicates                  )
      blobs  :            0 (         0 duplicates          0 deltas)
      trees  :            0 (         0 duplicates          0 deltas)
      commits:            0 (         0 duplicates          0 deltas)
      tags   :            0 (         0 duplicates          0 deltas)
Total branches:           0 (         0 loads     )
      marks:           1024 (         0 unique    )
      atoms:              0
Memory total:          2282 KiB
       pools:          2048 KiB
     objects:           234 KiB
---------------------------------------------------------------------
pack_report: getpagesize()            =       4096
pack_report: core.packedGitWindowSize = 1073741824
pack_report: core.packedGitLimit      = 8589934592
pack_report: pack_used_ctr            =          0
pack_report: pack_mmap_calls          =          0
pack_report: pack_open_windows        =          0 /          0
pack_report: pack_mapped              =          0 /          0
---------------------------------------------------------------------

and here are some versions

[temp@vm1 temp]$ cat /etc/redhat-release 
CentOS release 6.5 (Final)

[test@vm1 temp]$ hg --version
Mercurial Distributed SCM (version 1.4)

Copyright (C) 2005-2009 Matt Mackall <[email protected]> and others
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

[test@vm1 temp]$ git --version
git version 1.7.1

[test@vm1 temp]$ python --version
Python 2.6.6

Illegal option -o pipefail

This fails for me on Ubuntu Precise with the following error.

/tmp/fast-export/hg-fast-export.sh: 6: set: Illegal option -o pipefail

It appears to be the patch that #16 added. Reverting to before that works fine.

tfoote@stitch:/tmp/fast-export$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 12.04.2 LTS
Release:    12.04
Codename:   precise
tfoote@stitch:/tmp/fast-export$ bash --version
GNU bash, version 4.2.25(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Branch history out of order after conversion

Hi. I just ran fast-export on several mercurial repos and am manually reviewing the commit and branch history. I noticed that everything seems in order on the default/master branch, but other branches have their commits out of order. This is confirmed by comparing both the graph history and the date sequences. It seems to be grouping some of the commits by author name and date ordering them. Repos that don't have branching seem to be fine. I have only run the command:

$ pwd
/path to git directory/
$ hg-fast-export.sh -r

Is there another pass or command I need to run to clean-up the branch history?

gets confused by missing original branch commits in a clone

I had a local clone of the orginal hg repo, which I initially used for
hg-fast-export -r ../orig_hg -M master

Then I committed my change(s) in a another local hg clone of the
original clone (a separate hg repo for my changes is a way to easily
separate them in the resulting git branches).

I imported my changes with hg-fast-export -r ../my_hg -M my

I was very surprized not to see my new change on top of the master
git branch, as a single new commit of the my git branch. (This is
what I can reproduce reliably; once there was also a strange case,
when my and master git branches diverged, although master should
be the ancestor. I think it was a more complex case of the same
problem.)

How to reproduce

in a "top-level" dir

mkdir orig_hg
cd orig_hg/

in orig_hg/

hg init
echo a >f
hg add f
hg commit -m A
hg branch t
echo b >f
hg commit -m B
hg update default
echo c >f
hg commit -m C
cd ..

in the top-level dir

hg clone -b default orig_hg my_hg
cd my_hg/

in my_hg/

echo d >f
hg commit -m D
cd ..

in the top-level dir

mkdir tmp_git
cd tmp_git/

in tmp_git/

tmp_git $ git init
tmp_git $ hg-fast-export -r ../orig_hg -M master
master: Exporting full revision 1/3 with 1/0/0 added/changed/removed files
t: Exporting simple delta revision 2/3 with 0/1/0 added/changed/removed files
master: Exporting simple delta revision 3/3 with 0/1/0 added/changed/removed files
Issued 3 commands
git-fast-import statistics:
---------------------------------------------------------------------
Alloc'd objects:       5000
Total objects:            9 (         0 duplicates                  )
      blobs  :            3 (         0 duplicates          0 deltas of          0 attempts)
      trees  :            3 (         0 duplicates          0 deltas of          3 attempts)
      commits:            3 (         0 duplicates          0 deltas of          0 attempts)
      tags   :            0 (         0 duplicates          0 deltas of          0 attempts)
Total branches:           2 (         2 loads     )
      marks:           1024 (         3 unique    )
      atoms:              1
Memory total:          2344 KiB
       pools:          2110 KiB
     objects:           234 KiB
---------------------------------------------------------------------
pack_report: getpagesize()            =       4096
pack_report: core.packedGitWindowSize = 1073741824
pack_report: core.packedGitLimit      = 8589934592
pack_report: pack_used_ctr            =          6
pack_report: pack_mmap_calls          =          2
pack_report: pack_open_windows        =          1 /          1
pack_report: pack_mapped              =        614 /        614
---------------------------------------------------------------------

tmp_git $ gitk --all
tmp_git $ hg-fast-export -r ../my_hg -M my
Issued 0 commands
git-fast-import statistics:
---------------------------------------------------------------------
Alloc'd objects:       5000
Total objects:            0 (         0 duplicates                  )
      blobs  :            0 (         0 duplicates          0 deltas of          0 attempts)
      trees  :            0 (         0 duplicates          0 deltas of          0 attempts)
      commits:            0 (         0 duplicates          0 deltas of          0 attempts)
      tags   :            0 (         0 duplicates          0 deltas of          0 attempts)
Total branches:           0 (         0 loads     )
      marks:           1024 (         0 unique    )
      atoms:              0
Memory total:          2282 KiB
       pools:          2048 KiB
     objects:           234 KiB
---------------------------------------------------------------------
pack_report: getpagesize()            =       4096
pack_report: core.packedGitWindowSize = 1073741824
pack_report: core.packedGitLimit      = 8589934592
pack_report: pack_used_ctr            =          0
pack_report: pack_mmap_calls          =          0
pack_report: pack_open_windows        =          0 /          0
pack_report: pack_mapped              =          0 /          0
---------------------------------------------------------------------

tmp_git $ hg-fast-export -r ../my_hg -M my
Issued 0 commands
git-fast-import statistics:
---------------------------------------------------------------------
Alloc'd objects:       5000
Total objects:            0 (         0 duplicates                  )
      blobs  :            0 (         0 duplicates          0 deltas of          0 attempts)
      trees  :            0 (         0 duplicates          0 deltas of          0 attempts)
      commits:            0 (         0 duplicates          0 deltas of          0 attempts)
      tags   :            0 (         0 duplicates          0 deltas of          0 attempts)
Total branches:           0 (         0 loads     )
      marks:           1024 (         0 unique    )
      atoms:              0
Memory total:          2282 KiB
       pools:          2048 KiB
     objects:           234 KiB
---------------------------------------------------------------------
pack_report: getpagesize()            =       4096
pack_report: core.packedGitWindowSize = 1073741824
pack_report: core.packedGitLimit      = 8589934592
pack_report: pack_used_ctr            =          0
pack_report: pack_mmap_calls          =          0
pack_report: pack_open_windows        =          0 /          0
pack_report: pack_mapped              =          0 /          0
---------------------------------------------------------------------

tmp_git $ gitk --all

No ne commit in my. Bad.

A workaround:

tmp_git $ rm -rfv .git/hg*
rm: removing file `.git/hg2git-heads'
rm: removing file `.git/hg2git-mapping'
rm: removing file `.git/hg2git-marks'
rm: removing file `.git/hg2git-state'
tmp_git $ hg-fast-export -r ../my_hg -M my
my: Exporting full revision 1/3 with 1/0/0 added/changed/removed files
my: Exporting simple delta revision 2/3 with 0/1/0 added/changed/removed files
my: Exporting simple delta revision 3/3 with 0/1/0 added/changed/removed files
Issued 3 commands
git-fast-import statistics:
---------------------------------------------------------------------
Alloc'd objects:       5000
Total objects:            3 (         6 duplicates                  )
      blobs  :            1 (         2 duplicates          0 deltas of          0 attempts)
      trees  :            1 (         2 duplicates          0 deltas of          1 attempts)
      commits:            1 (         2 duplicates          0 deltas of          0 attempts)
      tags   :            0 (         0 duplicates          0 deltas of          0 attempts)
Total branches:           1 (         1 loads     )
      marks:           1024 (         3 unique    )
      atoms:              1
Memory total:          2344 KiB
       pools:          2110 KiB
     objects:           234 KiB
---------------------------------------------------------------------
pack_report: getpagesize()            =       4096
pack_report: core.packedGitWindowSize = 1073741824
pack_report: core.packedGitLimit      = 8589934592
pack_report: pack_used_ctr            =          2
pack_report: pack_mmap_calls          =          1
pack_report: pack_open_windows        =          1 /          1
pack_report: pack_mapped              =        238 /        238
---------------------------------------------------------------------

tmp_git $ gitk --all

The cause

The cause is probably that orig_hg had an extra commit in branch
t, totalling 3 with the last sequential number 2. And in my_hg
with the extra branch omitted there are total 3 commits with the last
one having number 2, too.

So, it is somehow unnoticed in the result of hg-fast-export.

Support ignoring files/directories on import

I'm not sure if this is within the scope of this project but I ran into an issue when running the script when the Mercurial repository contains a git sub-repository.

I describe what happened here, but for reference, I'll restate it here.

Basically what (I think) happened was the history for the .git directory was imported but the .git directory itself was non-existant. So when trying to purge that directory it kept giving me file doesn't exist errors.

Any idea what the best course of action would be? Does hg-fast-export support ignoring git directories? I couldn't find anything in the source (although I didn't look for more than 10 min).

Thanks!

fatal: Missing space after > in ident string

I am getting an error importing a repository

fatal: Missing space after > in ident string:  <unspecified>P <devnull@localhost> 1404822619 +0100
fast-import: dumping crash report to .git/fast_import_crash_5724
Traceback (most recent call last):
  File "../fast-export/hg-fast-export.py", line 504, in <module>
    notes=options.notes,encoding=encoding,fn_encoding=fn_encoding))
  File "../fast-export/hg-fast-export.py", line 404, in hg2git
    sob,brmap,hgtags,encoding,fn_encoding)
  File "../fast-export/hg-fast-export.py", line 244, in export_commit
    export_file_contents(ctx,man,changed,hgtags,fn_encoding)
  File "../fast-export/hg-fast-export.py", line 141, in export_file_contents
    wr(d)
  File "../fast-export/hg-fast-export.py", line 37, in wr
    wr_no_nl(msg)
  File "../fast-export/hg-fast-export.py", line 34, in wr_no_nl
    sys.stdout.write(msg)
IOError: [Errno 32] Broken pipe

I think this might be because the committer name is <unspecified>P which has a 2nd set of <> causing the parser to configure the user name with the host name. The relevant part of the crash report is:

committer Paul Hickman <devnull@localhost> 1404740209 +0100
  data 80
  from :3015
  M 100644 inline Scripts/Migrate-107000001-Client-Paul.sql
  data 797

  commit refs/heads/master
  mark :3017
* committer <unspecified>P <devnull@localhost> 1404822619 +0100

Active Branch LRU
-----------------
    active_branches = 1 cur, 5 max

  pos  clock name
   1)   3016 refs/heads/master

Inactive Branches
-----------------
refs/heads/master:
  status      : active loaded
  tip commit  : 3854800d894b00d6f468e99e6cb5eca640a7cf31
  old tree    : 2c9298f523dbb78a984546965e79261220de00da
  cur tree    : 2c9298f523dbb78a984546965e79261220de00da
  commit clock: 3016
  last pack   : 0


Marks
-----
  exported to /home/lfs/dest/.git/hg2git-marks.tmp

-------------------
END OF CRASH REPORT

What are Windows dependencies for script to work?

I am trying to run the script on Windows, environment is:

  • Git Bash 1.9
  • Mercurial 2.9 x64

I got error message about python not available.

  • installed Python 3.4 x64

Now I am getting following error:

Traceback (most recent call last):
  File "c:/server/ext/fast-export/hg-fast-export.py", line 6, in <module>
    from mercurial import node
ImportError: No module named 'mercurial'

Which dependencies exactly and in what configuration do I need to run this on Windows?

unable to resolve reference ... : Not a directory

We used the tool for pypy repo (https://bitbucket.org/pypy/pypy).
And after solved the issue "Empty path component found in input #48", there appeared another error:

Exporting tag [release-2.4.0] at [hg r73641] [git :73642]
...
Exporting tag [release-2.6.0] at [hg r77718] [git :77719]
Issued 79019 commands
error: unable to resolve reference refs/heads/stdlib-unification/py3k: Not a directory
error: Unable to lock refs/heads/stdlib-unification/py3k

git-fast-import statistics:

Alloc'd objects: 630000
...

The exporing process completed. But besides .git directory, there were no files exported.

Tags are not converted correctly

Used hg-fast-export on a Bitbucket repository, converting it to Git.
All went well, except for the tags. Now, the tags are gone, and the related commit points to a non existing changeset, that only exists in the old hg repository.
("Added tag 1.4.1 for changeset 5c688cb43dc7")

Windows support?

Running hg-fast-export.py for my repository throws an error 'No --marks option given'.
People say that hg-fast-export.sh seems to be working fine, but I'm running on Windows, so no bash support.

hg-fast-export bash script breaks when --force is used

When invoking:
hg-fast-export --force --quiet -r /path/to/hg/repo

The script bails out saying one should provide a '-r' option, which is provided.

I suspect the "break" statement in the bash loop collecting arguments is unintentional.

Converting .hg Subrepository

Hi,

is it possible, to convert subrepos from hg to git submodules? we are using a lot of subrepos right now, we need to convert them too. we would like to keep the history.

best regards

Commit messages became unreadable (Chinese text)

I want migrate from mercurial to git, and this tool works very well indeed, except all the commit messages(which were wrote in Chinese) became unreadable.

I checked the Chinese text inside code file, they were displayed very correct, and if I make a new commit in git, it can be displayed correct , too.

so , the only error is the historical message "exported" from mercurial, and I hope this could be fixed , thanks!

ps: below is some Chinese text, if you might use it for test...
你好,谢谢!

fast-export fails if python3 is sytem-wide default

If the system default python is python3 (i.e. the symlink is /usr/bin/python -> /usr/bin/python3) then fast-export fails as it is python2 only. The error is in this case rather confusingly

veelai@zaphod ~/fast-export $ python3 hg-fast-export.py 
Traceback (most recent call last):
  File "fast-export/hg-fast-export.py", line 6, in 
    from mercurial import node
ImportError: No module named mercurial

A possible solution is to replace PYTHON=${PYTHON:-python} by PYTHON=${PYTHON:-python2} in the shell scripts and '#!/usr/bin/env python' by '#!/usr/bin/env python2' in the python scripts. This should work in most environments, with one caveat: Debian as greatest distribution under the sky decided to be extravagant and does not ship a python2 symlink, but only python2.6 and similar.

sanitize_name methos doesn't cover all required cases.

Sanitize name is failing if branch name has less than two symbols.
Also it filtering regexp doen't cover cases if branch name has ' = and some other symbols.

My version of this method looks like:

def sanitize_name(name,what="branch"):
        """Sanitize input roughly according to git-check-ref-format(1)"""

        def dot(name):
            if len(name) == 0:
              return name
            if name[0] == '.' and len(name) == 1:
              return '_'
            if name[0] == '.':    
              return '_'+name[1:]
            return name

        n=name
        p=re.compile('([[ ~^:?\\\\*\)\(\=\,\'#]|\.\.)')
        n=n.strip()
        n=p.sub('_', n)
        if n[-1] in ('/', '.'): n=n[:-1]+'_'
        n='/'.join(map(dot,n.split('/')))
        p=re.compile('_+')        
        n=p.sub('_', n)  
        if n!=name:
            sys.stderr.write('Warning: sanitized %s [%s] to [%s]\n' % (what,name,n))
        return n

Fast export doesn't seem to do anything?

C:\Program Files\Git\mingw64\libexec\git-core\git-fast-import.exe statistics:

Alloc'd objects: 5000
Total objects: 0 ( 0 duplicates )
blobs : 0 ( 0 duplicates 0 deltas of 0 attempts)
trees : 0 ( 0 duplicates 0 deltas of 0 attempts)
commits: 0 ( 0 duplicates 0 deltas of 0 attempts)
tags : 0 ( 0 duplicates 0 deltas of 0 attempts)
Total branches: 0 ( 0 loads )
marks: 1024 ( 0 unique )
atoms: 0
Memory total: 2282 KiB
pools: 2048 KiB

objects: 234 KiB

pack_report: getpagesize() = 65536
pack_report: core.packedGitWindowSize = 1073741824
pack_report: core.packedGitLimit = 8589934592
pack_report: pack_used_ctr = 0
pack_report: pack_mmap_calls = 0
pack_report: pack_open_windows = 0 / 0

pack_report: pack_mapped = 0 / 0

My hg repo has a few branches, and over 1000 commits.
image

If I run git checkout HEAD afer, I get this error: error: pathspec 'HEAD' did not match any file(s) known to git.

Empty path component found in input

We used the tool for Pypy repository(https://bitbucket.org/pypy/pypy/downloads).
By using author-map, we worked out the issue "Missing < in ident string" at revesion 53977.
But there comes another error "Empy path component found in input":
fatal: Empty path component found in input
fast-import: dumping crash report to .git/fast_import_crash_25934
Traceback (most recent call last):
File "/home/yicong.hyc/fast-export/hg-fast-export.py", line 445, in
notes=options.notes,encoding=encoding))
File "/home/yicong.hyc/fast-export/hg-fast-export.py", line 367, in hg2git
c=export_commit(ui,repo,rev,old_marks,max,c,authors,sob,brmap,hgtags,notes,encoding)
File "/home/yicong.hyc/fast-export/hg-fast-export.py", line 228, in export_commit
export_file_contents(ctx,man,added,hgtags,encoding)
File "/home/yicong.hyc/fast-export/hg-fast-export.py", line 140, in export_file_contents
wr(d)
File "/home/yicong.hyc/fast-export/hg-fast-export.py", line 37, in wr
wr_no_nl(msg)
File "/home/yicong.hyc/fast-export/hg-fast-export.py", line 34, in wr_no_nl
sys.stdout.write(msg)
IOError: [Errno 32] Broken pipe

Looking at crahed report, we observed:

Most Recent Commands Before Crash

D pypy/translator/jvm/test/test_tuple.py
D pypy/translator/jvm/test/test_unicode.py
...
D pypy/translator/unsimplify.py
M 100644 inline /doc/config/translation.lldebug.txt

  • data 38

Branch name with Quotes

We are converting our hg repositories to git. We are getting an error while converting it, the reason is that our branch name contains quotations characters. The branch name is [ Protocol "74 fixed" ]. It gives the following error.

Fatal: Unable to create 'C:/Dev/projectA/.git/refs/heads/Protocol "74 fixed "-Datum.lock': Invalid argument.

Could you please tell us how can we fix this error?

Tags are not preserved after "git push"

I just run fast-export against my psutil repository:
https://code.google.com/p/psutil/source/checkout

fast-export.sh completes successfully and I can see all my tags exported into the new GIT repository:

giampaolo@UX32VD:/tmp/newgit$ git tags
release-0.1.0   Avoided to call distutils.core.setup() twice which caused setup.py to generate two .exe installers when running "setup.py bdist_wininst".
release-0.1.1   Get rid of MANIFEST file.
release-0.1.2   Added distutil's "keyword" argument.
...

I then pushed the new GIT repository on a remote repository:

git remote add origin [email protected]:grodola/prjname.git
git push origin mastter

Everything looks good except that if I change directory then clone the repository I just created all the tags are gone. Any idea?

no checks in ident string

I'm currently trying to convert a large mercurial repo to git using fast-export. After running it for some time, fast-export crashes with:

fatal: Missing > in ident string: test user <[email protected] 123456778 +1200
with the following traceback:
Traceback (most recent call last):
File "/home/cc/projs/fast-export/hg-fast-export.py", line 442, in
notes=options.notes,encoding=encoding))
File "/home/cc/projs/fast-export/hg-fast-export.py", line 364, in hg2git
c=export_commit(ui,repo,rev,old_marks,max,c,authors,sob,brmap,hgtags,notes,encoding)
File "/home/cc/projs/fast-export/hg-fast-export.py", line 226, in export_commit
export_file_contents(ctx,man,changed,hgtags,encoding)
File "/home/cc/projs/fast-export/hg-fast-export.py", line 140, in export_file_contents
wr(d)
File "/home/cc/projs/fast-export/hg-fast-export.py", line 37, in wr
wr_no_nl(msg)
File "/home/cc/projs/fast-export/hg-fast-export.py", line 34, in wr_no_nl
sys.stdout.write(msg)
IOError: [Errno 32] Broken pipe

fatal: Invalid raw date

hg-fast-export fails on a checkout of ssh://[email protected]/illumos-gate

master: Exporting simple delta revision 7371/14114 with 0/7/0 added/changed/removed files
fatal: Invalid raw date "<devnull@localhost> 1219151827 -0600" in ident:  <Gerald Jelinek> <devnull@localhost> 1219151827 -0600
fast-import: dumping crash report to .git/fast_import_crash_1875
Traceback (most recent call last):
  File "/usr/share/hg-fast-export/hg-fast-export.py", line 387, in <module>
    options.statusfile,authors=a,sob=options.sob,force=options.force))
  File "/usr/share/hg-fast-export/hg-fast-export.py", line 321, in hg2git
    c=export_commit(ui,repo,rev,old_marks,max,c,authors,sob,brmap)
  File "/usr/share/hg-fast-export/hg-fast-export.py", line 214, in export_commit
    export_file_contents(ctx,man,changed)
  File "/usr/share/hg-fast-export/hg-fast-export.py", line 125, in export_file_contents
    wr(d)
  File "/usr/share/hg-fast-export/hg-fast-export.py", line 26, in wr
    sys.stdout.write(msg)
IOError: [Errno 32] Broken pipe

The crash dump contains this command:

  commit refs/heads/master
  mark :7371
* committer <Gerald Jelinek> <devnull@localhost> 1219151827 -0600

Export script reports fatal error when hg branch name contains ampersand

  1. Use the default options for hg-fast-export.sh i.e. no mapping files are supplied
  2. Try to convert a Mercurial repository that contains a branch whose name contains an ampersand character
  3. Along with any messages warning of sanitized branch names, a message reads

fatal: Needed a single revision

File/Folder names with international characters get mangled

When converting from mercurial to git, file and folder names containing international characters get mangled, and somehow not committed properly. A folder name like västfolket will become v%E4stfolket, and all files that are affected will show as uncommitted changes in the repo afterwards.

Tested on OSX

Fail on old repository

I have quite large repository. When I'm exporting to git from hg I'm receiving error:

master: Exporting thorough delta revision 2804/4207 with 0/23/1 added/changed/removed files
Traceback (most recent call last):
  File "../fast-export/hg-fast-export.py", line 432, in <module>
    options.statusfile,authors=a,sob=options.sob,force=options.force,hgtags=options.hgtags,notes=options.notes))
  File "../fast-export/hg-fast-export.py", line 362, in hg2git
    c=export_commit(ui,repo,rev,old_marks,max,c,authors,sob,brmap,hgtags,notes)
  File "../fast-export/hg-fast-export.py", line 224, in export_commit
    export_file_contents(ctx,man,changed,hgtags)
  File "../fast-export/hg-fast-export.py", line 136, in export_file_contents
    wr(d)
  File "../fast-export/hg-fast-export.py", line 37, in wr
    wr_no_nl(msg)
  File "../fast-export/hg-fast-export.py", line 34, in wr_no_nl
    sys.stdout.write(msg)
IOError: [Errno 32] Broken pipe

I'm used following options:
../fast-export/hg-fast-export.sh -r reponame/ --hgtags --hg-hash --force

fails on https://bitbucket.org/pypy/pypy with Broken pipe

Fails on normal run:

><(((º> ~/repos/fast-export/hg-fast-export.sh -r ~/repos/pypy         
Error: repository has at least one unnamed head: hg r72634

Fails with --force:

><(((º> ~/repos/fast-export/hg-fast-export.sh -r ~/repos/pypy/ --force
Traceback (most recent call last):
  File "/home/saidler/repos/fast-export/hg-fast-export.py", line 468, in <module>
  notes=options.notes,encoding=encoding))
  File "/home/saidler/repos/fast-export/hg-fast-export.py", line 377, in hg2git
  sob,brmap,hgtags,notes,encoding)
  File "/home/saidler/repos/fast-export/hg-fast-export.py", line 235, in export_commit
  export_file_contents(ctx,man,changed,hgtags,encoding)
  File "/home/saidler/repos/fast-export/hg-fast-export.py", line 141, in export_file_contents
  wr(d)
 File "/home/saidler/repos/fast-export/hg-fast-export.py", line 37, in wr
 wr_no_nl(msg)
 File "/home/saidler/repos/fast-export/hg-fast-export.py", line 34, in wr_no_nl
 sys.stdout.write(msg)
 IOError: [Errno 32] Broken pipe

When re-running fast-export, error 'Branch [master] modified outside hg-fast-export' is shown.

This is the command I'm using:

hg-fast-export.sh -r C:/Migration/WorkingDir -A authors.map

Here's the actual error message:

Error: Branch [master] modified outside hg-fast-export:
e7443efd712a7dcff6296b975626f471e246c875 (repo) != None (cache)

Of course, I don't even have a 'master' branch in HG, I have a 'default' branch, which is then renamed to 'master' when exported to git.

This only happens when trying to catch up a previously exported repository.

Unexpected EOF while looking for matching `

Hi,

Me and @mriska get this while trying to convert a repo:

sh: -c: line 0: unexpected EOF while looking for matching `''
sh: -c: line 1: syntax error: unexpected end of file
Error: repository has at least one unnamed head: hg r3868
git-fast-import statistics:
---------------------------------------------------------------------
Alloc'd objects:       5000
Total objects:            0 (         0 duplicates                  )
      blobs  :            0 (         0 duplicates          0 deltas of          0 attempts)
      trees  :            0 (         0 duplicates          0 deltas of          0 attempts)
      commits:            0 (         0 duplicates          0 deltas of          0 attempts)
      tags   :            0 (         0 duplicates          0 deltas of          0 attempts)
Total branches:           0 (         0 loads     )
      marks:           1024 (         0 unique    )
      atoms:              0
Memory total:          2282 KiB
       pools:          2048 KiB
     objects:           234 KiB
---------------------------------------------------------------------
pack_report: getpagesize()            =       4096
pack_report: core.packedGitWindowSize = 1073741824
pack_report: core.packedGitLimit      = 8589934592
pack_report: pack_used_ctr            =          0
pack_report: pack_mmap_calls          =          0
pack_report: pack_open_windows        =          0 /          0
pack_report: pack_mapped              =          0 /          0
---------------------------------------------------------------------

This is using a very plain command line, with basically hg-fast-export.sh -r <sourcefolder>. The system is Mac OS X, with Python 2.7.

Any ideas? Unfortunately, this is speaking about a private repo, so I can not provide it to you for debugging.

The source repo is of relatively modest size, around 5000 commits. I've actually managed to convert it some months back, but we couldn't move over to Git at that time because of complexity within the project. Now it's time to do the conversion but this errors makes it a bit hard... 😄

Thanks in advance!

Import HG bookmarks to Git branches

HG bookmarks are effectively the same thing as Git feature branches, while HG branches are a very different beast, much less useful IMHO.

Therefore it would be useful if fast-export converted HG bookmarks → Git branches, instead of failing with an error:

Error: repository has at least one unnamed head: hg r779

fast-export failing on wrongly-named branched exported from mercurial

I have pretty old mercurial repository where branches named with useing spaces and different symbold. Import from such repository failed due to fail of def get_git_sha1(name,type='heads') method.

To fix it I think sanitize_name method should be moved into hg2git.py and called from get_git_sha1, by I didn't know good enouth codebase som I might be wrong.

store hg hashes in git commit notes

After migrating hg to git repository it would be worth to have the mapping of mercurial commit hashes into git commit hashes handy. Git commit notes could be used for this.

Conversion crashes due to empty commiter

Hi,

When I'm running a conversion, it fails due to a empty commiter on a (closed) branch.
Is there a way to ignore this/map this on a different user with (for example) an authors file?

hg-fast-export/git-hg seems don't respect the order of a merge

In Git, usually, the first parent of a merge is the branch which other branches merged into.

I have tried cosmin's git-hg which is a wrapper around this script and abourget's git-hg-again both on mutt's hg repo, it seems that the later respects the order of a merge well, the former is a bit random. You can see from the screenshots below.

  • A merge history graph of mutt imported cosmin's your git-hg:

enter image description here

enter image description here

  • The actuall history graph plotted by hgk on mutt's hg repository:

enter image description here

As you can see from the above, the second graph by abourget's git-hg-again is very close to the original hgk graph and is actually reflecting the real workflow of the mutt.

This is also posted as an answer to this question.

Create versions

If you create versions, I can make a Homebrew formula for fast-export so that more people will use it.

git-fast-import fails with fatal: mark :137 not declared

At some point syncing/mirroring the hg-repo mentioned in #21 (comment) stopped with issue visible below. [edited to add a space between link and "stopped" to make the link work/frej]

The system uses
git version 2.7.3
and
Mercurial Distributed SCM (version 3.5.2)

I would appreciate if you could have a look at it and maybe have an idea for a solution.

Output of the sync-script:

Rufe von https://bitbucket.org/rndblnch/osx-presentation ab
Suche nach Änderungen
Keine Änderungen gefunden
Using last hg repository "../osx-presentation"
master: Exporting simple delta revision 138/146 with 0/1/0 added/changed/removed files
fatal: mark :137 not declared
fast-import: dumping crash report to .git/fast_import_crash_10250
Traceback (most recent call last):
  File "/home/git/fast-export/hg-fast-export.py", line 483, in <module>
    notes=options.notes,encoding=encoding,fn_encoding=fn_encoding))
  File "/home/git/fast-export/hg-fast-export.py", line 383, in hg2git
    sob,brmap,hgtags,encoding,fn_encoding)
  File "/home/git/fast-export/hg-fast-export.py", line 235, in export_commit
    export_file_contents(ctx,man,changed,hgtags,fn_encoding)
  File "/home/git/fast-export/hg-fast-export.py", line 141, in export_file_contents
    wr(d)
  File "/home/git/fast-export/hg-fast-export.py", line 37, in wr
    wr_no_nl(msg)
  File "/home/git/fast-export/hg-fast-export.py", line 34, in wr_no_nl
    sys.stdout.write(msg)
IOError: [Errno 32] Broken pipe
Everything up-to-date
Everything up-to-date

Contents of the mentioned crash report:

fast-import crash report:
    fast-import process: 10250
    parent process     : 10249
    at Sat Apr 2 18:58:15 2016

fatal: mark :137 not declared

Most Recent Commands Before Crash
---------------------------------
  commit refs/heads/master
  mark :138
  author Renaud Blanch <[email protected]> 1454618373 +0100
  committer Renaud Blanch <[email protected]> 1454618373 +0100
  data 27
* from :137

Active Branch LRU
-----------------
    active_branches = 0 cur, 5 max

  pos  clock name

Inactive Branches

refs/heads/master:
status : dirty
tip commit : 0000000000000000000000000000000000000000
old tree : 0000000000000000000000000000000000000000
cur tree : 0000000000000000000000000000000000000000
commit clock: 0
last pack :

Marks

exported to /home/git/mirror/osx-presentation.git/.git/hg2git-marks.tmp


END OF CRASH REPORT

Support Windows Better

It seems the shell script is lightweight and just invokes the python script. It'd be nice if there was a batch script on Windows to do this, or simply move the work done by the shell script into the python script instead.

AttributeError: 'module' object has no attribute 'CalledProcessError

[ksearle@dev:~/src/scs] ~/src/fast-export/hg-fast-export.sh -r /home/ksearle/scs
Traceback (most recent call last):
  File "/home/ksearle/src/fast-export/hg-fast-export.py", line 504, in ?
    notes=options.notes,encoding=encoding,fn_encoding=fn_encoding))
  File "/home/ksearle/src/fast-export/hg-fast-export.py", line 382, in hg2git
    if not verify_heads(ui,repo,heads_cache,force,branchesmap):
  File "/home/ksearle/src/fast-export/hg-fast-export.py", line 341, in verify_heads
    sha1=get_git_sha1(sanitized_name)
  File "/home/ksearle/src/fast-export/hg2git.py", line 114, in get_git_sha1
    except subprocess.CalledProcessError:
AttributeError: 'module' object has no attribute 'CalledProcessError'
git-fast-import statistics:
---------------------------------------------------------------------
Alloc'd objects:       5000
Total objects:            0 (         0 duplicates                  )
      blobs  :            0 (         0 duplicates          0 deltas of          0 attempts)
      trees  :            0 (         0 duplicates          0 deltas of          0 attempts)
      commits:            0 (         0 duplicates          0 deltas of          0 attempts)
      tags   :            0 (         0 duplicates          0 deltas of          0 attempts)
Total branches:           0 (         0 loads     )
      marks:           1024 (         0 unique    )
      atoms:              0
Memory total:          2282 KiB
       pools:          2048 KiB
     objects:           234 KiB
---------------------------------------------------------------------
pack_report: getpagesize()            =       4096
pack_report: core.packedGitWindowSize = 1073741824
pack_report: core.packedGitLimit      = 8589934592
pack_report: pack_used_ctr            =          0
pack_report: pack_mmap_calls          =          0
pack_report: pack_open_windows        =          0 /          0
pack_report: pack_mapped              =          0 /          0
---------------------------------------------------------------------
[ksearle@dev:~/src/scs] cat /etc/redhat-release
CentOS release 5.8 (Final)
[ksearle@dev:~/src/scs] hg --version
Mercurial Distributed SCM (version 2.2.2)
[ksearle@dev:~/src/scs] git --version
git version 1.8.2.1
[ksearle@dev:~/src/scs] python -V
Python 2.4.3

File "../fast-export/hg-fast-export.py", line 143, in sanitize_name

Warning: sanitized tag [uploaded 2.0.0 for linux] to [uploaded_2.0.0_for_linux]
Exporting tag [uploaded_2.0.0_for_linux] at [hg r174] [git :175]
Traceback (most recent call last):
File "../fast-export/hg-fast-export.py", line 384, in
options.statusfile,authors=a,sob=options.sob,force=options.force))
File "../fast-export/hg-fast-export.py", line 325, in hg2git
c=export_tags(ui,repo,old_marks,mapping_cache,c,authors)
File "../fast-export/hg-fast-export.py", line 219, in export_tags
tag=sanitize_name(tag,"tag")
File "../fast-export/hg-fast-export.py", line 143, in sanitize_name
if n[-1] == '/': n=n[:-1]+'_'
IndexError: string index out of range

"ImportError: No module named mercurial" on OSX

I had to set the the PYTHONPATH explicitly: export PYTHONPATH="/usr/local/lib/python2.7/site-packages:$PYTHONPATH".

I see two options for this problem:
Either documenting this in the README, or having the script figuring out the correct path. Mercurial itself does it like this:

libdir = '../lib/python2.7/site-packages/'

if libdir != '@' 'LIBDIR' '@':
    if not os.path.isabs(libdir):
        libdir = os.path.join(os.path.dirname(os.path.realpath(__file__)),
                              libdir)
        libdir = os.path.abspath(libdir)
    sys.path.insert(0, libdir)

It detects the path to the executable, and tries to find the according libpath.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.