Merge lp:~jelmer/bzr-fastimport/remove-exporters into lp:bzr-fastimport

Proposed by Jelmer Vernooij
Status: Merged
Approved by: Martin Packman
Approved revision: 352
Merged at revision: 352
Proposed branch: lp:~jelmer/bzr-fastimport/remove-exporters
Merge into: lp:bzr-fastimport
Diff against target: 5423 lines (+20/-4960)
68 files modified
NEWS (+8/-0)
README.txt (+0/-4)
__init__.py (+1/-29)
cmds.py (+11/-234)
exporters/Makefile (+0/-15)
exporters/__init__.py (+0/-326)
exporters/darcs/.gitignore (+0/-3)
exporters/darcs/Makefile (+0/-55)
exporters/darcs/NEWS (+0/-26)
exporters/darcs/README (+0/-187)
exporters/darcs/TODO (+0/-8)
exporters/darcs/asciidoc.conf (+0/-21)
exporters/darcs/d2x (+0/-112)
exporters/darcs/d2x.txt (+0/-27)
exporters/darcs/darcs-fast-export (+0/-380)
exporters/darcs/darcs-fast-export.txt (+0/-68)
exporters/darcs/darcs-fast-import (+0/-375)
exporters/darcs/darcs-fast-import.txt (+0/-57)
exporters/darcs/git-darcs (+0/-279)
exporters/darcs/git-darcs.txt (+0/-92)
exporters/darcs/t/Makefile (+0/-9)
exporters/darcs/t/bench-results/Makefile (+0/-5)
exporters/darcs/t/bench-results/bench-results.gnu (+0/-6)
exporters/darcs/t/bench-results/bench-results.py (+0/-23)
exporters/darcs/t/bench-tailor.sh (+0/-59)
exporters/darcs/t/bench.sh (+0/-38)
exporters/darcs/t/lib-httpd.sh (+0/-67)
exporters/darcs/t/lib.sh (+0/-337)
exporters/darcs/t/test-bzr.sh (+0/-16)
exporters/darcs/t/test-git-d2x.sh (+0/-19)
exporters/darcs/t/test-git-incremental.sh (+0/-24)
exporters/darcs/t/test-git-progress.sh (+0/-18)
exporters/darcs/t/test-git.sh (+0/-18)
exporters/darcs/t/test-hg-d2x.sh (+0/-12)
exporters/darcs/t/test-hg.sh (+0/-16)
exporters/darcs/t/test2-bzr-d2x.sh (+0/-19)
exporters/darcs/t/test2-bzr-incremental.sh (+0/-21)
exporters/darcs/t/test2-git-funny-tagname.sh (+0/-25)
exporters/darcs/t/test2-git-http.sh (+0/-22)
exporters/darcs/t/test2-git-incremental-specworkdir.sh (+0/-22)
exporters/darcs/t/test2-git-incremental.sh (+0/-21)
exporters/darcs/t/test2-git.sh (+0/-18)
exporters/darcs/t/testimport-bzr-x2d.sh (+0/-15)
exporters/darcs/t/testimport-bzr.sh (+0/-15)
exporters/darcs/t/testimport-copy.sh (+0/-26)
exporters/darcs/t/testimport-darcs.sh (+0/-17)
exporters/darcs/t/testimport-deleteall.sh (+0/-31)
exporters/darcs/t/testimport-git-incremental.sh (+0/-16)
exporters/darcs/t/testimport-git-twoway-gd.sh (+0/-34)
exporters/darcs/t/testimport-git-twoway.sh (+0/-30)
exporters/darcs/t/testimport-git-x2d.sh (+0/-15)
exporters/darcs/t/testimport-git.sh (+0/-15)
exporters/darcs/t/testimport-gitsymlink.sh (+0/-45)
exporters/darcs/t/testimport-hg-x2d.sh (+0/-15)
exporters/darcs/t/testimport-hg.sh (+0/-15)
exporters/darcs/t/testimport-rename.sh (+0/-25)
exporters/darcs/x2d (+0/-125)
exporters/darcs/x2d.txt (+0/-28)
exporters/hg-fast-export.README (+0/-54)
exporters/hg-fast-export.py (+0/-442)
exporters/hg-fast-export.sh (+0/-100)
exporters/hg2git.py (+0/-112)
exporters/svn-archive.c (+0/-240)
exporters/svn-fast-export.README (+0/-12)
exporters/svn-fast-export.c (+0/-187)
exporters/svn-fast-export.py (+0/-225)
info.py (+0/-7)
setup.py (+0/-1)
To merge this branch: bzr merge lp:~jelmer/bzr-fastimport/remove-exporters
Reviewer Review Type Date Requested Status
Martin Packman (community) Approve
Review via email: mp+94998@code.launchpad.net

Description of the change

Remove the custom exporters from bzr-fastimport.

This is code that is imported from elsewhere which we're not really
maintaining. There are bzr command wrappers for them, but these wrappers only
expose a limited amount of the functionality of the actual exporters and don't
really add much value (other than a consistent, but fairly unuseful interface).

I'd really rather just point people at the actual exporters rather than
having to maintain a copy of them inside of bzr-fastimport.

To post a comment you must log in.
352. By Jelmer Vernooij

remove reference to exporter copyrights.

Revision history for this message
Martin Packman (gz) wrote :

Reasoning for removing these makes sense to me. One thing I'd like to see is web links to exporters in the documentation here. Links do bitrot like code but generally at a slower rate and it's easier to fix them. Giving people a poke in the right direction to find the exporter they need rather than just assuming "widely available" means everyone will know how to google for the right thing would help.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'NEWS'
--- NEWS 2012-02-28 14:00:56 +0000
+++ NEWS 2012-02-28 16:42:20 +0000
@@ -6,6 +6,14 @@
66
70.13 UNRELEASED70.13 UNRELEASED
88
9Changes
10-------
11
12* bzr-fastimport no longer ships exporters for various other version
13 control systems. The versions of these exporters shipped with bzr-fastimport
14 have been outdated for some time. Better and more recent exporters
15 are widely available.
16
9Compatibility17Compatibility
10-------------18-------------
1119
1220
=== modified file 'README.txt'
--- README.txt 2010-10-15 18:18:53 +0000
+++ README.txt 2012-02-28 16:42:20 +0000
@@ -38,14 +38,10 @@
38To view the documentation after installation:38To view the documentation after installation:
3939
40 bzr help fastimport40 bzr help fastimport
41
4241
43Licensing42Licensing
44---------43---------
4544
46For copyright and licensing details of the exporters, see the relevant
47files in the exporters/ directory.
48
49Otherwise this plugin is (C) Copyright Canonical Limited 2008 under the45Otherwise this plugin is (C) Copyright Canonical Limited 2008 under the
50GPL Version 2 or later. Please see the file COPYING.txt for the licence46GPL Version 2 or later. Please see the file COPYING.txt for the licence
51details.47details.
5248
=== modified file '__init__.py'
--- __init__.py 2011-12-18 04:07:47 +0000
+++ __init__.py 2012-02-28 16:42:20 +0000
@@ -24,12 +24,6 @@
2424
25The normal import recipe is::25The normal import recipe is::
2626
27 bzr fast-export-from-xxx SOURCE project.fi
28 bzr fast-import project.fi project.bzr
29
30If fast-export-from-xxx doesn't exist yet for the tool you're importing
31from, the alternative recipe is::
32
33 front-end > project.fi27 front-end > project.fi
34 bzr fast-import project.fi project.bzr28 bzr fast-import project.fi project.bzr
3529
@@ -41,22 +35,7 @@
41 bzr fast-import project.fi.gz project.bzr35 bzr fast-import project.fi.gz project.bzr
4236
43The list of known front-ends and their status is documented on37The list of known front-ends and their status is documented on
44http://bazaar-vcs.org/BzrFastImport/FrontEnds. The fast-export-from-xxx38http://bazaar-vcs.org/BzrFastImport/FrontEnds.
45commands provide simplified access to these so that the majority of users
46can generate a fast-import dump file without needing to study up on all
47the options - and the best combination of them to use - for the front-end
48relevant to them. In some cases, a fast-export-from-xxx wrapper will require
49that certain dependencies are installed so it checks for these before
50starting. A wrapper may also provide a limited set of options. See the
51online help for the individual commands for details::
52
53 bzr help fast-export-from-cvs
54 bzr help fast-export-from-darcs
55 bzr help fast-export-from-hg
56 bzr help fast-export-from-git
57 bzr help fast-export-from-mtn
58 bzr help fast-export-from-p4
59 bzr help fast-export-from-svn
6039
61Once a fast-import dump file is created, it can be imported into a40Once a fast-import dump file is created, it can be imported into a
62Bazaar repository using the fast-import command. If required, you can41Bazaar repository using the fast-import command. If required, you can
@@ -108,12 +87,5 @@
108 "fast_import_info",87 "fast_import_info",
109 "fast_import_query",88 "fast_import_query",
110 "fast_export",89 "fast_export",
111 "fast_export_from_cvs",
112 "fast_export_from_darcs",
113 "fast_export_from_hg",
114 "fast_export_from_git",
115 "fast_export_from_mtn",
116 "fast_export_from_p4",
117 "fast_export_from_svn"
118 ]:90 ]:
119 plugin_cmds.register_lazy("cmd_%s" % name, [], "bzrlib.plugins.fastimport.cmds")91 plugin_cmds.register_lazy("cmd_%s" % name, [], "bzrlib.plugins.fastimport.cmds")
12092
=== modified file 'cmds.py'
--- cmds.py 2012-02-28 16:16:13 +0000
+++ cmds.py 2012-02-28 16:42:20 +0000
@@ -72,16 +72,15 @@
72 bzr fast-import project.fi project.bzr72 bzr fast-import project.fi project.bzr
7373
74 Numerous commands are provided for generating a fast-import file74 Numerous commands are provided for generating a fast-import file
75 to use as input. These are named fast-export-from-xxx where xxx75 to use as input.
76 is one of cvs, darcs, git, hg, mtn, p4 or svn.
77 To specify standard input as the input stream, use a76 To specify standard input as the input stream, use a
78 source name of '-' (instead of project.fi). If the source name77 source name of '-' (instead of project.fi). If the source name
79 ends in '.gz', it is assumed to be compressed in gzip format.78 ends in '.gz', it is assumed to be compressed in gzip format.
80 79
81 project.bzr will be created if it doesn't exist. If it exists80 project.bzr will be created if it doesn't exist. If it exists
82 already, it should be empty or be an existing Bazaar repository81 already, it should be empty or be an existing Bazaar repository
83 or branch. If not specified, the current directory is assumed.82 or branch. If not specified, the current directory is assumed.
84 83
85 fast-import will intelligently select the format to use when84 fast-import will intelligently select the format to use when
86 creating a repository or branch. If you are running Bazaar 1.1785 creating a repository or branch. If you are running Bazaar 1.17
87 up to Bazaar 2.0, the default format for Bazaar 2.x ("2a") is used.86 up to Bazaar 2.0, the default format for Bazaar 2.x ("2a") is used.
@@ -200,27 +199,30 @@
200199
201 Import a Subversion repository into Bazaar::200 Import a Subversion repository into Bazaar::
202201
203 bzr fast-export-from-svn /svn/repo/path project.fi202 svn-fast-export /svn/repo/path > project.fi
204 bzr fast-import project.fi project.bzr203 bzr fast-import project.fi project.bzr
205204
206 Import a CVS repository into Bazaar::205 Import a CVS repository into Bazaar::
207206
208 bzr fast-export-from-cvs /cvs/repo/path project.fi207 cvs2git /cvs/repo/path > project.fi
209 bzr fast-import project.fi project.bzr208 bzr fast-import project.fi project.bzr
210209
211 Import a Git repository into Bazaar::210 Import a Git repository into Bazaar::
212211
213 bzr fast-export-from-git /git/repo/path project.fi212 cd /git/repo/path
213 git fast-export --all > project.fi
214 bzr fast-import project.fi project.bzr214 bzr fast-import project.fi project.bzr
215215
216 Import a Mercurial repository into Bazaar::216 Import a Mercurial repository into Bazaar::
217217
218 bzr fast-export-from-hg /hg/repo/path project.fi218 cd /hg/repo/path
219 hg fast-export > project.fi
219 bzr fast-import project.fi project.bzr220 bzr fast-import project.fi project.bzr
220221
221 Import a Darcs repository into Bazaar::222 Import a Darcs repository into Bazaar::
222223
223 bzr fast-export-from-darcs /darcs/repo/path project.fi224 cd /darcs/repo/path
225 darcs-fast-export > project.fi
224 bzr fast-import project.fi project.bzr226 bzr fast-import project.fi project.bzr
225 """227 """
226 hidden = False228 hidden = False
@@ -682,228 +684,3 @@
682 revision=revision, verbose=verbose, plain_format=plain,684 revision=revision, verbose=verbose, plain_format=plain,
683 rewrite_tags=rewrite_tag_names, baseline=baseline)685 rewrite_tags=rewrite_tag_names, baseline=baseline)
684 return exporter.run()686 return exporter.run()
685
686
687class cmd_fast_export_from_cvs(Command):
688 """Generate a fast-import file from a CVS repository.
689
690 Destination is a dump file, typically named xxx.fi where xxx is
691 the name of the project. If '-' is given, standard output is used.
692
693 cvs2svn 2.3 or later must be installed as its cvs2bzr script is used
694 under the covers to do the export.
695
696 The source must be the path on your filesystem to the part of the
697 repository you wish to convert. i.e. either that path or a parent
698 directory must contain a CVSROOT subdirectory. The path may point to
699 either the top of a repository or to a path within it. In the latter
700 case, only that project within the repository will be converted.
701
702 .. note::
703 Remote access to the repository is not sufficient - the path
704 must point into a copy of the repository itself. See
705 http://cvs2svn.tigris.org/faq.html#repoaccess for instructions
706 on how to clone a remote CVS repository locally.
707
708 By default, the trunk, branches and tags are all exported. If you
709 only want the trunk, use the `--trunk-only` option.
710
711 By default, filenames, log messages and author names are expected
712 to be encoded in ascii. Use the `--encoding` option to specify an
713 alternative. If multiple encodings are used, specify the option
714 multiple times. For a list of valid encoding names, see
715 http://docs.python.org/lib/standard-encodings.html.
716
717 Windows users need to install GNU sort and use the `--sort`
718 option to specify its location. GNU sort can be downloaded from
719 http://unxutils.sourceforge.net/.
720 """
721 hidden = False
722 _see_also = ['fast-import', 'fast-import-filter']
723 takes_args = ['source', 'destination']
724 takes_options = ['verbose',
725 Option('trunk-only',
726 help="Export just the trunk, ignoring tags and branches."
727 ),
728 ListOption('encoding', type=str, argname='CODEC',
729 help="Encoding used for filenames, commit messages "
730 "and author names if not ascii."
731 ),
732 Option('sort', type=str, argname='PATH',
733 help="GNU sort program location if not on the path."
734 ),
735 ]
736 encoding_type = 'exact'
737 def run(self, source, destination, verbose=False, trunk_only=False,
738 encoding=None, sort=None):
739 load_fastimport()
740 from bzrlib.plugins.fastimport.exporters import fast_export_from
741 custom = []
742 if trunk_only:
743 custom.append("--trunk-only")
744 if encoding:
745 for enc in encoding:
746 custom.extend(['--encoding', enc])
747 if sort:
748 custom.extend(['--sort', sort])
749 fast_export_from(source, destination, 'cvs', verbose, custom)
750
751
752class cmd_fast_export_from_darcs(Command):
753 """Generate a fast-import file from a Darcs repository.
754
755 Destination is a dump file, typically named xxx.fi where xxx is
756 the name of the project. If '-' is given, standard output is used.
757
758 Darcs 2.2 or later must be installed as various subcommands are
759 used to access the source repository. The source may be a network
760 URL but using a local URL is recommended for performance reasons.
761 """
762 hidden = False
763 _see_also = ['fast-import', 'fast-import-filter']
764 takes_args = ['source', 'destination']
765 takes_options = ['verbose',
766 Option('encoding', type=str, argname='CODEC',
767 help="Encoding used for commit messages if not utf-8."
768 ),
769 ]
770 encoding_type = 'exact'
771 def run(self, source, destination, verbose=False, encoding=None):
772 from bzrlib.plugins.fastimport.exporters import fast_export_from
773 custom = None
774 if encoding is not None:
775 custom = ['--encoding', encoding]
776 fast_export_from(source, destination, 'darcs', verbose, custom)
777
778
779class cmd_fast_export_from_hg(Command):
780 """Generate a fast-import file from a Mercurial repository.
781
782 Destination is a dump file, typically named xxx.fi where xxx is
783 the name of the project. If '-' is given, standard output is used.
784
785 Mercurial 1.2 or later must be installed as its libraries are used
786 to access the source repository. Given the APIs currently used,
787 the source repository must be a local file, not a network URL.
788 """
789 hidden = False
790 _see_also = ['fast-import', 'fast-import-filter']
791 takes_args = ['source', 'destination']
792 takes_options = ['verbose']
793 encoding_type = 'exact'
794 def run(self, source, destination, verbose=False):
795 load_fastimport()
796 from bzrlib.plugins.fastimport.exporters import fast_export_from
797 fast_export_from(source, destination, 'hg', verbose)
798
799
800class cmd_fast_export_from_git(Command):
801 """Generate a fast-import file from a Git repository.
802
803 Destination is a dump file, typically named xxx.fi where xxx is
804 the name of the project. If '-' is given, standard output is used.
805
806 Git 1.6 or later must be installed as the git fast-export
807 subcommand is used under the covers to generate the stream.
808 The source must be a local directory.
809
810 .. note::
811
812 Earlier versions of Git may also work fine but are
813 likely to receive less active support if problems arise.
814 """
815 hidden = False
816 _see_also = ['fast-import', 'fast-import-filter']
817 takes_args = ['source', 'destination']
818 takes_options = ['verbose']
819 encoding_type = 'exact'
820 def run(self, source, destination, verbose=False):
821 load_fastimport()
822 from bzrlib.plugins.fastimport.exporters import fast_export_from
823 fast_export_from(source, destination, 'git', verbose)
824
825
826class cmd_fast_export_from_mtn(Command):
827 """Generate a fast-import file from a Monotone repository.
828
829 Destination is a dump file, typically named xxx.fi where xxx is
830 the name of the project. If '-' is given, standard output is used.
831
832 Monotone 0.43 or later must be installed as the mtn git_export
833 subcommand is used under the covers to generate the stream.
834 The source must be a local directory.
835 """
836 hidden = False
837 _see_also = ['fast-import', 'fast-import-filter']
838 takes_args = ['source', 'destination']
839 takes_options = ['verbose']
840 encoding_type = 'exact'
841 def run(self, source, destination, verbose=False):
842 load_fastimport()
843 from bzrlib.plugins.fastimport.exporters import fast_export_from
844 fast_export_from(source, destination, 'mtn', verbose)
845
846
847class cmd_fast_export_from_p4(Command):
848 """Generate a fast-import file from a Perforce repository.
849
850 Source is a Perforce depot path, e.g., //depot/project
851
852 Destination is a dump file, typically named xxx.fi where xxx is
853 the name of the project. If '-' is given, standard output is used.
854
855 bzrp4 must be installed as its p4_fast_export.py module is used under
856 the covers to do the export. bzrp4 can be downloaded from
857 https://launchpad.net/bzrp4/.
858
859 The P4PORT environment variable must be set, and you must be logged
860 into the Perforce server.
861
862 By default, only the HEAD changelist is exported. To export all
863 changelists, append '@all' to the source. To export a revision range,
864 append a comma-delimited pair of changelist numbers to the source,
865 e.g., '100,200'.
866 """
867 hidden = False
868 _see_also = ['fast-import', 'fast-import-filter']
869 takes_args = ['source', 'destination']
870 takes_options = []
871 encoding_type = 'exact'
872 def run(self, source, destination, verbose=False):
873 load_fastimport()
874 from bzrlib.plugins.fastimport.exporters import fast_export_from
875 custom = []
876 fast_export_from(source, destination, 'p4', verbose, custom)
877
878
879class cmd_fast_export_from_svn(Command):
880 """Generate a fast-import file from a Subversion repository.
881
882 Destination is a dump file, typically named xxx.fi where xxx is
883 the name of the project. If '-' is given, standard output is used.
884
885 Python-Subversion (Python bindings to the Subversion APIs)
886 1.4 or later must be installed as this library is used to
887 access the source repository. The source may be a network URL
888 but using a local URL is recommended for performance reasons.
889 """
890 hidden = False
891 _see_also = ['fast-import', 'fast-import-filter']
892 takes_args = ['source', 'destination']
893 takes_options = ['verbose',
894 Option('trunk-path', type=str, argname="STR",
895 help="Path in repo to /trunk.\n"
896 "May be `regex:/cvs/(trunk)/proj1/(.*)` in "
897 "which case the first group is used as the "
898 "branch name and the second group is used "
899 "to match files.",
900 ),
901 ]
902 encoding_type = 'exact'
903 def run(self, source, destination, verbose=False, trunk_path=None):
904 load_fastimport()
905 from bzrlib.plugins.fastimport.exporters import fast_export_from
906 custom = []
907 if trunk_path is not None:
908 custom.extend(['--trunk-path', trunk_path])
909 fast_export_from(source, destination, 'svn', verbose, custom)
910687
=== removed directory 'exporters'
=== removed file 'exporters/Makefile'
--- exporters/Makefile 2009-10-02 19:01:37 +0000
+++ exporters/Makefile 1970-01-01 00:00:00 +0000
@@ -1,15 +0,0 @@
1SVN ?= /usr
2CFLAGS += -I${SVN}/include/subversion-1 -pipe -O2 -std=c99
3CFLAGS += `pkg-config --cflags apr-1`
4LDFLAGS += -L${SVN}/lib -lsvn_fs-1 -lsvn_repos-1
5LDFLAGS += `pkg-config --libs apr-1`
6
7all: svn-fast-export svn-archive
8
9svn-fast-export: svn-fast-export.c
10svn-archive: svn-archive.c
11
12.PHONY: clean
13
14clean:
15 rm -rf svn-fast-export svn-archive
160
=== removed file 'exporters/__init__.py'
--- exporters/__init__.py 2011-10-06 00:11:52 +0000
+++ exporters/__init__.py 1970-01-01 00:00:00 +0000
@@ -1,326 +0,0 @@
1# Copyright (C) 2009 Canonical Ltd
2#
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program. If not, see <http://www.gnu.org/licenses/>.
15
16"""Simplified and unified access to the various xxx-fast-export tools."""
17
18
19import gzip, os, subprocess, sys
20
21from bzrlib import errors
22from bzrlib.trace import note, warning
23
24
25class MissingDependency(Exception):
26
27 def __init__(self, tool, minimum_version, missing):
28 self.tool = tool
29 self.minimum_version = minimum_version
30 self.missing = missing
31
32 def get_message(self):
33 return "%s missing. Please install %s %s or later and try again." % \
34 (self.missing, self.tool, self.minimum_version)
35
36
37class _Exporter(object):
38
39 def check_install(self, tool_name, minimum_version, required_commands=None,
40 required_libraries=None):
41 """Check dependencies are correctly installed.
42
43 :param tool_name: name of the tool
44 :param minimum_version: minimum version required
45 :param required_commands: list of commands that must be on the path
46 :param required_libraries: list of Python libraries that must be
47 available
48 :raises MissingDependency: if a required dependency is not found
49 """
50 self.tool_name = tool_name
51 self.minimum_version = minimum_version
52 if required_commands:
53 for cmd in required_commands:
54 self._check_cmd_available(cmd)
55 if required_libraries:
56 for lib in required_libraries:
57 self._check_lib_available(lib)
58
59 def _check_cmd_available(self, cmd):
60 try:
61 if isinstance(cmd, str):
62 args = [cmd]
63 else:
64 args = cmd
65 retcode = subprocess.call(args, stdout=subprocess.PIPE,
66 stderr=subprocess.PIPE)
67 except OSError:
68 raise MissingDependency(self.tool_name, self.minimum_version, cmd)
69
70 def _check_lib_available(self, lib):
71 try:
72 __import__(lib)
73 except ImportError:
74 raise MissingDependency(self.tool_name, self.minimum_version, lib)
75
76 def generate(self, source, destination, verbose=False, custom=None):
77 """Generate a fast import stream.
78
79 :param source: the source filename or URL
80 :param destination: filename or '-' for standard output
81 :param verbose: if True, output additional diagnostics
82 :param custom: a list of custom options to be added to the
83 command line of the underlying scripts used. If an option
84 and its argument are to be separated by a space, pass them
85 as consecutive items.
86 """
87 raise NotImplementedError(self.generate)
88
89 def get_output_info(self, dest):
90 """Get the output streams/filenames given a destination filename.
91
92 :return: outf, basename, marks where
93 outf is a file-like object for storing the output,
94 basename is the name without the .fi and .gz prefixes
95 marks is the name of the marks file to use, if any
96 """
97 if dest == '-':
98 return sys.stdout, None, None
99 else:
100 #if dest.endswith('.gz'):
101 # outf = gzip.open(dest, 'wb')
102 # base = dest[:-3]
103 #else:
104 outf = open(dest, 'w')
105 base = dest
106 if base.endswith(".fi"):
107 base = dest[:-3]
108 marks = "%s.marks" % (base,)
109 return outf, base, marks
110
111 def execute(self, args, outf, cwd=None):
112 """Execute a command, capture the output and close files.
113
114 :param args: list of arguments making up the command
115 :param outf: a file-like object for storing the output,
116 :param cwd: current working directory to use
117 :return: the return code
118 """
119 if cwd is not None:
120 note("Executing %s in directory %s ..." % (" ".join(args), cwd))
121 else:
122 note("Executing %s ..." % (" ".join(args),))
123 try:
124 p = subprocess.Popen(args, stdout=outf, cwd=cwd)
125 p.wait()
126 finally:
127 if outf != sys.stdout:
128 outf.close()
129 return p.returncode
130
131 def report_results(self, retcode, destination):
132 """Report whether the export succeeded or otherwise."""
133 if retcode == 0:
134 note("Export to %s completed successfully." % (destination,))
135 else:
136 warning("Export to %s exited with error code %d."
137 % (destination, retcode))
138
139 def execute_exporter_script(self, args, outf):
140 """Execute an exporter script, capturing the output.
141
142 The script must be a Python script under the exporters directory.
143
144 :param args: list of arguments making up the script, the first of
145 which is the script name relative to the exporters directory.
146 :param outf: a file-like object for storing the output,
147 :return: the return code
148 """
149 # Note: currently assume Python is on the path. We could work around
150 # this later (for Windows users say) by packaging the scripts as Python
151 # modules and calling their internals directly.
152 exporters_dir = os.path.dirname(__file__)
153 script_abspath = os.path.join(exporters_dir, args[0])
154 actual_args = ['python', script_abspath] + args[1:]
155 return self.execute(actual_args, outf)
156
157
158class CvsExporter(_Exporter):
159
160 def __init__(self):
161 self.check_install('cvs2svn', '2.30', ['cvs2bzr'])
162 self.check_install('CVS', '1.11', ['cvs'])
163
164 def generate(self, source, destination, verbose=False, custom=None):
165 """Generate a fast import stream. See _Exporter.generate() for details."""
166 # TODO: pass a custom cvs2bzr-default.options file as soon as
167 # cvs2bzr handles --options along with others.
168 args = ["cvs2bzr", "--dumpfile", destination]
169 outf, base, marks = self.get_output_info(destination)
170 # Marks aren't supported by cvs2bzr so no need to set that option
171 if custom:
172 args.extend(custom)
173 args.append(source)
174 retcode = self.execute(args, outf)
175 self.report_results(retcode, destination)
176
177
178class DarcsExporter(_Exporter):
179
180 def __init__(self):
181 self.check_install('Darcs', '2.2', [('darcs', '--version')])
182
183 def generate(self, source, destination, verbose=False, custom=None):
184 """Generate a fast import stream. See _Exporter.generate() for details."""
185 args = ["darcs/darcs-fast-export"]
186 outf, base, marks = self.get_output_info(destination)
187 if marks:
188 args.append('--export-marks=%s' % marks)
189 if custom:
190 args.extend(custom)
191 args.append(source)
192 retcode = self.execute_exporter_script(args, outf)
193 self.report_results(retcode, destination)
194
195
196class MercurialExporter(_Exporter):
197
198 def __init__(self):
199 self.check_install('Mercurial', '1.2', None, ['mercurial'])
200
201 def generate(self, source, destination, verbose=False, custom=None):
202 """Generate a fast import stream. See _Exporter.generate() for details."""
203 # XXX: Should we add --force here?
204 args = ["hg-fast-export.py", "-r", source, "-s"]
205 outf, base, marks = self.get_output_info(destination)
206 if base:
207 args.append('--marks=%s.marks' % (base,))
208 args.append('--mapping=%s.mapping' % (base,))
209 args.append('--heads=%s.heads' % (base,))
210 args.append('--status=%s.status' % (base,))
211 if custom:
212 args.extend(custom)
213 retcode = self.execute_exporter_script(args, outf)
214 self.report_results(retcode, destination)
215
216
217class GitExporter(_Exporter):
218
219 def __init__(self):
220 self.cmd_name = "git"
221 if sys.platform == 'win32':
222 self.cmd_name = "git.cmd"
223 self.check_install('Git', '1.6', [self.cmd_name])
224
225 def generate(self, source, destination, verbose=False, custom=None):
226 """Generate a fast import stream. See _Exporter.generate() for details."""
227 args = [self.cmd_name, "fast-export", "--all", "--signed-tags=warn"]
228 outf, base, marks = self.get_output_info(destination)
229 if marks:
230 marks = os.path.abspath(marks)
231 # Note: we don't pass import-marks because that creates
232 # a stream of incremental changes, not the full thing.
233 # We may support incremental output later ...
234 #if os.path.exists(marks):
235 # args.append('--import-marks=%s' % marks)
236 args.append('--export-marks=%s' % marks)
237 if custom:
238 args.extend(custom)
239 retcode = self.execute(args, outf, cwd=source)
240 self.report_results(retcode, destination)
241
242
243class MonotoneExporter(_Exporter):
244
245 def __init__(self):
246 self.check_install('Monotone', '0.43', ['mtn'])
247
248 def generate(self, source, destination, verbose=False, custom=None):
249 """Generate a fast import stream. See _Exporter.generate() for details."""
250 args = ["mtn", "git_export"]
251 outf, base, marks = self.get_output_info(destination)
252 if marks:
253 marks = os.path.abspath(marks)
254 if os.path.exists(marks):
255 args.append('--import-marks=%s' % marks)
256 args.append('--export-marks=%s' % marks)
257 if custom:
258 args.extend(custom)
259 retcode = self.execute(args, outf, cwd=source)
260 self.report_results(retcode, destination)
261
262
263class PerforceExporter(_Exporter):
264
265 def __init__(self):
266 self.check_install('p4', '2009.1', ['p4'])
267 self.check_install('Perforce Python API', '2009.1', None, ['P4'])
268 self.check_install('bzrp4', '', None, ['bzrlib.plugins.bzrp4'])
269
270 def generate(self, source, destination, verbose=False, custom=None):
271 """Generate a fast import stream. See _Exporter.generate() for details."""
272 from bzrlib.plugins.bzrp4 import p4_fast_export
273 outf, base, marks = self.get_output_info(destination)
274 # Marks aren't supported by p4_fast_export so no need to set that
275 # option
276 original_stdout = sys.stdout
277 sys.stdout = outf
278 try:
279 retcode = p4_fast_export.main([source])
280 finally:
281 sys.stdout = original_stdout
282 self.report_results(retcode, destination)
283
284
285class SubversionExporter(_Exporter):
286
287 def __init__(self):
288 self.check_install('Python Subversion', '1.4', None,
289 ['svn.fs', 'svn.core', 'svn.repos'])
290
291 def generate(self, source, destination, verbose=False, custom=None):
292 """Generate a fast import stream. See _Exporter.generate() for details."""
293 args = ["svn-fast-export.py"]
294 outf, base, marks = self.get_output_info(destination)
295 # Marks aren't supported by svn-fast-export so no need to set that option
296 if custom:
297 args.extend(custom)
298 args.append(source)
299 retcode = self.execute_exporter_script(args, outf)
300 self.report_results(retcode, destination)
301
302
303def fast_export_from(source, destination, tool, verbose=False, custom=None):
304 # Get the exporter
305 if tool == 'cvs':
306 factory = CvsExporter
307 elif tool == 'darcs':
308 factory = DarcsExporter
309 elif tool == 'hg':
310 factory = MercurialExporter
311 elif tool == 'git':
312 factory = GitExporter
313 elif tool == 'mtn':
314 factory = MonotoneExporter
315 elif tool == 'p4':
316 factory = PerforceExporter
317 elif tool == 'svn':
318 factory = SubversionExporter
319 try:
320 exporter = factory()
321 except MissingDependency, ex:
322 raise errors.BzrError(ex.get_message())
323
324 # Do the export
325 exporter.generate(source, destination, verbose=verbose,
326 custom=custom)
3270
=== removed directory 'exporters/darcs'
=== removed file 'exporters/darcs/.gitignore'
--- exporters/darcs/.gitignore 2008-10-19 12:51:00 +0000
+++ exporters/darcs/.gitignore 1970-01-01 00:00:00 +0000
@@ -1,3 +0,0 @@
1Changelog
2HEADER.html
3.htaccess
40
=== removed file 'exporters/darcs/Makefile'
--- exporters/darcs/Makefile 2009-06-25 21:47:09 +0000
+++ exporters/darcs/Makefile 1970-01-01 00:00:00 +0000
@@ -1,55 +0,0 @@
1VERSION = 0.9
2DATE := $(shell date +%Y-%m-%d)
3
4INSTALL = /usr/bin/install -c
5DESTDIR =
6prefix = /usr
7bindir = $(prefix)/bin
8mandir = $(prefix)/share/man/man1
9
10MAN_TXT = $(wildcard *.txt)
11MAN_HTML=$(patsubst %.txt,%.html,$(MAN_TXT))
12MAN=$(patsubst %.txt,%.1,$(MAN_TXT))
13
14PROGRAMS = darcs-fast-export darcs-fast-import d2x x2d git-darcs
15
16all: man
17
18install: all
19 $(INSTALL) -d $(DESTDIR)$(bindir)
20 $(INSTALL) -d $(DESTDIR)$(mandir)
21 $(INSTALL) -m755 $(PROGRAMS) $(DESTDIR)$(bindir)
22 $(INSTALL) -m644 *.1 $(DESTDIR)$(mandir)
23
24doc: HEADER.html Changelog html
25
26HEADER.html: README Makefile
27 asciidoc -a toc -a numbered -a sectids -o HEADER.html README
28
29Changelog: .git/refs/heads/master
30 git log >Changelog
31
32%.html: %.txt
33 asciidoc $^
34
35%.1: %.txt asciidoc.conf
36 a2x --asciidoc-opts="-f asciidoc.conf" \
37 -a dfe_version=$(VERSION) -a dfe_date=$(DATE) -f manpage $<
38
39man: $(MAN)
40
41html: $(MAN_HTML)
42
43dist:
44 git archive --format=tar --prefix=darcs-fast-export-$(VERSION)/ $(VERSION) > darcs-fast-export-$(VERSION).tar
45 mkdir -p darcs-fast-export-$(VERSION)
46 git log > darcs-fast-export-$(VERSION)/Changelog
47 tar rf darcs-fast-export-$(VERSION).tar darcs-fast-export-$(VERSION)/Changelog
48 rm -rf darcs-fast-export-$(VERSION)
49 gzip -f -9 darcs-fast-export-$(VERSION).tar
50
51release:
52 git tag -l |grep -q $(VERSION) || dg tag $(VERSION)
53 $(MAKE) dist
54 gpg --comment "See http://vmiklos.hu/gpg/ for info" \
55 -ba darcs-fast-export-$(VERSION).tar.gz
560
=== removed file 'exporters/darcs/NEWS'
--- exporters/darcs/NEWS 2009-06-25 21:47:09 +0000
+++ exporters/darcs/NEWS 1970-01-01 00:00:00 +0000
@@ -1,26 +0,0 @@
1VERSION DESCRIPTION
2-----------------------------------------------------------------------------
30.9 - fix handling of accents in tag names
4 - warning fixes for Python-2.6
5 - git-darcs: the add subcommand can now remember d-f-e
6 options
7 - git-darcs: new list, find-darcs and find-git subcommands
80.8 - revert the "not exporting unchanged files multiple
9 times" optimization, it causes corrupted results in some
10 cases.
110.7 - new darcs-fast-export option: --progress
12 - massive speedup in darcs-fast-export due to not
13 exporting unchanged files multiple times and reading
14 patches directly
150.6 - add a new darcs-fast-import script, allowing two-way sync
16 - new darcs-fast-export option: --git-branch
17 - add a new git-darcs script, making two-way sync easy
180.5 - new --help, --encoding, --authors-file, --working and
19 --logfile options
20 - add "hashed" support (see darcs init -h)
21 - add incremental conversion support for darcs1 as well
22 - add d2x wrapper script
230.4 - add incremental conversion support
240.3 - add darcs2 support
250.2 - add bzr and hg support
260.1 - initial short and fast version, supporting darcs1->git
270
=== removed file 'exporters/darcs/README'
--- exporters/darcs/README 2009-09-09 01:12:40 +0000
+++ exporters/darcs/README 1970-01-01 00:00:00 +0000
@@ -1,187 +0,0 @@
1= darcs backend for fast data importers
2Miklos Vajna <vmiklos-at-frugalware-dot-org>
3
4== Purpose and Features
5
6darcs-fast-export is a tool to dump a http://darcs.net/[darcs]
7repository in a format understood by "fast-importers" such as
8http://git.or.cz/[git]
9http://www.kernel.org/pub/software/scm/git/docs/git-fast-import.html[fast-import].
10It exhibits the following _features:_
11
12Fast::
13 darcs-fast-export provides a fast darcs backend for fast-import.
14 See link:t/bench-results/[here] for exact details.
15
16Correct::
17 darcs-fast-export produces correct results in any extreme cases.
18 It has been tested with a collection of large darcs repos (called
19 http://code.haskell.org/darcs/big-zoo/[big-zoo]). And several testcases
20 under the `t/` directory.
21
22Independent::
23 Ideally it should work with any fast importer, but actually it has been
24 tested with git fast-import, bzr fast-import and hg fastimport. (These
25 are the three fast-import implementations available ATM.)
26
27Formats::
28 It supports the 'darcs-2', 'hashed', and 'old-fashioned-inventory' darcs
29 repository formats.
30
31Incremental conversions::
32 It supports the usual `--export-marks` / `--import-marks` switches to
33 allow incremental conversion.
34
35Wrapper scripts::
36 A wrapper script called `d2x` is available if you find typing
37 `--export-marks` / `--import-marks` all the time boring. A similar one
38 is also provided for the other direction, called `x2d`. Finally, if you
39 want to work on darcs repos with git, you can use the `git-darcs`
40 wrapper.
41
42Author mappings::
43 Supports `--authors-file` option like Git's SVN adaptor, for DARCS
44 repositories that originated in CVS or SVN.
45
46Import script::
47 The pair of `darcs-fast-export`, `darcs-fast-import` is also
48 included in this repo. It has been tested with the fast-expoters of Git,
49 Hg, Bzr and - of course - Darcs itself.
50
51Two-way sync::
52 Using `darcs-fast-export` / `darcs-fast-import`, it is possible to
53 convert a darcs repo to an other VCS, work there, then convert your work
54 back to Darcs (or vica versa). This has been tested with "darcs -> git;
55 hack hack; git -> darcs".
56
57== Usage
58
59See the manpages:
60
61* link:darcs-fast-export.html[darcs-fast-export]
62* link:darcs-fast-import.html[darcs-fast-import]
63* link:d2x.html[d2x]
64* link:x2d.html[x2d]
65* link:git-darcs.html[git-darcs]
66
67=== Example
68
69Assuming that `test/` is a darcs repo, you could do this:
70----
71$ mkdir test.git
72$ cd test.git
73$ git --bare init
74$ cd ..
75$ darcs-fast-export test |(cd test.git; git fast-import)
76----
77
78For more examples (especially for bzr and hg), see the `t/` directory.
79
80== Download
81
82Using git:
83----
84$ git clone git://vmiklos.hu/darcs-fast-export
85----
86
87== Status
88
89In general, darcs-fast-export should work fine. darcs-fast-import has
90known problems with tags - other than that it should be okay. git-darcs
91should work properly as long as you are not paying too much attention to
92the imported tags (newly created tags won't be pushed back).
93
94darcs-fast-export has been tested with the following versions:
95
96Darcs version (see http://bugs.darcs.net/issue844[this bug] on why do
97you need such a new version):
98----
99$ darcs --version
1002.2.0 (release)
101----
102
103Git version:
104----
105$ git --version
106git version 1.6.0.2
107----
108
109Bzr versions:
110----
111$ bzr version
112Bazaar (bzr) 1.12
113$ (cd ~/bzr/fastimport; bzr log --limit 1|grep revno)
114revno: 181
115----
116
117Yes, you need the fastiport plugin from BZR, the last hg release series
118supported by fastimport-0.6 is hg-1.0.x.
119
120Mercurial (Hg) version:
121----
122$ hg version
123Mercurial Distributed SCM (version 1.3)
124----
125
126Strictly speaking this document is a wrong place to talk about
127configuring hg fastimport. However... you will need something like:
128
129----
130$ hg clone http://vc.gerg.ca/hg/pyfastimport
131$ hg clone http://vc.gerg.ca/hg/hg-fastimport
132$ sudo ln -s /path/to/pyfastimport/fastimport /usr/lib/python2.6/site-packages/fastimport
133$ sudo ln -s /path/to/hg-fastimport/hgfastimport /usr/lib/python2.6/site-packages/hgfastimport
134echo -e "[extensions]\nfastimport = /usr/lib/python2.6/site-packages/hgfastimport" > ~/.hgrc
135----
136
137and once you installed the plugin correctly, you should have something like:
138
139----
140$ ls /usr/lib/python*/site-packages/hgext/fastimport/__init__.py
141/usr/lib/python2.5/site-packages/hgext/fastimport/__init__.py
142----
143
144== Additional resources
145
146You can reach the Changelog link:Changelog[here], and a gitweb interface
147http://vmiklos.hu/gitweb/?p=darcs-fast-export.git[here].
148
149The fast-import stream format documentation is
150http://git.kernel.org/?p=git/git.git;a=blob;f=fast-import.c;hb=HEAD[here]
151if you're interested.
152
153== Alternatives
154
155- http://repo.or.cz/w/darcs2git.git[darcs2git] tries to find conflict
156 resolutions (to map them to merge commits), but it's rather slow
157 because of this. It does not support the darcs2 format and/or
158 incremental conversions, either. darcs-fast-export may support mapping
159 to merge commits later, but not before
160 http://bugs.darcs.net/issue1261[this issue] is addressed.
161
162- http://progetti.arstecnica.it/tailor[tailor] is an any2any VCS
163 converter, but it produces corrupted results when converting the
164 big-zoo - see http://progetti.arstecnica.it/tailor/ticket/171[this
165 ticket].
166
167- http://git.sanityinc.com/?p=darcs-to-git.git[darcs-to-git] is similar
168 to darcs2git, but it fails for the testcases found in the testsuite of
169 darcs-fast-export.
170
171- http://github.com/freshtonic/undarcs/tree/master[undarcs] claims to be
172 fast, but its own README says it produces incorrect results. When I
173 tried, it did not handle the darcs2 format, binary files and incremental
174 support.
175
176== Thanks
177
178- Jason Dagit for helping me with darcs2 issues
179- Shawn O. Pearce and Johannes Schindelin for writing `git-fast-import`
180 / `git-fast-export`
181- Ian Clatworthy for writing bzr fast-import
182- Paul Crowley for writing hg fast-import
183- Matthias Andree for assorted improvements, among them the --help,
184 --encoding and --authors-file features (using Python's optparse), support
185 for hashed repositories, `_darcs/format` interpretation, and mangling
186 whitespace in tags to cope with repos imported into DARCS from CVS.
187- Pieter de Bie for writing git-bzr, which was the base of git-darcs
1880
=== removed file 'exporters/darcs/TODO'
--- exporters/darcs/TODO 2010-06-27 23:21:13 +0000
+++ exporters/darcs/TODO 1970-01-01 00:00:00 +0000
@@ -1,8 +0,0 @@
1more intelligent tests, such as detect if the hg fastimport extension is
2not enabled, etc.
3
4parse the patches manually so we can avoid re-adding existing files manually.
5
6avoid darcs apply.
7
8import: handle evil merges (git-subtree), maybe using git log --first-parent
90
=== removed file 'exporters/darcs/asciidoc.conf'
--- exporters/darcs/asciidoc.conf 2008-12-22 23:48:45 +0000
+++ exporters/darcs/asciidoc.conf 1970-01-01 00:00:00 +0000
@@ -1,21 +0,0 @@
1ifdef::doctype-manpage[]
2ifdef::backend-docbook[]
3[header]
4template::[header-declarations]
5<refentry>
6 <refentryinfo>
7 <date>{dfe_date}</date>
8 </refentryinfo>
9 <refmeta>
10 <refentrytitle>{mantitle}</refentrytitle>
11 <manvolnum>{manvolnum}</manvolnum>
12 <refmiscinfo class="source">darcs-fast-export</refmiscinfo>
13 <refmiscinfo class="version">{dfe_version}</refmiscinfo>
14 <refmiscinfo class="manual">darcs-fast-export manual</refmiscinfo>
15 </refmeta>
16 <refnamediv>
17 <refname>{manname}</refname>
18 <refpurpose>{manpurpose}</refpurpose>
19 </refnamediv>
20endif::backend-docbook[]
21endif::doctype-manpage[]
220
=== removed file 'exporters/darcs/d2x'
--- exporters/darcs/d2x 2011-10-06 00:11:52 +0000
+++ exporters/darcs/d2x 1970-01-01 00:00:00 +0000
@@ -1,112 +0,0 @@
1#!/bin/sh
2#
3# d2x - convert darcs repos to git, bzr or hg using fast-import
4#
5# Copyright (c) 2008 by Miklos Vajna <vmiklos@frugalware.org>
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 2 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20
21usage()
22{
23 echo "Usage: d2x -f format darcsrepo"
24}
25
26die()
27{
28 echo "$@"
29 usage
30 exit 1
31}
32
33check_up_to_date()
34{
35 upstreamnum=$(cd $origin; darcs show repo|grep 'Num Patches'|sed 's/.*: //')
36 if [ "$upstreamnum" = "$(eval $*)" ]; then
37 echo "No remote changes to pull!"
38 exit 0
39 fi
40}
41
42case $1 in
43 -h|--help)
44 usage
45 exit 0
46 ;;
47 -f)
48 format="$2"
49 shift 2
50 ;;
51esac
52
53[ -n "$format" ] || die "Target format is not given!"
54
55case $format in
56 git|bzr|hg)
57 ;;
58 *)
59 die "The requested target format is not yet supported!"
60 ;;
61esac
62
63origin="$1"
64shift 1
65
66[ -d "$origin" ] || die "Source repo does not exist!"
67
68# convert to abspath
69cd $origin
70origin=$(pwd)
71
72dmark="$origin.$format/darcs/dfe-marks"
73fmark="$origin.$format/darcs/ffi-marks"
74
75mkdir -p $origin.$format/darcs
76cd $origin.$format
77
78common_opts="--working $origin.$format/darcs/repo --logfile $origin.$format/darcs/log $origin"
79if [ ! -f $dmark ]; then
80 case $format in
81 git)
82 git --bare init
83 darcs-fast-export $* --export-marks=$dmark $common_opts | \
84 git fast-import --export-marks=$fmark
85 ;;
86 bzr)
87 bzr init-repo .
88 darcs-fast-export $* --export-marks=$dmark $common_opts | \
89 bzr fast-import --export-marks=$fmark -
90 ;;
91 hg)
92 hg init
93 darcs-fast-export $* $origin | \
94 hg fastimport -
95 esac
96else
97 case $format in
98 git)
99 check_up_to_date "git rev-list HEAD |wc -l"
100 darcs-fast-export $* --export-marks=$dmark --import-marks=$dmark $common_opts | \
101 git fast-import --export-marks=$fmark --import-marks=$fmark
102 ;;
103 bzr)
104 check_up_to_date "cd master; bzr revno"
105 darcs-fast-export $* --export-marks=$dmark --import-marks=$dmark $common_opts | \
106 bzr fast-import --export-marks=$fmark --import-marks=$fmark -
107 ;;
108 hg)
109 die "Incremental conversion to hg is not yet supported by hg fastimport."
110 ;;
111 esac
112fi
1130
=== removed file 'exporters/darcs/d2x.txt'
--- exporters/darcs/d2x.txt 2008-11-27 13:36:26 +0000
+++ exporters/darcs/d2x.txt 1970-01-01 00:00:00 +0000
@@ -1,27 +0,0 @@
1= d2x(1)
2
3== NAME
4
5d2x - convert darcs repos to git, bzr or hg using fast-import
6
7== SYNOPSIS
8
9d2x -f <format> <darcsrepo> [<darcs-fast-export options>]
10
11== DESCRIPTION
12
13d2x is a wrapper script that just automates doing an initial or
14continuing an incremental conversion. All it does is initializing the
15target repo, starting darcs-fast-export and the relevant importer with
16the proper switches and pipe the exporter's output to the importer's
17standard input.
18
19== OPTIONS
20
21--help::
22 Display usage.
23
24-f <format>::
25 Specify the format of the target repo. Currently supported targets are
26 git, bzr and hg. Incremental conversion is supported in case of git and
27 bzr.
280
=== removed file 'exporters/darcs/darcs-fast-export'
--- exporters/darcs/darcs-fast-export 2010-11-09 00:01:12 +0000
+++ exporters/darcs/darcs-fast-export 1970-01-01 00:00:00 +0000
@@ -1,380 +0,0 @@
1#!/usr/bin/env python
2
3"""
4
5 darcs-fast-export - darcs backend for fast data importers
6
7 Copyright (c) 2008, 2009 Miklos Vajna <vmiklos@frugalware.org>
8 Copyright (c) 2008 Matthias Andree <matthias.andree@gmx.de>
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
13 any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23
24"""
25
26import xml.dom.minidom
27import xml.parsers.expat
28import os
29import sys
30import gzip
31import time
32import calendar
33import shutil
34import subprocess
35import optparse
36import re
37import urllib
38import urllib2
39import StringIO
40
41sys = reload(sys)
42sys.setdefaultencoding("utf-8")
43
44class Handler:
45 def __init__(self):
46 self.hashes = []
47 self.authormap = {}
48 self.export_marks = []
49 self.import_marks = []
50
51 def get_patchname(self, patch):
52 ret = []
53 s = ""
54 if patch.attributes['inverted'].value == 'True':
55 s = "UNDO: "
56 cs = patch.getElementsByTagName("name")[0].childNodes
57 if cs.length > 0:
58 ret.append(s + cs[0].data)
59 lines = patch.getElementsByTagName("comment")
60 if lines:
61 for i in lines[0].childNodes[0].data.split('\n'):
62 if not i.startswith("Ignore-this: "):
63 ret.append(i)
64 return "\n".join(ret).encode('utf-8')
65
66 def get_author(self, patch):
67 """darcs allows any freeform string, but fast-import has a more
68 strict format, so fix up broken author names here."""
69
70 author = patch.attributes['author'].value
71 if author in self.authormap:
72 author = self.authormap[author]
73 if not len(author):
74 author = "darcs-fast-export <darcs-fast-export>"
75 # add missing name
76 elif not ">" in author:
77 author = "%s <%s>" % (author.split('@')[0], author)
78 # avoid double quoting
79 elif author[0] == '"' and author[-1] == '"':
80 author = author[1:-1]
81 # name after email
82 elif author[-1] != '>':
83 author = author[author.index('>')+2:] + ' ' + author[:author.index('>')+1]
84 return author.encode('utf-8')
85
86 def get_date(self, patch):
87 try:
88 date = time.strptime(patch, "%Y%m%d%H%M%S")
89 except ValueError:
90 date = time.strptime(patch[:19] + patch[-5:], '%a %b %d %H:%M:%S %Y')
91 return calendar.timegm(date)
92
93 def progress(self, s):
94 print "progress [%s] %s" % (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), s)
95 sys.stdout.flush()
96
97 def log(self, s):
98 self.logsock.write("[%s] %s" % (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), s))
99 self.logsock.flush()
100
101 def parse_inventory(self, sock=None):
102 prev = None
103 nextprev = False
104 buf = []
105 if not sock:
106 sock = self.open(os.path.join(self.origin, "_darcs", "hashed_inventory"))
107 for i in sock.readlines():
108 if i.startswith("hash"):
109 buf.insert(0, i[6:-1])
110 if i.startswith("Starting with inventory:"):
111 nextprev = True
112 elif nextprev:
113 prev = i[:-1]
114 nextprev = False
115 sock.close()
116 for i in buf:
117 self.hashes.insert(0, i)
118 if prev:
119 sock = self.gzip_open(os.path.join(self.origin, "_darcs", "inventories", prev))
120 self.parse_inventory(sock)
121
122 # this is like gzip.open but supports urls as well
123 def gzip_open(self, path):
124 if os.path.exists(path):
125 return gzip.open(path)
126 buf = urllib.urlopen(path).read()
127 sock = StringIO.StringIO(buf)
128 return gzip.GzipFile(fileobj=sock)
129
130 # this is like os.path.exists but supports urls as well
131 def path_exists(self, path):
132 if os.path.exists(path):
133 return True
134 else:
135 try:
136 urllib2.urlopen(urllib2.Request(path))
137 return True
138 except urllib2.HTTPError, e:
139 return False
140
141 # this is like open, but supports urls as well
142 def open(self, path):
143 if os.path.exists(path):
144 return open(path)
145 else:
146 return urllib.urlopen(path)
147
148 def handle_opts(self):
149 # Option Parser
150 usage="%prog [options] darcsrepo"
151 opp = optparse.OptionParser(usage=usage)
152 opp.add_option("--import-marks", metavar="IFILE",
153 help="read state for incremental imports from IFILE")
154 opp.add_option("--export-marks", metavar="OFILE",
155 help="write state for incremental imports from OFILE")
156 opp.add_option("--encoding",
157 help="encoding of log [default: %default], if unspecified and input isn't utf-8, guess")
158 opp.add_option("--authors-file", metavar="F",
159 help="read author transformations in old=new format from F")
160 opp.add_option("--working", metavar="W",
161 help="working directory which is removed at the end of non-incremental conversions")
162 opp.add_option("--logfile", metavar="L",
163 help="log file which contains the output of external programs invoked during the conversion")
164 opp.add_option("--git-branch", metavar="B",
165 help="git branch [default: refs/heads/master]")
166 opp.add_option("--progress", metavar="P",
167 help="insert progress statements after every n commit [default: 100]")
168 (self.options, self.args) = opp.parse_args()
169 if len(self.args) < 1:
170 opp.error("darcsrepo required")
171
172 # read author mapping file in gitauthors format,
173 # i. e. in=out (one per # line)
174 if self.options.authors_file:
175 sock = open(self.options.authors_file)
176 self.authormap = dict([i.strip().split('=',1) for i in sock])
177 sock.close()
178
179 if "://" not in self.args[0]:
180 self.origin = os.path.abspath(self.args[0])
181 else:
182 self.origin = self.args[0].strip('/')
183 if self.options.working:
184 self.working = os.path.abspath(self.options.working)
185 else:
186 if "://" not in self.origin:
187 self.working = "%s.darcs" % self.origin
188 else:
189 self.working = "%s.darcs" % os.path.split(self.origin)[-1]
190 if self.options.logfile:
191 logfile = os.path.abspath(self.options.logfile)
192 else:
193 if "://" not in self.origin:
194 logfile = "%s.log" % self.origin
195 else:
196 logfile = "%s.log" % os.path.split(self.origin)[-1]
197 self.logsock = open(logfile, "a")
198 if self.options.git_branch:
199 self.git_branch = self.options.git_branch
200 else:
201 self.git_branch = "refs/heads/master"
202
203 if self.options.progress:
204 self.prognum = int(self.options.progress)
205 else:
206 self.prognum = 100
207
208 def handle_import_marks(self):
209 if self.options.import_marks:
210 sock = open(self.options.import_marks)
211 for i in sock.readlines():
212 line = i.strip()
213 if not len(line):
214 continue
215 self.import_marks.append(line.split(' ')[1])
216 self.export_marks.append(line)
217 sock.close()
218
219 def get_patches(self):
220 self.progress("getting list of patches")
221 if not len(self.import_marks):
222 sock = os.popen("darcs changes --xml --reverse --repo %s" % self.origin)
223 else:
224 sock = os.popen("darcs changes --xml --reverse --repo %s --from-match 'hash %s'" % (self.origin, self.import_marks[-1]))
225 buf = sock.read()
226 sock.close()
227 # this is hackish. we need to escape some bad chars, otherwise the xml
228 # will not be valid
229 buf = buf.replace('\x1b', '^[')
230 if self.options.encoding:
231 xmldoc = xml.dom.minidom.parseString(unicode(buf, self.options.encoding).encode('utf-8'))
232 else:
233 try:
234 xmldoc = xml.dom.minidom.parseString(buf)
235 except xml.parsers.expat.ExpatError:
236 try:
237 import chardet
238 except ImportError:
239 sys.exit("Error, encoding is not utf-8. Please " +
240 "either specify it with the --encoding " +
241 "option or install chardet.")
242 self.progress("encoding is not utf8, guessing charset")
243 encoding = chardet.detect(buf)['encoding']
244 self.progress("detected encoding is %s" % encoding)
245 xmldoc = xml.dom.minidom.parseString(unicode(buf, encoding).encode('utf-8'))
246 sys.stdout.flush()
247 return xmldoc.getElementsByTagName('patch')
248
249 def setup_workdir(self):
250 darcs2 = False
251 self.oldfashionedpatch = True
252 self.cwd = os.getcwd()
253 if self.path_exists(os.path.join(self.origin, "_darcs", "format")):
254 sock = self.open(os.path.join(self.origin, "_darcs", "format"))
255 format = [x.strip() for x in sock]
256 sock.close()
257 darcs2 = 'darcs-2' in format
258 self.oldfashionedpatch = not 'hashed' in format
259 if not self.oldfashionedpatch:
260 self.progress("parsing the inventory")
261 if "://" not in self.origin:
262 os.chdir(self.origin)
263 self.parse_inventory()
264 if not self.options.import_marks or not os.path.exists(self.working):
265 # init the tmp darcs repo
266 os.mkdir(self.working)
267 os.chdir(self.working)
268 if darcs2:
269 os.system("darcs init --darcs-2")
270 else:
271 os.system("darcs init --old-fashioned-inventory")
272 else:
273 os.chdir(self.working)
274 if self.options.import_marks:
275 sock = os.popen("darcs pull -a --match 'hash %s' %s" % (self.import_marks[-1], self.origin))
276 self.log("Building/updating working directory:\n%s" % sock.read())
277 sock.close()
278
279 def export_patches(self):
280 patches = self.get_patches()
281 # this is the number of the NEXT patch
282 count = 1
283 if len(self.import_marks):
284 patches = patches[1:]
285 count = len(self.import_marks) + 1
286 if len(self.export_marks):
287 # this is the mark number of the NEXT patch
288 markcount = int(self.export_marks[-1].split(' ')[0][1:]) + 1
289 else:
290 markcount = count
291 # this may be huge and we need it many times
292 patchnum = len(patches)
293
294 if not len(self.import_marks):
295 self.progress("starting export, repo has %d patches" % patchnum)
296 else:
297 self.progress("continuing export, %d patches to convert" % patchnum)
298 paths = []
299 for i in patches:
300 # apply the patch
301 hash = i.attributes['hash'].value
302 buf = ["\nNew patches:\n"]
303 if self.oldfashionedpatch:
304 sock = self.gzip_open(os.path.join(self.origin, "_darcs", "patches", hash))
305 else:
306 sock = self.gzip_open(os.path.join(self.origin, "_darcs", "patches", self.hashes[count-1]))
307 buf.append(sock.read())
308 sock.close()
309 sock = os.popen("darcs changes --context")
310 buf.append(sock.read())
311 sock.close()
312 sock = subprocess.Popen(["darcs", "apply", "--allow-conflicts"], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
313 sock.stdin.write("".join(buf))
314 sock.stdin.close()
315 self.log("Applying %s:\n%s" % (hash, sock.stdout.read()))
316 sock.stdout.close()
317 message = self.get_patchname(i)
318 # export the commit
319 print "commit %s" % self.git_branch
320 print "mark :%s" % markcount
321 if self.options.export_marks:
322 self.export_marks.append(":%s %s" % (markcount, hash))
323 date = self.get_date(i.attributes['date'].value)
324 print "committer %s %s +0000" % (self.get_author(i), date)
325 print "data %d\n%s" % (len(message), message)
326 if markcount > 1:
327 print "from :%s" % (markcount-1)
328 # export the files
329 for j in paths:
330 print "D %s" % j
331 paths = []
332 for (root, dirs, files) in os.walk ("."):
333 for f in files:
334 j = os.path.normpath(os.path.join(root, f))
335 if j.startswith("_darcs") or "-darcs-backup" in j:
336 continue
337 paths.append(j)
338 sock = open(j)
339 buf = sock.read()
340 sock.close()
341 # darcs does not track the executable bit :/
342 print "M 644 inline %s" % j
343 print "data %s\n%s" % (len(buf), buf)
344 if message[:4] == "TAG ":
345 tag = re.sub('[^\xe9-\xf8\w.\-]+', '_', message[4:].strip().split('\n')[0]).strip('_')
346 print "tag %s" % tag
347 print "from :%s" % markcount
348 print "tagger %s %s +0000" % (self.get_author(i), date)
349 print "data %d\n%s" % (len(message), message)
350 if count % self.prognum == 0:
351 self.progress("%d/%d patches" % (count, patchnum))
352 count += 1
353 markcount += 1
354
355 os.chdir(self.cwd)
356
357 if not self.options.export_marks:
358 shutil.rmtree(self.working)
359 self.logsock.close()
360
361 def handle_export_marks(self):
362 if self.options.export_marks:
363 self.progress("writing export marks")
364 sock = open(self.options.export_marks, 'w')
365 sock.write("\n".join(self.export_marks))
366 sock.write("\n")
367 sock.close()
368
369 self.progress("finished")
370
371 def handle(self):
372 self.handle_opts()
373 self.handle_import_marks()
374 self.setup_workdir()
375 self.export_patches()
376 self.handle_export_marks()
377
378if __name__ == "__main__":
379 h = Handler()
380 h.handle()
3810
=== removed file 'exporters/darcs/darcs-fast-export.txt'
--- exporters/darcs/darcs-fast-export.txt 2009-10-22 10:25:39 +0000
+++ exporters/darcs/darcs-fast-export.txt 1970-01-01 00:00:00 +0000
@@ -1,68 +0,0 @@
1= darcs-fast-export(1)
2
3== NAME
4
5darcs-fast-export - darcs frontend to git fast-import
6
7== SYNOPSIS
8
9darcs-fast-export [<options>] <darcsrepo>
10
11== DESCRIPTION
12
13darcs-fast-export expects one argument, the path to the source darcs
14repository. It will print the git fast-import format on standard output
15(stdout).
16
17The script can produce the fast-import stream format from the darcs
18repository. It supports incremental conversion as well, via the
19--import-marks / --export-marks switches.
20
21Optionally the darcsrepo string may be a HTTP repository, in that case
22only the patches are downloaded, not the pristine, speeding up a
23one-time import.
24
25== OPTIONS
26
27-h, --help::
28 Display usage.
29
30--import-marks=<file>::
31 Import marks from <file>. This is read at the beginning of the
32 conversion at once. Use it if you want to continue an incremental
33 conversion.
34
35--export-marks=<file>::
36 Export marks to <file> at the end of the conversion. It can be the
37 same as the one for --import-marks as it is written only once at the
38 end. Use it if you want to be able to incrementally update the target
39 repository later.
40
41--encoding=<encoding>::
42 The encoding of the author names and commit messages in the repository.
43 The default is utf-8. If it is not the default, it will be guessed.
44 Given that it takes some time, you can explicitly specify it as an
45 option to make the conversion faster. Content in the output will encoded
46 as utf-8 and will be written that way to the target repository, unless
47 the importer re-encodes it again to some other character set.
48
49--working=<directory>::
50 The conversion is done by applying the patches one by one and recording
51 the state of the working directory. You can specify the path of this
52 directory using this option.
53
54--logfile=<logfile>::
55 The output of external commands are redirected to a log file. You can
56 specify the path of that file with this parameter.
57
58--git-branch=<branch>::
59 There is only one branch in one darcs repository, but the fast-import
60 stream format allows multiple branches, thus the exporter has to name
61 darcs's branch. The default value is 'refs/heads/master'.
62
63--progress=<n>::
64 Insert progress statements after every <n> patches, to be shown by the
65 fast importer during import. The default value is '100'.
66
67--authors-file=<file>::
68 Read author transformations in old=new format from <file>.
690
=== removed file 'exporters/darcs/darcs-fast-import'
--- exporters/darcs/darcs-fast-import 2010-07-28 01:33:33 +0000
+++ exporters/darcs/darcs-fast-import 1970-01-01 00:00:00 +0000
@@ -1,375 +0,0 @@
1#!/usr/bin/env python
2
3"""
4
5 darcs-fast-export - darcs backend for fast data exporters
6
7 Copyright (c) 2008, 2009, 2010 Miklos Vajna <vmiklos@frugalware.org>
8 Copyright (c) 2008 Matthias Andree <matthias.andree@gmx.de>
9
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 2, or (at your option)
13 any later version.
14
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
19
20 You should have received a copy of the GNU General Public License
21 along with this program; if not, write to the Free Software
22 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23
24"""
25
26import sys
27import os
28import re
29import time
30import shutil
31import optparse
32import subprocess
33
34class Handler:
35 def __init__(self):
36 self.marks = {}
37 self.files = []
38 self.prevfiles = None
39 self.ch = None
40 self.line = None
41 self.unread_line = False
42 self.eof = False
43 self.debug = False
44 self.export_marks = []
45 self.import_marks = []
46
47 def read_next_line(self):
48 if self.unread_line:
49 self.unread_line = False
50 return
51 self.line = ""
52 if self.eof:
53 return
54 if self.ch:
55 self.line += self.ch
56 self.ch = None
57 buf = sys.stdin.readline()
58 if not len(buf):
59 self.eof = True
60 else:
61 self.line += buf
62 if self.debug:
63 print "read_next_line: '%s'" % self.line
64
65 def read(self, length):
66 buf = ""
67 if self.ch:
68 buf += self.ch
69 self.ch = None
70 buf += sys.stdin.read(length)
71 if self.debug:
72 print "read: '%s'" % buf
73 return buf
74
75 def skip_optional_lf(self):
76 self.ch = self.read(1)
77 if self.ch == "\n":
78 self.ch = None
79
80 def bug(self, s):
81 raise Exception(s)
82
83 def get_date(self, ts, tz):
84 # first fix the case when tz is higher than +1200, as
85 # darcs won't accept it
86 if int(tz[:3]) > 12:
87 ts = str(int(ts) + 60*60*24)
88 tz = str(int(tz[:3])-24) + tz[3:]
89 # int(ts) is seconds since epoch. Since we're trying to
90 # capture both the absolute time of the commit and the
91 # localtime in the timezone of the committer, we need to turn
92 # the (seconds-since-epoch, committer-timezone-offset) pair
93 # that we get from the git-fast-export stream format into a
94 # localized-time-plus-timezone-marker string that darcs will
95 # accept. Therefore, we parse the timezone-offset (which
96 # looks like +0500 or +0000 or -0730 or something) and add it
97 # to seconds-since-epoch before calling gmtime().
98 mo = re.search(r'^([\+\-])(\d\d)(\d\d)$', tz)
99 offset = 60*60*int(mo.group(2)) + 60*int(mo.group(3))
100 if mo.group(1) == "-":
101 offset = -offset
102 offset_time = int(ts) + offset
103 s = time.strftime("%a %b %d %H:%M:%S %Y", time.gmtime(offset_time))
104 items = s.split(' ')
105 return " ".join(items[:-1]) + " " + tz + " " + items[-1]
106
107 def invoke_darcs(self, cmdline):
108 if os.system("darcs %s" % cmdline) != 0:
109 self.bug("darcs failed")
110
111 def invoke_add(self, path):
112 self.invoke_darcs("add --boring --case-ok %s" % path)
113
114 def handle_mark(self):
115 if self.line.startswith("mark :"):
116 self.mark_num = int(self.line[6:-1])
117 self.read_next_line()
118
119 def handle_data(self):
120 if not self.line.startswith("data "):
121 self.bug("Expected 'data n' command, found: '%s'" % self.line[:-1])
122 length = int(self.line[5:-1])
123 self.buf = self.read(length)
124 self.skip_optional_lf()
125
126 def handle_blob(self):
127 self.read_next_line()
128 self.handle_mark()
129 self.handle_data()
130 self.marks[self.mark_num] = self.buf
131
132 def handle_ident(self, s):
133 items = s.split(' ')
134 self.ident = " ".join(items[:-2])
135 self.date = self.get_date(items[-2], items[-1])
136
137 def handle_msg(self):
138 items = self.buf.split('\n')
139 self.short = items[0]
140 self.long = "\n".join(items[1:])
141
142 def handle_tag(self):
143 version = self.line[:-1].split(' ')[1]
144 self.read_next_line()
145 if self.line.startswith("from "):
146 self.read_next_line()
147 if self.line.startswith("tagger "):
148 self.handle_ident(self.line[7:-1])
149 self.read_next_line()
150 self.handle_data()
151 self.skip_optional_lf()
152 sock = subprocess.Popen(["darcs", "tag", "--pipe"], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
153 buf = [self.date, self.ident, version]
154 sock.stdin.write("\n".join(buf))
155 sock.stdin.close()
156 self.log("Tagging %s:\n%s" % (version, sock.stdout.read()))
157 sock.stdout.close()
158 if sock.wait() != 0:
159 self.bug("darcs tag failed: '%s'" % sock.returncode)
160
161 def handle_commit(self):
162 if not self.prevfiles and self.options.import_marks:
163 # first commit in an incremental continued
164 # import
165 for (root, dirs, files) in os.walk("."):
166 for i in files:
167 path = os.path.normpath(os.path.join(root, i))
168 if path.startswith("_darcs") or "-darcs-backup" in path:
169 continue
170 self.files.append(path)
171 self.prevfiles = self.files[:]
172 adds = []
173 symlinks = []
174
175 self.read_next_line()
176 self.handle_mark()
177 if self.line.startswith("author "):
178 self.handle_ident(self.line[7:-1])
179 self.read_next_line()
180 if self.line.startswith("committer "):
181 self.handle_ident(self.line[10:-1])
182 self.read_next_line()
183 self.handle_data()
184 self.skip_optional_lf()
185 self.handle_msg()
186 self.read_next_line()
187 if self.line.startswith("from "):
188 self.read_next_line()
189 while self.line.startswith("merge "):
190 self.read_next_line()
191 change = False
192 while len(self.line) > 0:
193 if self.line.startswith("deleteall"):
194 path = self.line[2:-1]
195 for path in self.files:
196 os.unlink(path)
197 self.files = []
198 change = True
199 elif self.line.startswith("D "):
200 path = self.line[2:-1]
201 if os.path.exists(path):
202 os.unlink(path)
203 if path in self.files:
204 self.files.remove(path)
205 change = True
206 elif self.line.startswith("R "):
207 self.invoke_darcs("mv %s" % self.line[2:])
208 change = True
209 elif self.line.startswith("C "):
210 src, dest = self.line[:-1].split(' ')[1:]
211 shutil.copy(src.strip('"'), dest.strip('"'))
212 self.invoke_add(dest)
213 change = True
214 elif self.line.startswith("M "):
215 items = self.line.split(' ')
216 path = items[3][:-1]
217 dir = os.path.split(path)[0]
218 if len(dir) and not os.path.exists(dir):
219 os.makedirs(dir)
220 if items[1] == "120000":
221 if not self.options.symhack:
222 print "Adding symbolic links (symlinks) is not supported by Darcs."
223 sys.exit(2)
224 idx = int(items[2][1:]) # TODO: handle inline symlinks
225 symlinks.append((self.marks[idx], path))
226 self.read_next_line()
227 continue
228 sock = open(path, "w")
229 if items[2] != "inline":
230 idx = int(items[2][1:])
231 sock.write(self.marks[idx])
232 else:
233 self.read_next_line()
234 self.handle_data()
235 sock.write(self.buf)
236 sock.close()
237 if path not in self.prevfiles:
238 adds.append(path)
239 if path not in self.files:
240 self.files.append(path)
241 change = True
242 else:
243 self.unread_line = True
244 break
245 self.read_next_line()
246 if not len(self.line):
247 break
248
249 if not change:
250 # darcs does not support empty commits
251 return
252 for i in adds:
253 self.invoke_add(i)
254 args = ["darcs", "record", "--ignore-times", "-a", "--pipe"]
255 buf = [self.date, self.ident]
256 if not len(self.short):
257 args.extend(['-m', ''])
258 else:
259 buf.extend([self.short, self.long])
260 sock = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
261 sock.stdin.write("\n".join(buf)+"\n")
262 sock.stdin.close()
263 self.log("Recording :%s:\n%s" % (self.mark_num, sock.stdout.read()))
264 sock.stdout.close()
265 if sock.wait() != 0:
266 self.bug("darcs record failed: '%s'" % sock.returncode)
267
268 for src, path in symlinks:
269 # symlink does not do what we want if path is
270 # already there
271 if os.path.exists(path):
272 # rmtree() does not work on symlinks
273 if os.path.islink(path):
274 os.remove(path)
275 else:
276 shutil.rmtree(path)
277 os.symlink(src, path)
278 if self.options.export_marks:
279 # yeah, an xml parser would be better, but
280 # should we mess with encodings just because of
281 # this? i hope not
282 sock = os.popen("darcs changes --last=1 --xml", "r")
283 buf = sock.read()
284 sock.close()
285 hash = buf.split('\n')[1].split("'")[-2]
286 self.export_marks.append(":%s %s" % (self.mark_num, hash))
287
288 def handle_progress(self, s):
289 print "import progress [%s] %s" % (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), s.strip())
290 sys.stdout.flush()
291
292 def handle_opts(self):
293 # Option Parser
294 usage="%prog [options]"
295 opp = optparse.OptionParser(usage=usage)
296 opp.set_defaults(symhack=False)
297 opp.add_option("--import-marks", metavar="IFILE",
298 help="read state for incremental imports from IFILE")
299 opp.add_option("--export-marks", metavar="OFILE",
300 help="write state for incremental imports to OFILE")
301 opp.add_option("--logfile", metavar="L",
302 help="log file which contains the output of external programs invoked during the conversion")
303 opp.add_option("--symhack", action="store_true", dest="symhack",
304 help="Do not error out when a symlink would be created, just create it in the workdir")
305 opp.add_option("--progress", metavar="P",
306 help="insert progress statements after every n commit [default: 100]")
307 (self.options, args) = opp.parse_args()
308
309 if self.options.logfile:
310 logfile = self.options.logfile
311 else:
312 logfile = "_darcs/import.log"
313 self.logsock = open(os.path.abspath(logfile), "a")
314
315 if self.options.progress:
316 self.prognum = int(self.options.progress)
317 else:
318 self.prognum = 0
319
320 def log(self, s):
321 self.logsock.write("[%s] %s" % (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), s))
322 self.logsock.flush()
323
324 def handle_export_marks(self):
325 if self.options.export_marks:
326 sock = open(self.options.export_marks, 'w')
327 sock.write("\n".join(self.export_marks))
328 sock.write("\n")
329 sock.close()
330
331 def handle_import_marks(self):
332 if self.options.import_marks:
333 sock = open(self.options.import_marks)
334 for i in sock.readlines():
335 line = i.strip()
336 if not len(line):
337 continue
338 self.import_marks.append(line.split(' ')[1])
339 self.export_marks.append(line)
340 sock.close()
341
342 def handle(self):
343 self.handle_opts()
344 self.handle_import_marks()
345
346 commitcount = 0
347 while not self.eof:
348 self.read_next_line()
349 if not len(self.line[:-1]):
350 pass
351 elif self.line.startswith("blob"):
352 self.handle_blob()
353 elif self.line.startswith("commit"):
354 self.handle_commit()
355 commitcount += 1
356 if self.prognum != 0 and commitcount % self.prognum == 0:
357 self.handle_progress("%d patches" % commitcount)
358 elif self.line.startswith("tag"):
359 self.handle_tag()
360 elif self.line.startswith("reset"):
361 self.read_next_line()
362 if not self.line.startswith("from "):
363 self.unread_line = True
364 elif self.line.startswith("checkpoint"):
365 pass
366 elif self.line.startswith("progress"):
367 self.handle_progress(self.line[9:])
368 else:
369 self.bug("'%s': invalid command" % self.line[:-1])
370
371 self.handle_export_marks()
372
373if __name__ == "__main__":
374 h = Handler()
375 h.handle()
3760
=== removed file 'exporters/darcs/darcs-fast-import.txt'
--- exporters/darcs/darcs-fast-import.txt 2010-06-27 21:28:23 +0000
+++ exporters/darcs/darcs-fast-import.txt 1970-01-01 00:00:00 +0000
@@ -1,57 +0,0 @@
1= darcs-fast-import(1)
2
3== NAME
4
5darcs-fast-import - darcs backend to the 'fast-import stream' format
6
7== SYNOPSIS
8
9darcs-fast-import [<options>]
10
11== DESCRIPTION
12
13darcs-fast-import can produce a darcs repository from a fast-import
14stream, read from the standard input. It supports incremental conversion
15as well, via the --import-marks / --export-marks switches.
16
17== OPTIONS
18
19-h, --help::
20 Display usage.
21
22--import-marks::
23 Import marks from a given file. This is read at the beginning of the
24 conversion at once. Use it if you want to continue an incremental
25 conversion.
26
27--export-marks::
28 Export marks to a given file at the end of the conversion. It can be the
29 same as the one for --import-marks as it is written only once at the
30 end. Use it if you want to be able to incrementally update the target
31 repository later.
32
33--logfile::
34 The output of external commands are redirected to a log file. You can
35 specify the path of that file with this parameter.
36
37--symhack::
38 Enable hack for symbolic links. darcs add does not handle them
39 but in case they are just added, we can create them in the working
40 directory. This can be handy in case for example the symbolic link is in
41 a subdirectory of the project and you don't even care about that
42 subdirectory. So the hack can be useful, but be extremely careful when
43 you use it.
44
45--progress=<n>::
46 Insert progress statements after every <n> created patches. The
47 default is not to print anything as progress info is usually provided by
48 the exporter. Use this option in case the exporter does not have such a
49 switch but you still want to get some feedback.
50
51== EXIT CODES
52
53The exit code is:
54
55* 0 on success
56* 1 on unhandled exception
57* 2 in case the stream would try to let the importer create a symlink
580
=== removed file 'exporters/darcs/git-darcs'
--- exporters/darcs/git-darcs 2011-10-06 00:11:52 +0000
+++ exporters/darcs/git-darcs 1970-01-01 00:00:00 +0000
@@ -1,279 +0,0 @@
1#!/bin/bash
2#
3# git-darcs - bidirectional operation between a darcs repo and git
4#
5# Copyright (c) 2008, 2010 by Miklos Vajna <vmiklos@frugalware.org>
6#
7# Based on git-bzr, which is
8#
9# Copyright (c) 2008 Pieter de Bie <pdebie@ai.rug.nl>
10#
11# This program is free software; you can redistribute it and/or modify
12# it under the terms of the GNU General Public License as published by
13# the Free Software Foundation; either version 2 of the License, or
14# (at your option) any later version.
15#
16# This program is distributed in the hope that it will be useful,
17# but WITHOUT ANY WARRANTY; without even the implied warranty of
18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19# GNU General Public License for more details.
20#
21# You should have received a copy of the GNU General Public License
22# along with this program. If not, see <http://www.gnu.org/licenses/>.
23#
24
25add()
26{
27 name="$1"
28 shift
29 location="$1"
30 shift
31 if ! [ -n "$name" -a -n "$location" ]; then
32 echo "Usage: git darcs add name location [darcs-fast-export options]"
33 return 1
34 fi
35 if git remote show |grep -q $name; then
36 echo "There is already a remote with that name"
37 return 1
38 fi
39 if [ -n "$(git config git-darcs.$name.location)" ]; then
40 echo "There is already a darcs repo with that name"
41 return 1
42 fi
43 repo=$location/_darcs
44 if [ ! -d $repo ] && ! wget --quiet --spider $repo; then
45 echo "Remote is not a darcs repository"
46 return 1
47 fi
48 git config git-darcs.$name.location $location
49 echo "Darcs repo $name added. You can fetch it with 'git darcs fetch $name'"
50 if ! [ -z "$*" ]; then
51 git config git-darcs.$name.darcs-fast-export-options "$*"
52 echo "darcs-fast-export will get options: $*"
53 fi
54}
55
56get_location()
57{
58 l=$(git config git-darcs.$remote.location)
59 if [ -z "$l" ]; then
60 echo "Cannot find darcs remote with name '$remote'." >&2
61 return 1
62 fi
63 echo $l
64}
65
66fetch()
67{
68 remote="$1"
69 shift
70 if ! [ -n "$remote" -a -z "$*" ]; then
71 echo "Usage: git darcs fetch reponame"
72 return 1
73 fi
74 location=$(get_location $remote) || return $?
75 git_map=$git_dir/darcs-git/$remote-git-map
76 darcs_map=$git_dir/darcs-git/$remote-darcs-map
77 common_opts="--working $git_dir/darcs-git/repo --logfile $git_dir/darcs-git/fetch.log --git-branch=refs/remotes/darcs/$remote"
78 dfe_opts=$(git config git-darcs.$remote.darcs-fast-export-options)
79 pre_fetch="$(git config git-darcs.$remote.pre-fetch)"
80 if [ -n "$pre_fetch" ]; then
81 $pre_fetch
82 fi
83 if [ ! -f $git_map -a ! -f $darcs_map ]; then
84 echo "There doesn't seem to be an existing refmap."
85 echo "Doing an initial import"
86 mkdir -p $git_dir/darcs-git
87 darcs-fast-export --export-marks=$darcs_map $common_opts $dfe_opts $location | \
88 git fast-import --export-marks=$git_map
89 elif [ -f $git_map -a -f $darcs_map ]; then
90 echo "Updating remote $remote"
91 old_rev=$(git rev-parse refs/remotes/darcs/$remote)
92 darcs-fast-export --import-marks=$darcs_map --export-marks=$darcs_map $common_opts $dfe_opts $location | \
93 git fast-import --quiet --import-marks=$git_map --export-marks=$git_map
94 new_rev=$(git rev-parse refs/remotes/darcs/$remote)
95 if [ "$old_rev" != "$new_rev" ]; then
96 echo "Fetched the following updates:"
97 git shortlog $old_rev..$new_rev
98 else
99 echo "Nothing fetched."
100 return 0
101 fi
102 else
103 echo "One of the mapfiles is missing! Something went wrong!"
104 return 1
105 fi
106 post_fetch="$(git config git-darcs.$remote.post-fetch)"
107 if [ -n "$post_fetch" ]; then
108 $post_fetch
109 fi
110}
111
112pull()
113{
114 remote="$1"
115 shift
116 if ! [ -n "$remote" -a -z "$*" ]; then
117 echo "Usage: git darcs pull reponame"
118 return 1
119 fi
120 fetch $remote || return $?
121 # see if we need to merge or rebase
122 branch=$(git symbolic-ref HEAD|sed 's|.*/||')
123 if [ "$(git config branch.$branch.rebase)" = "true" ]; then
124 git rebase refs/remotes/darcs/$remote
125 else
126 git merge refs/remotes/darcs/$remote
127 fi
128}
129
130push()
131{
132 remote="$1"
133 shift
134 if ! [ -n "$remote" -a -z "$*" ]; then
135 echo "Usage: git darcs push reponame"
136 return 1
137 fi
138 location=$(get_location $remote) || return $?
139 if [ -n "$(git rev-list --left-right HEAD...refs/remotes/darcs/$remote | sed -n '/^>/ p')" ]; then
140 echo "HEAD is not a strict child of $remote, cannot push. Merge first"
141 return 1
142 fi
143 if [ -z "$(git rev-list --left-right HEAD...refs/remotes/darcs/$remote | sed -n '/^</ p')" ]; then
144 echo "Nothing to push. Commit something first"
145 return 1
146 fi
147 git_map=$git_dir/darcs-git/$remote-git-map
148 darcs_map=$git_dir/darcs-git/$remote-darcs-map
149 if [ ! -f $git_map -o ! -f $darcs_map ]; then
150 echo "We do not have refmapping yet. Then how can I push?"
151 return 1
152 fi
153 pre_push="$(git config git-darcs.$remote.pre-push)"
154 if [ -n "$pre_push" ]; then
155 $pre_push
156 fi
157 echo "Pushing the following updates:"
158 git shortlog refs/remotes/darcs/$remote..
159 git fast-export --import-marks=$git_map --export-marks=$git_map HEAD | \
160 (cd $location; darcs-fast-import --import-marks=$darcs_map --export-marks=$darcs_map \
161 --logfile $git_dir/darcs-git/push.log)
162 if [ $? == 0 ]; then
163 git update-ref refs/remotes/darcs/$remote HEAD
164 post_push="$(git config git-darcs.$remote.post-push)"
165 if [ -n "$post_push" ]; then
166 $post_push
167 fi
168 fi
169}
170
171# List the darcs remotes
172list()
173{
174 if [ -z "$*" ]
175 then
176 git config -l | sed -n -e '/git-darcs\..*/ {s/git-darcs\.//; s/\.location=.*//p}'
177 return 0
178 elif [ "$#" -eq 1 ]
179 then
180 case $1 in
181 -v|--verbose)
182 git config -l | sed -n -e '/git-darcs\..*/ {s/git-darcs\.//; s/\.location=/\t/p}'
183 return 0
184 ;;
185 esac
186 fi
187 echo "Usage: git darcs list [-v|--verbose]"
188 return 1
189}
190
191# Find the darcs commit(s) supporting a git SHA1 prefix
192find_darcs()
193{
194 sha1="$1"
195 shift
196 if [ -z "$sha1" -o -n "$*" ]
197 then
198 echo "Usage: git darcs find-darcs <sha1-prefix>"
199 return 1
200 fi
201 for remote in $(git for-each-ref --format='%(refname)' refs/remotes/darcs)
202 do
203 remote=`basename $remote`
204 git_map=$git_dir/darcs-git/$remote-git-map
205 darcs_map=$git_dir/darcs-git/$remote-darcs-map
206 if [ ! -f $git_map -o ! -f $darcs_map ]
207 then
208 echo "Missing mappings for remote $remote"
209 return 1
210 fi
211 for row in `sed -n -e "/:.* $sha1.*/ s/[^ ]*/&/p" $git_map`
212 do
213 sed -n -e "/$row / {s/[^ ]*//; s/.*/$remote\t&/p}" $darcs_map
214 done
215 done
216}
217
218# Find the git commit(s) supporting a darcs patch prefix
219find_git()
220{
221 patch="$1"
222 shift
223 if [ -z "$patch" -o -n "$*" ]
224 then
225 echo "Usage: git darcs find-git <patch-prefix>"
226 return 1
227 fi
228 for remote in $(git for-each-ref --format='%(refname)' refs/remotes/darcs)
229 do
230 remote=`basename $remote`
231 git_map=$git_dir/darcs-git/$remote-git-map
232 darcs_map=$git_dir/darcs-git/$remote-darcs-map
233 if [ ! -f $git_map -o ! -f $darcs_map ]
234 then
235 echo "Missing mappings for remote $remote"
236 return 1
237 fi
238 for row in `sed -n -e "/:.* $patch.*/ s/[^ ]*/&/p" $darcs_map`
239 do
240 sed -n -e "/$row / {s/[^ ]* \(.*\)/$remote\t\1/p}" $git_map
241 done
242 done
243}
244
245git rev-parse 2> /dev/null
246if [ $? != 0 ]; then
247 echo "Must be inside a git repository to work"
248 exit 1
249fi
250
251git_dir=$(git rev-parse --git-dir)
252# make it absolute
253cd $git_dir
254git_dir=$(pwd)
255cd - >/dev/null
256command="$1"
257shift
258
259case $command in
260 add|push|fetch|pull|list)
261 ;;
262 find-darcs)
263 command=find_darcs
264 ;;
265 find-git)
266 command=find_git
267 ;;
268 *)
269 echo "Usage: git darcs [COMMAND] [OPTIONS]"
270 echo "Commands: add, push, fetch, pull, list, find-darcs, find-git"
271 exit 1
272 ;;
273esac
274
275
276up=$(git rev-parse --show-cdup)
277[ -z "$up" ] && up="."
278cd $up
279$command "$@"
2800
=== removed file 'exporters/darcs/git-darcs.txt'
--- exporters/darcs/git-darcs.txt 2010-03-17 00:09:30 +0000
+++ exporters/darcs/git-darcs.txt 1970-01-01 00:00:00 +0000
@@ -1,92 +0,0 @@
1= git-darcs(1)
2
3== NAME
4
5git-darcs - a bidirectional git - darcs gateway
6
7== SYNOPSIS
8
9git-darcs <command> <options>
10
11== DESCRIPTION
12
13git darcs can convert a darcs repo to a git one, can update such an
14existing git repo later, and finally can push back your changes from the
15git repo to the darcs one.
16
17A typical workflow is:
18
19----
20$ mkdir git-repo
21$ cd git-repo
22$ git init
23$ git darcs add upstream /path/to/darcs-repo
24$ git darcs pull upstream
25
26... hack, hack, hack ...
27
28$ git darcs push upstream
29----
30
31== GLOBAL OPTIONS
32
33-h, --help::
34 Display usage.
35
36== COMMANDS
37
38The supported commands are the followings:
39
40add::
41 This can register a new darcs repo in the git one, so that you
42 can fetch from it. The syntax is `add nick path [dfe-options]`.
43 Add any options you want to be passed to darcs-fast-export,
44 like --encoding=utf-8, or --authors-file AUTHORMAP. Remember
45 that if AUTHORMAP is not absolute, it will be interpreted
46 relative to the git repository's root directory.
47
48push::
49 Transfers your changes created in the current branch back the
50 darcs one. The syntax is `push nick`.
51
52fetch::
53 Downloads changes from the darcs repo and updates the
54 `darcs/<nick>` branch. None of your local branches are updated.
55
56pull::
57 Calls `fetch` then `git merge` or `git rebase` based on the
58 `branch.<branchname>.rebase` configuration setting, where `<branchname>`
59 is the current branch. The default is - just like with `git pull` - is
60 to `git merge`.
61
62list::
63 List the name [and location] of each registered darcs repo.
64 The syntax is `list [-v|--verbose]`.
65
66find-darcs::
67 Searches for darcs patches matching a SHA1 prefix.
68 The syntax is `find-darcs <sha1-prefix>`.
69
70find-git::
71 Searches for git commits matching a darcs patch prefix.
72 The syntax is `find-git <patch-prefix>`.
73
74== HOOKS
75
76It's possible to automatically run before and after the fetch and the
77push subcommand. For example if you want to automatically run `darcs
78pull -a` before a `git darcs fetch upstream`:
79
80----
81git config git-darcs.upstream.pre-fetch "darcs pull -a --repodir=/path/to/darcs-repo"
82----
83
84Or in case you want to automatically `darcs send` all patches after a
85`git darcs push upstream`:
86
87----
88git config git-darcs.upstream.post-push "darcs send -a --repodir=/path/to/darcs-repo"
89----
90
91== SEE-ALSO
92*git*(1), *darcs*(1)
930
=== removed directory 'exporters/darcs/t'
=== removed file 'exporters/darcs/t/Makefile'
--- exporters/darcs/t/Makefile 2008-11-11 00:38:24 +0000
+++ exporters/darcs/t/Makefile 1970-01-01 00:00:00 +0000
@@ -1,9 +0,0 @@
1T = $(wildcard test*.sh)
2
3all: $(T)
4 @echo "passed $$(echo $(T)|wc -w) tests."
5
6$(T):
7 @echo "*** $@ ***"; sh $@
8
9.PHONY: $(T)
100
=== removed directory 'exporters/darcs/t/bench-results'
=== removed file 'exporters/darcs/t/bench-results/Makefile'
--- exporters/darcs/t/bench-results/Makefile 2008-12-26 00:36:08 +0000
+++ exporters/darcs/t/bench-results/Makefile 1970-01-01 00:00:00 +0000
@@ -1,5 +0,0 @@
1bench-results.png: bench-results.gnu bench-results.dat
2 gnuplot bench-results.gnu
3
4bench-results.dat: bench-results.py $(wildcard ../darcs-benchmark/big-zoo/*.log)
5 python bench-results.py > bench-results.dat
60
=== removed file 'exporters/darcs/t/bench-results/bench-results.gnu'
--- exporters/darcs/t/bench-results/bench-results.gnu 2008-12-26 00:36:08 +0000
+++ exporters/darcs/t/bench-results/bench-results.gnu 1970-01-01 00:00:00 +0000
@@ -1,6 +0,0 @@
1set terminal png
2set output 'bench-results.png'
3unset key
4set xlabel "number of patches"
5set ylabel "elapsed time in hours"
6plot 'bench-results.dat' with linespoints
70
=== removed file 'exporters/darcs/t/bench-results/bench-results.py'
--- exporters/darcs/t/bench-results/bench-results.py 2008-12-26 00:36:08 +0000
+++ exporters/darcs/t/bench-results/bench-results.py 1970-01-01 00:00:00 +0000
@@ -1,23 +0,0 @@
1from glob import glob
2import re
3
4def cmp_data(a, b):
5 return cmp(a[0], b[0])
6
7logs = glob("../darcs-benchmark/big-zoo/*.log")
8
9data = []
10
11for i in logs:
12 sock = open(i)
13 for j in sock.readlines():
14 if "Num Patches:" in j:
15 patches = int(j.split(": ")[1].strip())
16 elif j.startswith("real"):
17 l = re.sub("real\t([0-9]+)m([0-9.]+)s\n", r"\1 \2", j).split(" ")
18 secs = int(l[0])*60 + float(l[1])
19 hours = secs / 3600
20 data.append([patches, hours])
21data.sort(cmp=cmp_data)
22for i in data:
23 print "%s %s" % (i[0], i[1])
240
=== removed file 'exporters/darcs/t/bench-tailor.sh'
--- exporters/darcs/t/bench-tailor.sh 2008-11-29 13:34:30 +0000
+++ exporters/darcs/t/bench-tailor.sh 1970-01-01 00:00:00 +0000
@@ -1,59 +0,0 @@
1#!/bin/sh
2
3create_config()
4{
5 cd $1
6 mypath=$(pwd)
7 cd - >/dev/null
8 myname=$(basename $mypath)
9
10 cat > config << EOF
11[DEFAULT]
12encoding-errors-policy = replace
13
14[$myname]
15source = darcs:$myname
16target = git:$myname
17
18[darcs:$myname]
19subdir = darcs
20repository = $mypath
21
22[git:$myname]
23subdir = git
24repository = $mypath.git
25EOF
26}
27
28PATH=$HOME/darcs/tailor:$PATH
29if [ ! -d darcs-benchmark ]; then
30 darcs get http://code.haskell.org/darcs/darcs-benchmark
31 cd darcs-benchmark
32else
33 cd darcs-benchmark
34 darcs pull -a
35fi
36sh initialise.sh
37cd big-zoo
38if [ -n "$1" ]; then
39 targets=$1
40else
41 targets=*_play.tar.gz
42fi
43for i in $targets
44do
45 echo "benchmarking $i"
46 rm -rf _playground
47 tar xf $i
48 cd _playground
49 log="../$i.tailor-$(tailor --version).log"
50 create_config sandbox
51 sh -c 'time tailor --configfile config' 2>&1 |tee $log
52 if diff --exclude _darcs --exclude .git -Nur sandbox git >/dev/null; then
53 echo "ok, the result is correct" >> $log
54 else
55 echo "ouch, the result is corrupted" >> $log
56 exit 1
57 fi
58 cd ..
59done
600
=== removed file 'exporters/darcs/t/bench.sh'
--- exporters/darcs/t/bench.sh 2008-12-25 23:50:21 +0000
+++ exporters/darcs/t/bench.sh 1970-01-01 00:00:00 +0000
@@ -1,38 +0,0 @@
1#!/bin/sh
2
3# this is a test as well, but it would take a lot of time, so don't
4# prefix it with 'test'.
5
6. lib.sh
7
8if [ ! -d darcs-benchmark ]; then
9 darcs get http://code.haskell.org/darcs/darcs-benchmark
10 cd darcs-benchmark
11else
12 cd darcs-benchmark
13 darcs pull -a
14fi
15sh initialise.sh
16cd big-zoo
17if [ -n "$1" ]; then
18 targets=$1
19else
20 targets=*_play.tar.gz
21fi
22for i in $targets
23do
24 echo "benchmarking $i"
25 rm -rf _playground
26 tar xf $i
27 cd _playground
28 log="../$i.d-f-e-$(git describe).log"
29 sh -c 'time d2x -f git sandbox' 2>&1 |tee $log
30 darcs show repo --repodir sandbox |egrep -v 'Root|Cache|Default' >> $log
31 if diff_git sandbox >/dev/null; then
32 echo "ok, the result is correct" >> $log
33 else
34 echo "ouch, the result is corrupted" >> $log
35 exit 1
36 fi
37 cd ..
38done
390
=== removed directory 'exporters/darcs/t/data'
=== removed file 'exporters/darcs/t/data/hungarian.gif'
40Binary files exporters/darcs/t/data/hungarian.gif 2008-11-11 00:27:43 +0000 and exporters/darcs/t/data/hungarian.gif 1970-01-01 00:00:00 +0000 differ1Binary files exporters/darcs/t/data/hungarian.gif 2008-11-11 00:27:43 +0000 and exporters/darcs/t/data/hungarian.gif 1970-01-01 00:00:00 +0000 differ
=== removed file 'exporters/darcs/t/lib-httpd.sh'
--- exporters/darcs/t/lib-httpd.sh 2009-10-22 10:26:11 +0000
+++ exporters/darcs/t/lib-httpd.sh 1970-01-01 00:00:00 +0000
@@ -1,67 +0,0 @@
1#!/bin/sh
2#
3# This is based on git's t/lib-httpd.sh, which is
4# Copyright (c) 2008 Clemens Buchacher <drizzd@aon.at>
5#
6
7if test -n "$DFE_TEST_SKIP_HTTPD"
8then
9 echo "skipping test (undef DFE_TEST_SKIP_HTTPD to enable)"
10 exit
11fi
12
13LIB_HTTPD_PATH=${LIB_HTTPD_PATH-'/usr/sbin/httpd'}
14LIB_HTTPD_PORT=${LIB_HTTPD_PORT-'8111'}
15
16HTTPD_ROOT_PATH="$PWD"/httpd
17HTTPD_DOCUMENT_ROOT_PATH=$HTTPD_ROOT_PATH/www
18
19if ! test -x "$LIB_HTTPD_PATH"
20then
21 echo "skipping test, no web server found at '$LIB_HTTPD_PATH'"
22 exit
23fi
24
25HTTPD_VERSION=`$LIB_HTTPD_PATH -v | \
26 sed -n 's/^Server version: Apache\/\([0-9]*\)\..*$/\1/p; q'`
27
28if test -n "$HTTPD_VERSION"
29then
30 if test -z "$LIB_HTTPD_MODULE_PATH"
31 then
32 if ! test $HTTPD_VERSION -ge 2
33 then
34 echo "skipping test, at least Apache version 2 is required"
35 exit
36 fi
37
38 LIB_HTTPD_MODULE_PATH='/usr/lib/apache'
39 fi
40else
41 error "Could not identify web server at '$LIB_HTTPD_PATH'"
42fi
43
44HTTPD_PARA="-d $HTTPD_ROOT_PATH -f $HTTPD_ROOT_PATH/apache.conf"
45
46prepare_httpd() {
47 mkdir -p $HTTPD_DOCUMENT_ROOT_PATH
48
49 ln -s $LIB_HTTPD_MODULE_PATH $HTTPD_ROOT_PATH/modules
50
51 echo "PidFile httpd.pid" > $HTTPD_ROOT_PATH/apache.conf
52 echo "DocumentRoot www" >> $HTTPD_ROOT_PATH/apache.conf
53 echo "ErrorLog error.log" >> $HTTPD_ROOT_PATH/apache.conf
54
55 HTTPD_URL=http://127.0.0.1:$LIB_HTTPD_PORT
56}
57
58start_httpd() {
59 prepare_httpd
60
61 "$LIB_HTTPD_PATH" $HTTPD_PARA \
62 -c "Listen 127.0.0.1:$LIB_HTTPD_PORT" -k start
63}
64
65stop_httpd() {
66 "$LIB_HTTPD_PATH" $HTTPD_PARA -k stop
67}
680
=== removed file 'exporters/darcs/t/lib.sh'
--- exporters/darcs/t/lib.sh 2010-07-28 01:33:33 +0000
+++ exporters/darcs/t/lib.sh 1970-01-01 00:00:00 +0000
@@ -1,337 +0,0 @@
1export DARCS_EMAIL="user@example.com"
2export GIT_PAGER=cat
3export PATH="$(pwd)/..:$PATH"
4pypath="/$(python -c 'from distutils import sysconfig; print sysconfig.get_python_lib()[1:]')/"
5
6_drrec()
7{
8 darcs rec --ignore-times "$@"
9}
10
11_drrec_multiline()
12{
13 echo -e "`LANG= LC_ALL= date +"%a %b %d %H:%M:%S %Z %Y"`
14$DARCS_EMAIL
15$@" | darcs rec --ignore-times -a --pipe .
16}
17
18_drrecamend()
19{
20 echo y |darcs amend-rec --ignore-times -a
21}
22
23create_darcs()
24{
25 rm -rf $1
26 mkdir -p $1
27 cd $1
28 darcs init $2
29 echo A > file
30 darcs add file
31 _drrec -a -m A
32 cd ..
33 rm -rf $1.tmp
34 darcs get $1 $1.tmp
35 cd $1
36 echo B > file
37 _drrec -a -m B
38 cd ../$1.tmp
39 echo C > file
40 _drrec -a -m C
41 cd ../$1
42 darcs pull -a ../$1.tmp
43 echo D > file
44 _drrec_multiline "first line
45second line
46third line"
47 darcs tag 1.0
48 echo e > file
49 _drrec -a -m e
50 echo f > file
51 _drrec --author="éáõû <$DARCS_EMAIL>" -a -m f
52 echo g > file
53 _drrec --author="" -a -m g
54 cp ../data/hungarian.gif .
55 darcs add hungarian.gif
56 _drrec -a -m "add a binary file"
57 rm file
58 echo test > file2
59 darcs add file2
60 _drrec -a -m "replace file with file2"
61 touch file3
62 darcs add file3
63 _drrec -a -m "add empty file"
64 rm file3
65 _drrec -a -m "remove file"
66 mkdir dir dir2
67 darcs add dir
68 darcs add dir2
69 _drrec -a -m "add empty dirs"
70 darcs mv dir dir-p
71 darcs mv dir2 dir2-p
72 _drrec -a -m "rename empty dirs"
73 echo a > a
74 echo b > b
75 darcs add a b
76 _drrec -a -m "add a b"
77 rm b
78 _drrec -a -m "remove and rename"
79 darcs mv a b
80 _drrecamend
81 echo c > c
82 darcs add c
83 # empty commit message
84 _drrec -a -m ""
85 cd ..
86}
87
88create_bzr()
89{
90 rm -rf $1
91 mkdir -p $1
92 cd $1
93 bzr init $2
94 echo A > file
95 bzr add file
96 bzr commit -m A
97 cd ..
98 rm -rf $1.tmp
99 bzr branch $1 $1.tmp
100 cd $1
101 echo B > file
102 bzr commit -m B
103 cd ../$1.tmp
104 echo C > file
105 bzr commit -m C
106 cd ../$1
107 bzr merge ../$1.tmp
108 echo D > file
109 bzr resolve file
110 echo "first line
111second line
112third line" | bzr commit -F /dev/stdin
113 bzr tag 1.0
114 echo e > file
115 bzr commit -m e
116 #echo f > file
117 #bzr commit --author="éáõû <$DARCS_EMAIL>" -m f
118 #echo g > file
119 #_drrec --author="" -a -m g
120 cp ../data/hungarian.gif .
121 bzr add hungarian.gif
122 bzr commit -m "add a binary file"
123 rm file
124 echo test > file2
125 bzr add file2
126 bzr commit -m "replace file with file2"
127 touch file3
128 bzr add file3
129 bzr commit -m "add empty file"
130 rm file3
131 bzr commit -m "remove file"
132 cd ..
133}
134
135create_hg()
136{
137 rm -rf $1
138 mkdir -p $1
139 cd $1
140 hg init $2
141 echo A > file
142 hg add file
143 hg commit -m A
144 cd ..
145 rm -rf $1.tmp
146 hg clone $1 $1.tmp
147 cd $1
148 echo B > file
149 hg commit -m B
150 cd ../$1.tmp
151 echo C > file
152 hg commit -m C
153 cd ../$1
154 hg pull ../$1.tmp
155 hg merge
156 echo D > file
157 hg resolve -m file
158 echo "first line
159second line
160third line" | hg commit -l /dev/stdin
161 hg tag 1.0
162 echo e > file
163 hg commit -m e
164 #echo f > file
165 #bzr commit --author="éáõû <$DARCS_EMAIL>" -m f
166 #echo g > file
167 #_drrec --author="" -a -m g
168 cp ../data/hungarian.gif .
169 hg add hungarian.gif
170 hg commit -m "add a binary file"
171 hg rm file
172 echo test > file2
173 hg add file2
174 hg commit -m "replace file with file2"
175 touch file3
176 hg add file3
177 hg commit -m "add empty file"
178 hg rm file3
179 hg commit -m "remove file"
180 mkdir subdir
181 echo test > subdir/file
182 hg add subdir/file
183 hg commit -m "add subdir file"
184 echo test2 > subdir/file
185 hg commit -m "commit with weird date" -d "Fri Apr 03 12:38:26 2009 +1300"
186 cd ..
187}
188create_git()
189{
190 rm -rf $1
191 mkdir -p $1
192 cd $1
193 git init $2
194 git commit --allow-empty -m 'root commit'
195 echo A > file
196 git add file
197 git commit -a -m A
198 echo B > file
199 git commit -a -m B
200 git checkout -b tmp HEAD~1
201 echo C > file
202 git commit -a -m C
203 git checkout master
204 git merge tmp
205 echo D > file
206 echo "first line
207second line
208third line" | git commit -a -F -
209 git branch -d tmp
210 git tag 1.0
211 echo e > file
212 git commit -a -m e
213 echo f > file
214 git config i18n.commitencoding ISO-8859-2
215 git commit --author="éáõû <$DARCS_EMAIL>" -a -m f
216 cp ../data/hungarian.gif .
217 git add hungarian.gif
218 git commit -a -m "add a binary file"
219 rm file
220 echo test > file2
221 git add file2
222 git commit -a -m "replace file with file2"
223 touch file3
224 git add file3
225 git commit -a -m "add empty file"
226 rm file3
227 git commit -a -m "remove file"
228 # now add back 'file' with its old conents, so the mark gets
229 # reused
230 echo f > file
231 git add file
232 git commit -a -m "file: other -> f"
233 # this is a boring file for Darcs
234 touch foo.pyc
235 git add foo.pyc
236 git commit -a -m "boring file"
237 # replace an uppercase file to a lowercase one
238 echo SPAM > SPAM
239 git add SPAM
240 git commit -a -m SPAM
241 rm SPAM
242 echo spam > spam
243 git add spam
244 git commit -a -m "SPAM -> spam"
245 cd ..
246}
247
248diff_git()
249{
250 rm -rf $1.git.nonbare
251 git clone -q $1.git $1.git.nonbare
252 diff --exclude _darcs --exclude .git --exclude '*-darcs-backup*' -Nur $1.git.nonbare $1
253 return $?
254}
255
256diff_importgit()
257{
258 test -z "`(cd $1.darcs; darcs diff)`" &&
259 diff --exclude _darcs --exclude .git --exclude '*-darcs-backup*' -Nur $1 $1.darcs
260 return $?
261}
262
263diff_importhg()
264{
265 cd $1.darcs && test -z "`darcs diff 2>&1`" && cd .. &&
266 diff --exclude _darcs --exclude .hg --exclude '*-darcs-backup*' --exclude 'hg-export.*' \
267 --exclude '.hgtags' --exclude '*.orig' -Nur $1 $1.darcs
268 return $?
269}
270
271diff_importdarcs()
272{
273 cd $1.importdarcs && test -z "`darcs diff 2>&1`" && cd .. &&
274 diff --exclude _darcs --exclude '*-darcs-backup*' -Nur $1 $2
275 return $?
276}
277
278diff_importbzr()
279{
280 cd $1.darcs && test -z "`darcs diff 2>&1`" && cd .. &&
281 diff --exclude _darcs --exclude .bzr --exclude '*-darcs-backup*' -Nur $1 $1.darcs
282 return $?
283}
284
285diff_bzr()
286{
287 cd $1.bzr/trunk
288 bzr update
289 cd - >/dev/null
290 diff --exclude _darcs --exclude .bzr --exclude '*-darcs-backup*' -Nur $1.bzr/trunk $1
291 return $?
292}
293
294diff_hg()
295{
296 hg -R $1.hg update
297 diff --exclude _darcs --exclude .hg --exclude '*-darcs-backup*' -Nur $1.hg $1
298 return $?
299}
300
301die()
302{
303 echo "fatal: $@"
304 exit 1
305}
306
307upd_file_darcs()
308{
309 cd $1
310 echo $3 > $2
311 _drrec -a -m "updated '$2' to '$3'"
312 cd ..
313}
314
315upd_file_git()
316{
317 cd $1
318 echo $3 > $2
319 git commit -a -m "updated '$2' to '$3'"
320 cd ..
321}
322
323upd_file_bzr()
324{
325 cd $1
326 echo $3 > $2
327 bzr commit -m "updated '$2' to '$3'"
328 cd ..
329}
330
331upd_file_hg()
332{
333 cd $1
334 echo $3 > $2
335 hg commit -m "updated '$2' to '$3'"
336 cd ..
337}
3380
=== removed directory 'exporters/darcs/t/test'
=== removed file 'exporters/darcs/t/test-bzr.sh'
--- exporters/darcs/t/test-bzr.sh 2009-08-10 22:19:29 +0000
+++ exporters/darcs/t/test-bzr.sh 1970-01-01 00:00:00 +0000
@@ -1,16 +0,0 @@
1. ./lib.sh
2
3create_darcs test --old-fashioned-inventory
4
5rm -rf test.darcs test.bzr
6mkdir test.bzr
7cd test.bzr
8bzr init-repo .
9cd ..
10if [ "$1" != "--stdout" ]; then
11 darcs-fast-export test |(cd test.bzr; bzr fast-import -)
12 diff_bzr test
13 exit $?
14else
15 darcs-fast-export test
16fi
170
=== removed file 'exporters/darcs/t/test-git-d2x.sh'
--- exporters/darcs/t/test-git-d2x.sh 2009-08-10 22:19:29 +0000
+++ exporters/darcs/t/test-git-d2x.sh 1970-01-01 00:00:00 +0000
@@ -1,19 +0,0 @@
1. ./lib.sh
2
3create_darcs test --old-fashioned-inventory
4
5rm -rf test.git
6if [ "$1" != "--stdout" ]; then
7 d2x -f git test
8 diff_git test || die "initial conversion differs"
9 upd_file_darcs test file2 upd_contents
10 d2x -f git test
11 diff_git test || die "update differs"
12 upd_file_darcs test hungarian.gif "binary to text"
13 d2x -f git test
14 diff_git test || die "update2 differs"
15 d2x -f git test
16 diff_git test || die "update3 (noop) differs"
17else
18 darcs-fast-export test
19fi
200
=== removed file 'exporters/darcs/t/test-git-incremental.sh'
--- exporters/darcs/t/test-git-incremental.sh 2009-08-10 22:19:29 +0000
+++ exporters/darcs/t/test-git-incremental.sh 1970-01-01 00:00:00 +0000
@@ -1,24 +0,0 @@
1. ./lib.sh
2
3create_darcs test --old-fashioned-inventory
4
5rm -rf test.darcs test.git
6mkdir test.git
7cd test.git
8git --bare init
9cd ..
10if [ "$1" != "--stdout" ]; then
11 dmark="$(pwd)/test.dfe-marks"
12 gmark="$(pwd)/test.gfi-marks"
13 rm -f $mark $gmark
14 darcs-fast-export --export-marks=$dmark test |(cd test.git; git fast-import --export-marks=$gmark)
15 diff_git test || die "initial conversion differs"
16 upd_file_darcs test file2 upd_contents
17 darcs-fast-export --export-marks=$dmark --import-marks=$dmark test |(cd test.git; git fast-import --export-marks=$gmark --import-marks=$gmark)
18 diff_git test || die "update differs"
19 upd_file_darcs test hungarian.gif "binary to text"
20 darcs-fast-export --export-marks=$dmark --import-marks=$dmark test |(cd test.git; git fast-import --export-marks=$gmark --import-marks=$gmark)
21 diff_git test || die "update2 differs"
22else
23 darcs-fast-export test
24fi
250
=== removed file 'exporters/darcs/t/test-git-progress.sh'
--- exporters/darcs/t/test-git-progress.sh 2009-08-10 22:19:29 +0000
+++ exporters/darcs/t/test-git-progress.sh 1970-01-01 00:00:00 +0000
@@ -1,18 +0,0 @@
1. ./lib.sh
2
3create_darcs test --old-fashioned-inventory
4
5rm -rf test.darcs test.git
6mkdir test.git
7cd test.git
8git --bare init
9cd ..
10if [ "$1" != "--stdout" ]; then
11 darcs-fast-export --progres 2 test |(cd test.git; git fast-import)
12 if [ $? = 0 ]; then
13 diff_git test
14 exit $?
15 fi
16else
17 darcs-fast-export test
18fi
190
=== removed file 'exporters/darcs/t/test-git.sh'
--- exporters/darcs/t/test-git.sh 2009-08-10 22:19:29 +0000
+++ exporters/darcs/t/test-git.sh 1970-01-01 00:00:00 +0000
@@ -1,18 +0,0 @@
1. ./lib.sh
2
3create_darcs test --old-fashioned-inventory
4
5rm -rf test.darcs test.git
6mkdir test.git
7cd test.git
8git --bare init
9cd ..
10if [ "$1" != "--stdout" ]; then
11 darcs-fast-export test |(cd test.git; git fast-import)
12 if [ $? = 0 ]; then
13 diff_git test
14 exit $?
15 fi
16else
17 darcs-fast-export test
18fi
190
=== removed file 'exporters/darcs/t/test-hg-d2x.sh'
--- exporters/darcs/t/test-hg-d2x.sh 2009-08-10 22:19:29 +0000
+++ exporters/darcs/t/test-hg-d2x.sh 1970-01-01 00:00:00 +0000
@@ -1,12 +0,0 @@
1. ./lib.sh
2
3create_darcs test --old-fashioned-inventory
4
5rm -rf test.hg
6if [ "$1" != "--stdout" ]; then
7 d2x -f hg test
8 diff_hg test
9 exit $?
10else
11 darcs-fast-export test
12fi
130
=== removed file 'exporters/darcs/t/test-hg.sh'
--- exporters/darcs/t/test-hg.sh 2009-09-09 01:12:40 +0000
+++ exporters/darcs/t/test-hg.sh 1970-01-01 00:00:00 +0000
@@ -1,16 +0,0 @@
1. ./lib.sh
2
3create_darcs test --old-fashioned-inventory
4
5rm -rf test.darcs test.hg
6mkdir test.hg
7cd test.hg
8hg init
9cd ..
10if [ "$1" != "--stdout" ]; then
11 darcs-fast-export test |(cd test.hg; hg fastimport -)
12 diff_hg test
13 exit $?
14else
15 darcs-fast-export test
16fi
170
=== removed directory 'exporters/darcs/t/test/_darcs'
=== removed directory 'exporters/darcs/t/test/_darcs/patches'
=== removed directory 'exporters/darcs/t/test/_darcs/prefs'
=== removed directory 'exporters/darcs/t/test/_darcs/pristine'
=== removed directory 'exporters/darcs/t/test2'
=== removed file 'exporters/darcs/t/test2-bzr-d2x.sh'
--- exporters/darcs/t/test2-bzr-d2x.sh 2009-08-10 22:19:29 +0000
+++ exporters/darcs/t/test2-bzr-d2x.sh 1970-01-01 00:00:00 +0000
@@ -1,19 +0,0 @@
1. ./lib.sh
2
3create_darcs test2 --darcs-2
4
5rm -rf test2.bzr
6if [ "$1" != "--stdout" ]; then
7 d2x -f bzr test2
8 diff_bzr test2 || die "initial conversion differs"
9 upd_file_darcs test2 file2 upd_contents
10 d2x -f bzr test2
11 diff_bzr test2 || die "update differs"
12 upd_file_darcs test2 hungarian.gif "binary to text"
13 d2x -f bzr test2
14 diff_bzr test2 || die "update2 differs"
15 d2x -f bzr test2
16 diff_bzr test2 || die "update3 (noop) differs"
17else
18 darcs-fast-export test2
19fi
200
=== removed file 'exporters/darcs/t/test2-bzr-incremental.sh'
--- exporters/darcs/t/test2-bzr-incremental.sh 2009-08-10 22:19:29 +0000
+++ exporters/darcs/t/test2-bzr-incremental.sh 1970-01-01 00:00:00 +0000
@@ -1,21 +0,0 @@
1. ./lib.sh
2
3create_darcs test2 --darcs-2
4
5rm -rf test2.darcs test2.bzr
6mkdir test2.bzr
7cd test2.bzr
8bzr init-repo .
9cd ..
10if [ "$1" != "--stdout" ]; then
11 dmark="$(pwd)/test2.dfe-marks"
12 bmark="$(pwd)/test2.bfi-marks"
13 rm -f $mark $gmark
14 darcs-fast-export --export-marks=$dmark test2 |(cd test2.bzr; bzr fast-import --export-marks=$bmark -)
15 diff_bzr test2 || die "initial conversion differs"
16 upd_file_darcs test2 file2 upd_contents
17 darcs-fast-export --export-marks=$dmark --import-marks=$dmark test2 |(cd test2.bzr; bzr fast-import --export-marks=$bmark --import-marks=$bmark -)
18 diff_bzr test2 || die "update differs"
19else
20 darcs-fast-export test2
21fi
220
=== removed file 'exporters/darcs/t/test2-git-funny-tagname.sh'
--- exporters/darcs/t/test2-git-funny-tagname.sh 2009-08-10 22:19:29 +0000
+++ exporters/darcs/t/test2-git-funny-tagname.sh 1970-01-01 00:00:00 +0000
@@ -1,25 +0,0 @@
1. ./lib.sh
2
3create_darcs test2 --darcs-2
4cd test2
5darcs tag "this :just (won't work; die)"
6darcs tag "accent-tag-éáőű"
7cd ..
8
9rm -rf test2.darcs test2.git
10mkdir test2.git
11cd test2.git
12git --bare init
13cd ..
14if [ "$1" != "--stdout" ]; then
15 darcs-fast-export test2 |(cd test2.git; git fast-import)
16 ret=$?
17 if [ $ret = 0 ]; then
18 diff_git test2
19 exit $?
20 else
21 exit $ret
22 fi
23else
24 darcs-fast-export test2
25fi
260
=== removed file 'exporters/darcs/t/test2-git-http.sh'
--- exporters/darcs/t/test2-git-http.sh 2009-10-22 10:26:11 +0000
+++ exporters/darcs/t/test2-git-http.sh 1970-01-01 00:00:00 +0000
@@ -1,22 +0,0 @@
1. ./lib.sh
2. ./lib-httpd.sh
3
4rm -rf test2.darcs test2.git httpd
5create_darcs test2 --darcs-2
6mkdir -p $HTTPD_DOCUMENT_ROOT_PATH
7mv -v test2 $HTTPD_DOCUMENT_ROOT_PATH
8ln -s $HTTPD_DOCUMENT_ROOT_PATH/test2 .
9
10mkdir test2.git
11cd test2.git
12git --bare init
13cd ..
14start_httpd
15darcs-fast-export $HTTPD_URL/test2 |(cd test2.git; git fast-import)
16ret=$?
17stop_httpd
18if [ $ret != 0 ]; then
19 exit $ret
20fi
21diff_git test2
22exit $?
230
=== removed file 'exporters/darcs/t/test2-git-incremental-specworkdir.sh'
--- exporters/darcs/t/test2-git-incremental-specworkdir.sh 2009-08-10 22:19:29 +0000
+++ exporters/darcs/t/test2-git-incremental-specworkdir.sh 1970-01-01 00:00:00 +0000
@@ -1,22 +0,0 @@
1. ./lib.sh
2
3create_darcs test2 --darcs-2
4
5rm -rf test2.darcs test2.git
6mkdir test2.git
7cd test2.git
8git --bare init
9mkdir darcs
10cd ..
11if [ "$1" != "--stdout" ]; then
12 dmark="$(pwd)/test2.git/darcs/test2.dfe-marks"
13 gmark="$(pwd)/test2.git/darcs/test2.gfi-marks"
14 rm -f $mark $gmark
15 darcs-fast-export --export-marks=$dmark test2 --working test2.git/darcs/repo |(cd test2.git; git fast-import --export-marks=$gmark)
16 diff_git test2 || die "initial conversion differs"
17 upd_file_darcs test2 file2 upd_contents
18 darcs-fast-export --export-marks=$dmark --import-marks=$dmark test2 --working test2.git/darcs/repo |(cd test2.git; git fast-import --export-marks=$gmark --import-marks=$gmark)
19 diff_git test2 || die "update differs"
20else
21 darcs-fast-export test2
22fi
230
=== removed file 'exporters/darcs/t/test2-git-incremental.sh'
--- exporters/darcs/t/test2-git-incremental.sh 2009-08-10 22:19:29 +0000
+++ exporters/darcs/t/test2-git-incremental.sh 1970-01-01 00:00:00 +0000
@@ -1,21 +0,0 @@
1. ./lib.sh
2
3create_darcs test2 --darcs-2
4
5rm -rf test2.darcs test2.git
6mkdir test2.git
7cd test2.git
8git --bare init
9cd ..
10if [ "$1" != "--stdout" ]; then
11 dmark="$(pwd)/test2.dfe-marks"
12 gmark="$(pwd)/test2.gfi-marks"
13 rm -f $mark $gmark
14 darcs-fast-export --export-marks=$dmark test2 |(cd test2.git; git fast-import --export-marks=$gmark)
15 diff_git test2 || die "initial conversion differs"
16 upd_file_darcs test2 file2 upd_contents
17 darcs-fast-export --export-marks=$dmark --import-marks=$dmark test2 |(cd test2.git; git fast-import --export-marks=$gmark --import-marks=$gmark)
18 diff_git test2 || die "update differs"
19else
20 darcs-fast-export test2
21fi
220
=== removed file 'exporters/darcs/t/test2-git.sh'
--- exporters/darcs/t/test2-git.sh 2009-08-10 22:19:29 +0000
+++ exporters/darcs/t/test2-git.sh 1970-01-01 00:00:00 +0000
@@ -1,18 +0,0 @@
1. ./lib.sh
2
3create_darcs test2 --darcs-2
4
5rm -rf test2.darcs test2.git
6mkdir test2.git
7cd test2.git
8git --bare init
9cd ..
10if [ "$1" != "--stdout" ]; then
11 darcs-fast-export test2 |(cd test2.git; git fast-import)
12 if [ $? = 0 ]; then
13 diff_git test2
14 exit $?
15 fi
16else
17 darcs-fast-export test2
18fi
190
=== removed directory 'exporters/darcs/t/test2/_darcs'
=== removed directory 'exporters/darcs/t/test2/_darcs/inventories'
=== removed directory 'exporters/darcs/t/test2/_darcs/patches'
=== removed directory 'exporters/darcs/t/test2/_darcs/prefs'
=== removed directory 'exporters/darcs/t/test2/_darcs/pristine.hashed'
=== removed file 'exporters/darcs/t/testimport-bzr-x2d.sh'
--- exporters/darcs/t/testimport-bzr-x2d.sh 2009-08-10 22:19:29 +0000
+++ exporters/darcs/t/testimport-bzr-x2d.sh 1970-01-01 00:00:00 +0000
@@ -1,15 +0,0 @@
1. ./lib.sh
2
3create_bzr test
4
5rm -rf test.darcs
6x2d -f bzr test
7diff_importbzr test || die "initial conversion differs"
8upd_file_bzr test file2 upd_contents
9x2d -f bzr test
10diff_importbzr test || die "update differs"
11upd_file_bzr test hungarian.gif "binary to text"
12x2d -f bzr test
13diff_importbzr test || die "update2 differs"
14x2d -f bzr test
15diff_importbzr test || die "update3 (noop) differs"
160
=== removed file 'exporters/darcs/t/testimport-bzr.sh'
--- exporters/darcs/t/testimport-bzr.sh 2009-08-10 22:19:29 +0000
+++ exporters/darcs/t/testimport-bzr.sh 1970-01-01 00:00:00 +0000
@@ -1,15 +0,0 @@
1. ./lib.sh
2
3create_bzr test
4
5rm -rf test.darcs
6mkdir test.darcs
7cd test.darcs
8darcs init
9cd ..
10(cd test; bzr fast-export .) | (cd test.darcs; darcs-fast-import)
11if [ $? != 0 ]; then
12 exit 1
13fi
14diff_importbzr test
15exit $?
160
=== removed file 'exporters/darcs/t/testimport-copy.sh'
--- exporters/darcs/t/testimport-copy.sh 2009-08-10 22:19:29 +0000
+++ exporters/darcs/t/testimport-copy.sh 1970-01-01 00:00:00 +0000
@@ -1,26 +0,0 @@
1. ./lib.sh
2
3rm -rf test
4mkdir test
5cd test
6git init
7echo a > file
8git add file
9git commit -m a1
10cp file file2
11git add file2
12git commit -m b
13cd ..
14
15rm -rf test.darcs
16mkdir test.darcs
17cd test.darcs
18darcs init
19cd ..
20(cd test; git fast-export -C -C HEAD) > out
21cat out | (cd test.darcs; darcs-fast-import)
22if [ $? != 0 ]; then
23 exit 1
24fi
25diff_importgit test
26exit $?
270
=== removed file 'exporters/darcs/t/testimport-darcs.sh'
--- exporters/darcs/t/testimport-darcs.sh 2009-08-10 22:19:29 +0000
+++ exporters/darcs/t/testimport-darcs.sh 1970-01-01 00:00:00 +0000
@@ -1,17 +0,0 @@
1. ./lib.sh
2
3create_darcs test2 --darcs-2
4
5rm -rf test2.importdarcs test2.darcs
6mkdir test2.importdarcs
7cd test2.importdarcs
8darcs init
9cd ..
10
11darcs-fast-export test2 | (cd test2.importdarcs; darcs-fast-import)
12
13if [ $? != 0 ]; then
14 exit 1
15fi
16diff_importdarcs test2 test2.importdarcs
17exit $?
180
=== removed file 'exporters/darcs/t/testimport-deleteall.sh'
--- exporters/darcs/t/testimport-deleteall.sh 2009-08-10 22:19:29 +0000
+++ exporters/darcs/t/testimport-deleteall.sh 1970-01-01 00:00:00 +0000
@@ -1,31 +0,0 @@
1. ./lib.sh
2
3rm -rf test
4mkdir test
5cd test
6git init
7echo a > file
8git add file
9echo A > file2
10git add file2
11git commit -m a12
12git rm file*
13echo b>file3
14git add file3
15git commit -m b
16cd ..
17
18rm -rf test.darcs
19mkdir test.darcs
20cd test.darcs
21darcs init
22cd ..
23(cd test; git fast-export --progress=2 HEAD) > out
24sed -i '/^D file$/d' out
25sed -i 's/^D file2$/deleteall/' out
26cat out | (cd test.darcs; darcs-fast-import)
27if [ $? != 0 ]; then
28 exit 1
29fi
30diff_importgit test
31exit $?
320
=== removed file 'exporters/darcs/t/testimport-git-incremental.sh'
--- exporters/darcs/t/testimport-git-incremental.sh 2009-08-10 22:19:29 +0000
+++ exporters/darcs/t/testimport-git-incremental.sh 1970-01-01 00:00:00 +0000
@@ -1,16 +0,0 @@
1. ./lib.sh
2
3create_git test
4
5rm -rf test.darcs
6mkdir test.darcs
7cd test.darcs
8darcs init
9cd ..
10gmark="$(pwd)/test.gfe-marks"
11dmark="$(pwd)/test.dfi-marks"
12(cd test; git fast-export --export-marks=$gmark HEAD) | (cd test.darcs; darcs-fast-import --export-marks=$dmark)
13diff_importgit test || die "initial conversion differs"
14upd_file_git test file2 upd_contents
15(cd test; git fast-export --export-marks=$gmark --import-marks=$gmark HEAD) | (cd test.darcs; darcs-fast-import --export-marks=$dmark --import-marks=$dmark)
16diff_importgit test || die "update differs"
170
=== removed file 'exporters/darcs/t/testimport-git-twoway-gd.sh'
--- exporters/darcs/t/testimport-git-twoway-gd.sh 2009-08-10 22:19:29 +0000
+++ exporters/darcs/t/testimport-git-twoway-gd.sh 1970-01-01 00:00:00 +0000
@@ -1,34 +0,0 @@
1. ./lib.sh
2
3create_darcs test
4
5rm -rf test.git
6mkdir test.git
7cd test.git
8git init
9git darcs add upstream ../test
10git darcs pull upstream
11cd ..
12diff_git test || die "initial fetch differs"
13upd_file_darcs test file2 upd_contents
14cd test.git
15git darcs pull upstream
16cd ..
17diff_git test || die "fetch #1 differs"
18upd_file_git test.git file2 upd_contents2
19cd test.git
20git darcs push upstream
21cd ..
22diff_git test || die "push #1 difers"
23upd_file_darcs test file2 upd_contents3
24upd_file_darcs test file2 upd_contents32
25cd test.git
26git darcs pull upstream
27cd ..
28diff_git test || die "fetch #2 (multiple commits) differs"
29upd_file_git test.git file2 upd_contents4
30upd_file_git test.git file2 upd_contents42
31cd test.git
32git darcs push upstream
33cd ..
34diff_git test || die "push #2 (multiple commits) differs"
350
=== removed file 'exporters/darcs/t/testimport-git-twoway.sh'
--- exporters/darcs/t/testimport-git-twoway.sh 2009-08-10 22:19:29 +0000
+++ exporters/darcs/t/testimport-git-twoway.sh 1970-01-01 00:00:00 +0000
@@ -1,30 +0,0 @@
1. ./lib.sh
2
3create_git test
4
5rm -rf test.darcs
6mkdir test.darcs
7cd test.darcs
8darcs init
9cd ..
10gmark="$(pwd)/test.gmarks"
11dmark="$(pwd)/test.dmarks"
12
13(cd test; git fast-export --export-marks=$gmark HEAD) | (cd test.darcs; darcs-fast-import --export-marks=$dmark)
14diff_importgit test || die "initial conversion differs"
15upd_file_git test file2 upd_contents
16(cd test; git fast-export --export-marks=$gmark --import-marks=$gmark HEAD) | (cd test.darcs; darcs-fast-import --export-marks=$dmark --import-marks=$dmark)
17diff_importgit test || die "git -> darcs update #1 differs"
18upd_file_darcs test.darcs file2 upd_contents2
19darcs-fast-export --export-marks=$dmark --import-marks=$dmark --working test/.git/darcs test.darcs | (cd test; git fast-import --export-marks=$gmark --import-marks=$gmark)
20(cd test; git checkout -f)
21diff_importgit test || die "darcs -> git update #2 differs"
22upd_file_git test file2 upd_contents3
23upd_file_git test file2 upd_contents32
24(cd test; git fast-export --export-marks=$gmark --import-marks=$gmark HEAD) | (cd test.darcs; darcs-fast-import --export-marks=$dmark --import-marks=$dmark)
25diff_importgit test || die "git -> darcs update #3 differs"
26upd_file_darcs test.darcs file2 upd_contents4
27upd_file_darcs test.darcs file2 upd_contents42
28darcs-fast-export --export-marks=$dmark --import-marks=$dmark --working test/.git/darcs test.darcs | (cd test; git fast-import --export-marks=$gmark --import-marks=$gmark)
29(cd test; git checkout -f)
30diff_importgit test || die "darcs -> git update #4 differs"
310
=== removed file 'exporters/darcs/t/testimport-git-x2d.sh'
--- exporters/darcs/t/testimport-git-x2d.sh 2009-08-10 22:19:29 +0000
+++ exporters/darcs/t/testimport-git-x2d.sh 1970-01-01 00:00:00 +0000
@@ -1,15 +0,0 @@
1. ./lib.sh
2
3create_git test
4
5rm -rf test.darcs
6x2d -f git test
7diff_importgit test || die "initial conversion differs"
8upd_file_git test file2 upd_contents
9x2d -f git test
10diff_importgit test || die "update differs"
11upd_file_git test hungarian.gif "binary to text"
12x2d -f git test
13diff_importgit test || die "update2 differs"
14x2d -f git test
15diff_importgit test || die "update3 (noop) differs"
160
=== removed file 'exporters/darcs/t/testimport-git.sh'
--- exporters/darcs/t/testimport-git.sh 2009-08-10 22:19:29 +0000
+++ exporters/darcs/t/testimport-git.sh 1970-01-01 00:00:00 +0000
@@ -1,15 +0,0 @@
1. ./lib.sh
2
3create_git test
4
5rm -rf test.darcs
6mkdir test.darcs
7cd test.darcs
8darcs init
9cd ..
10(cd test; git fast-export --progress=2 HEAD) | (cd test.darcs; darcs-fast-import)
11if [ $? != 0 ]; then
12 exit 1
13fi
14diff_importgit test
15exit $?
160
=== removed file 'exporters/darcs/t/testimport-gitsymlink.sh'
--- exporters/darcs/t/testimport-gitsymlink.sh 2010-06-27 17:37:50 +0000
+++ exporters/darcs/t/testimport-gitsymlink.sh 1970-01-01 00:00:00 +0000
@@ -1,45 +0,0 @@
1. ./lib.sh
2
3create_git test
4cd test
5# add two dirs with the some contents, then remove the second
6# and make it a symlink to the first
7mkdir dira
8echo blabla > dira/file
9echo blablabla > dira/file2
10mkdir dirb
11touch dirb/file
12touch dirb/file2
13git add dira dirb
14git commit -a -m "add dira/dirb"
15rm -rf dirb
16ln -s dira dirb
17git add dirb
18git commit -a -m "change a dir to a symlink"
19cd ..
20
21rm -rf test.darcs
22mkdir test.darcs
23cd test.darcs
24darcs init
25cd ..
26(cd test; git fast-export --progress=2 HEAD) | (cd test.darcs; darcs-fast-import)
27# we *do* want this to fail, but with error code 2. that means that we
28# detected that symlinks are not supported and the user does not get a
29# meaningless exception
30if [ $? != 2 ]; then
31 exit 1
32fi
33
34# now try with the symhack option
35rm -rf test.darcs
36mkdir test.darcs
37cd test.darcs
38darcs init
39cd ..
40(cd test; git fast-export --progress=2 HEAD) | (cd test.darcs; darcs-fast-import --symhack)
41if [ $? != 0 ]; then
42 exit 1
43fi
44diff_importgit test
45exit $?
460
=== removed file 'exporters/darcs/t/testimport-hg-x2d.sh'
--- exporters/darcs/t/testimport-hg-x2d.sh 2009-08-10 22:19:29 +0000
+++ exporters/darcs/t/testimport-hg-x2d.sh 1970-01-01 00:00:00 +0000
@@ -1,15 +0,0 @@
1. ./lib.sh
2
3create_hg test
4
5rm -rf test.darcs
6x2d -f hg test
7diff_importhg test || die "initial conversion differs"
8upd_file_hg test file2 upd_contents
9x2d -f hg test
10diff_importhg test || die "update differs"
11upd_file_hg test hungarian.gif "binary to text"
12x2d -f hg test
13diff_importhg test || die "update2 differs"
14x2d -f hg test
15diff_importhg test || die "update3 (noop) differs"
160
=== removed file 'exporters/darcs/t/testimport-hg.sh'
--- exporters/darcs/t/testimport-hg.sh 2009-09-09 01:12:40 +0000
+++ exporters/darcs/t/testimport-hg.sh 1970-01-01 00:00:00 +0000
@@ -1,15 +0,0 @@
1. ./lib.sh
2
3create_hg test
4
5rm -rf test.darcs
6mkdir test.darcs
7cd test.darcs
8darcs init
9cd ..
10(cd test; $pypath/bzrlib/plugins/fastimport/exporters/hg-fast-export.py -r .) | (cd test.darcs; darcs-fast-import)
11if [ $? != 0 ]; then
12 exit 1
13fi
14diff_importhg test
15exit $?
160
=== removed file 'exporters/darcs/t/testimport-rename.sh'
--- exporters/darcs/t/testimport-rename.sh 2009-08-10 22:19:29 +0000
+++ exporters/darcs/t/testimport-rename.sh 1970-01-01 00:00:00 +0000
@@ -1,25 +0,0 @@
1. ./lib.sh
2
3rm -rf test
4mkdir test
5cd test
6git init
7echo a > file
8git add file
9git commit -m a1
10git mv file file2
11git commit -m b
12cd ..
13
14rm -rf test.darcs
15mkdir test.darcs
16cd test.darcs
17darcs init
18cd ..
19(cd test; git fast-export -M HEAD) > out
20cat out | (cd test.darcs; darcs-fast-import)
21if [ $? != 0 ]; then
22 exit 1
23fi
24diff_importgit test
25exit $?
260
=== removed file 'exporters/darcs/x2d'
--- exporters/darcs/x2d 2011-10-06 00:11:52 +0000
+++ exporters/darcs/x2d 1970-01-01 00:00:00 +0000
@@ -1,125 +0,0 @@
1#!/bin/sh
2#
3# x2d - convert git, bzr or hg repos to darcs using fast-export
4#
5# Copyright (c) 2008 by Miklos Vajna <vmiklos@frugalware.org>
6#
7# This program is free software; you can redistribute it and/or modify
8# it under the terms of the GNU General Public License as published by
9# the Free Software Foundation; either version 2 of the License, or
10# (at your option) any later version.
11#
12# This program is distributed in the hope that it will be useful,
13# but WITHOUT ANY WARRANTY; without even the implied warranty of
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15# GNU General Public License for more details.
16#
17# You should have received a copy of the GNU General Public License
18# along with this program. If not, see <http://www.gnu.org/licenses/>.
19#
20
21usage()
22{
23 echo "Usage: x2d -f format repo"
24}
25
26die()
27{
28 echo "$@"
29 usage
30 exit 1
31}
32
33check_up_to_date()
34{
35 upstreamnum=$(darcs show repo|grep 'Num Patches'|sed 's/.*: //')
36 if [ "$upstreamnum" = "$(cd $origin; eval $*)" ]; then
37 echo "No remote changes to pull!"
38 exit 0
39 fi
40}
41
42case $1 in
43 -h|--help)
44 usage
45 exit 0
46 ;;
47 -f)
48 format="$2"
49 shift 2
50 ;;
51esac
52
53[ -n "$format" ] || die "Source format is not given!"
54
55case $format in
56 git|bzr|hg)
57 ;;
58 *)
59 die "The requested source format is not yet supported!"
60 ;;
61esac
62
63common_opts=""
64while [ -n "$2" ]
65do
66 common_opts="$common_opts $1"
67 shift 1
68done
69origin="$1"
70shift 1
71
72[ -d "$origin" ] || die "Source repo does not exist!"
73
74# convert to abspath
75cd $origin
76origin=$(pwd)
77
78dmark="$origin.darcs/_darcs/fast-import/dfe-marks"
79fmark="$origin.darcs/_darcs/fast-import/ffi-marks"
80
81mkdir -p $origin.darcs
82cd $origin.darcs
83
84common_opts="$common_opts --logfile $origin.darcs/_darcs/fast-import/log"
85pypath="/$(python -c 'from distutils import sysconfig; print sysconfig.get_python_lib()[1:]')/"
86
87if [ ! -f $dmark ]; then
88 darcs init
89 mkdir -p _darcs/fast-import
90 case $format in
91 git)
92 (cd $origin; git fast-export --export-marks=$fmark HEAD) | \
93 darcs-fast-import --export-marks=$dmark $common_opts
94 ;;
95 bzr)
96 (cd $origin; bzr fast-export \
97 --export-marks=$fmark . ) | darcs-fast-import --export-marks=$dmark $common_opts
98 ;;
99 hg)
100 (cd $origin; $pypath/bzrlib/plugins/fastimport/exporters/hg-fast-export.py -r . ) | \
101 darcs-fast-import --export-marks=$dmark $common_opts
102 esac
103else
104 case $format in
105 git)
106 check_up_to_date "git rev-list HEAD |wc -l"
107 (cd $origin; git fast-export --export-marks=$fmark --import-marks=$fmark HEAD) | \
108 darcs-fast-import --export-marks=$dmark --import-marks=$dmark $common_opts
109 ;;
110 bzr)
111 # bzr revno is not good here, because at merges
112 # it produces less revision than the number we
113 # have in darcs
114 check_up_to_date "bzr log --include-merges |grep -c revno:"
115 (cd $origin; bzr fast-export \
116 --export-marks=$fmark --import-marks=$fmark . ) | \
117 darcs-fast-import --export-marks=$dmark --import-marks=$dmark $common_opts
118 ;;
119 hg)
120 check_up_to_date 'echo $(($(hg tip --template "{rev}")+1))'
121 (cd $origin; $pypath/bzrlib/plugins/fastimport/exporters/hg-fast-export.py -r . ) | \
122 darcs-fast-import --export-marks=$dmark --import-marks=$dmark $common_opts
123 ;;
124 esac
125fi
1260
=== removed file 'exporters/darcs/x2d.txt'
--- exporters/darcs/x2d.txt 2010-06-27 21:11:37 +0000
+++ exporters/darcs/x2d.txt 1970-01-01 00:00:00 +0000
@@ -1,28 +0,0 @@
1= x2d(1)
2
3== NAME
4
5x2d - convert git, bzr or hg repos to a darcs one using fast-export
6
7== SYNOPSIS
8
9x2d -f <format> [<importoptions>] <otherrepo>
10
11== DESCRIPTION
12
13x2d is a wrapper script that just automates doing an initial or
14continuing an incremental conversion. All it does is initializing the
15target darcs repo, starting darcs-fast-import and the relevant exporter
16with the proper switches and pipe the importer's output to the
17importer's standard input.
18
19== OPTIONS
20
21--help::
22 Display usage.
23
24-f <format>::
25 Specify the format of the source repo. Currently supported sources are
26 git, bzr and hg. Incremental conversion is supported for all of them.
27
28The rest of the options is directly passed to darcs-fast-import.
290
=== removed file 'exporters/hg-fast-export.README'
--- exporters/hg-fast-export.README 2009-07-23 04:55:18 +0000
+++ exporters/hg-fast-export.README 1970-01-01 00:00:00 +0000
@@ -1,54 +0,0 @@
1hg-fast-import.py - mercurial to bzr converter using bzr fast-import
2
3Legal
4=====
5
6Most hg-* scripts are licensed under the MIT license[0] and were written
7by Rocco Rutte <pdmef@gmx.net> with hints and help from the git list and
8#mercurial on freenode. hg-fast-export[1] was integrated into
9bzr-fastimport by Ian Clatworthy with permission from Rocco.
10
11The current maintainer is Frej Drejhammar <frej.drejhammar@gmail.com>.
12
13Usage
14=====
15
16Using hg-fast-export is quite simple for a mercurial repository <repo>:
17
18 bzr init-repo foo.bzr
19 cd foo.bzr
20 hg-fast-import.py -r <repo> | bzr fast-import -
21
22Notes/Limitations
23=================
24
25hg-fast-import supports multiple branches but only named branches with exactly
26one head each. Otherwise commits to the tip of these heads within branch
27will get flattened into merge commits.
28
29The way the hg API and remote access protocol is designed it is not
30possible to use hg-fast-export on remote repositories
31(http/ssh). First clone the repository, then convert it.
32
33Design
34======
35
36hg-fast-import.py was designed in a way that doesn't require a 2-pass mechanism
37or any prior repository analysis: if just outputs what it finds.
38This also implies that it heavily relies on strictly
39linear ordering of changesets from hg, i.e. its append-only storage
40model so that changesets hg-fast-import already saw never get modified.
41
42Todo
43====
44
45Test incremental imports, particularly handling of branches and tags.
46
47For one-time conversions, everything should be fine.
48
49Footnotes
50=========
51
52[0] http://www.opensource.org/licenses/mit-license.php
53
54[1] http://repo.or.cz/w/fast-export.git
550
=== removed file 'exporters/hg-fast-export.py'
--- exporters/hg-fast-export.py 2009-08-10 07:24:46 +0000
+++ exporters/hg-fast-export.py 1970-01-01 00:00:00 +0000
@@ -1,442 +0,0 @@
1#!/usr/bin/env python
2
3# Copyright (c) 2007, 2008 Rocco Rutte <pdmef@gmx.net> and others.
4# License: MIT <http://www.opensource.org/licenses/mit-license.php>
5
6from mercurial import repo,hg,cmdutil,util,ui,revlog,node
7from hg2git import setup_repo,fixup_user,get_branch,get_changeset
8from hg2git import load_cache,save_cache,get_git_sha1,set_default_branch,set_origin_name
9from tempfile import mkstemp
10from optparse import OptionParser
11import re
12import sys
13import os
14
15# silly regex to catch Signed-off-by lines in log message
16sob_re=re.compile('^Signed-[Oo]ff-[Bb]y: (.+)$')
17# insert 'checkpoint' command after this many commits or none at all if 0
18cfg_checkpoint_count=0
19# write some progress message every this many file contents written
20cfg_export_boundary=1000
21
22def gitmode(flags):
23 return 'l' in flags and '120000' or 'x' in flags and '100755' or '100644'
24
25def wr(msg=''):
26 if msg == None:
27 msg = ''
28 print msg
29 #map(lambda x: sys.stderr.write('\t[%s]\n' % x),msg.split('\n'))
30
31def checkpoint(count):
32 count=count+1
33 if cfg_checkpoint_count>0 and count%cfg_checkpoint_count==0:
34 sys.stderr.write("Checkpoint after %d commits\n" % count)
35 wr('checkpoint')
36 wr()
37 return count
38
39def get_parent_mark(parent,marks):
40 """Get the mark for some parent.
41 If we saw it in the current session, return :%d syntax and
42 otherwise the SHA1 from the cache."""
43 return marks.get(str(parent),':%d' % (parent+1))
44
45def file_mismatch(f1,f2):
46 """See if two revisions of a file are not equal."""
47 return node.hex(f1)!=node.hex(f2)
48
49def split_dict(dleft,dright,l=[],c=[],r=[],match=file_mismatch):
50 """Loop over our repository and find all changed and missing files."""
51 for left in dleft.keys():
52 right=dright.get(left,None)
53 if right==None:
54 # we have the file but our parent hasn't: add to left set
55 l.append(left)
56 elif match(dleft[left],right):
57 # we have it but checksums mismatch: add to center set
58 c.append(left)
59 for right in dright.keys():
60 left=dleft.get(right,None)
61 if left==None:
62 # if parent has file but we don't: add to right set
63 r.append(right)
64 # change is already handled when comparing child against parent
65 return l,c,r
66
67def get_filechanges(repo,revision,parents,mleft):
68 """Given some repository and revision, find all changed/deleted files."""
69 l,c,r=[],[],[]
70 for p in parents:
71 if p<0: continue
72 mright=repo.changectx(p).manifest()
73 l,c,r=split_dict(mleft,mright,l,c,r)
74 l.sort()
75 c.sort()
76 r.sort()
77 return l,c,r
78
79def get_author(logmessage,committer,authors):
80 """As git distincts between author and committer of a patch, try to
81 extract author by detecting Signed-off-by lines.
82
83 This walks from the end of the log message towards the top skipping
84 empty lines. Upon the first non-empty line, it walks all Signed-off-by
85 lines upwards to find the first one. For that (if found), it extracts
86 authorship information the usual way (authors table, cleaning, etc.)
87
88 If no Signed-off-by line is found, this defaults to the committer.
89
90 This may sound stupid (and it somehow is), but in log messages we
91 accidentially may have lines in the middle starting with
92 "Signed-off-by: foo" and thus matching our detection regex. Prevent
93 that."""
94
95 loglines=logmessage.split('\n')
96 i=len(loglines)
97 # from tail walk to top skipping empty lines
98 while i>=0:
99 i-=1
100 if len(loglines[i].strip())==0: continue
101 break
102 if i>=0:
103 # walk further upwards to find first sob line, store in 'first'
104 first=None
105 while i>=0:
106 m=sob_re.match(loglines[i])
107 if m==None: break
108 first=m
109 i-=1
110 # if the last non-empty line matches our Signed-Off-by regex: extract username
111 if first!=None:
112 r=fixup_user(first.group(1),authors)
113 return r
114 return committer
115
116def export_file_contents(ctx,manifest,files):
117 count=0
118 max=len(files)
119 for file in files:
120 # Skip .hgtags files. They only get us in trouble.
121 if file == ".hgtags":
122 sys.stderr.write('Skip %s\n' % (file))
123 continue
124 d=ctx.filectx(file).data()
125 wr('M %s inline %s' % (gitmode(manifest.flags(file)),file))
126 wr('data %d' % len(d)) # had some trouble with size()
127 wr(d)
128 count+=1
129 if count%cfg_export_boundary==0:
130 sys.stderr.write('Exported %d/%d files\n' % (count,max))
131 if max>cfg_export_boundary:
132 sys.stderr.write('Exported %d/%d files\n' % (count,max))
133
134def is_merge(parents):
135 c=0
136 for parent in parents:
137 if parent>=0:
138 c+=1
139 return c>1
140
141def sanitize_name(name,what="branch"):
142 """Sanitize input roughly according to git-check-ref-format(1)"""
143
144 def dot(name):
145 if name[0] == '.': return '_'+name[1:]
146 return name
147
148 n=name
149 p=re.compile('([[ ~^:?*]|\.\.)')
150 n=p.sub('_', n)
151 if n[-1] == '/': n=n[:-1]+'_'
152 n='/'.join(map(dot,n.split('/')))
153 p=re.compile('_+')
154 n=p.sub('_', n)
155
156 if n!=name:
157 sys.stderr.write('Warning: sanitized %s [%s] to [%s]\n' % (what,name,n))
158 return n
159
160def export_commit(ui,repo,revision,marks,mapping,heads,last,max,count,authors,sob,brmap):
161 def get_branchname(name):
162 if brmap.has_key(name):
163 return brmap[name]
164 n=sanitize_name(name)
165 brmap[name]=n
166 return n
167
168 (revnode,_,user,(time,timezone),files,desc,branch,_)=get_changeset(ui,repo,revision,authors)
169 parents=repo.changelog.parentrevs(revision)
170
171 branch=get_branchname(branch)
172
173 wr('commit refs/heads/%s' % branch)
174 wr('mark :%d' % (revision+1))
175 if sob:
176 wr('author %s %d %s' % (get_author(desc,user,authors),time,timezone))
177 wr('committer %s %d %s' % (user,time,timezone))
178 wr('data %d' % (len(desc)+1)) # wtf?
179 wr(desc)
180 wr()
181
182 pidx1, pidx2 = 0, 1
183 if parents[1] > 0:
184 if parents[0] <= 0 or \
185 repo.changelog.node(parents[0]) < repo.changelog.node(parents[1]):
186 pidx1, pidx2 = 1, 0
187
188 full_rev=False
189 if revision==0: full_rev=True
190
191 src=heads.get(branch,'')
192 link=''
193 if src!='':
194 # if we have a cached head, this is an incremental import: initialize it
195 # and kill reference so we won't init it again
196 wr('from %s' % src)
197 heads[branch]=''
198 sys.stderr.write('%s: Initializing to parent [%s]\n' %
199 (branch,src))
200 link=src # avoid making a merge commit for incremental import
201 elif link=='' and not heads.has_key(branch) and revision>0:
202 if parents[0]>=0:
203 # newly created branch with parent: connect to parent
204 tmp=get_parent_mark(parents[0],marks)
205 wr('from %s' % tmp)
206 sys.stderr.write('%s: Link new branch to parent [%s]\n' %
207 (branch,tmp))
208 link=tmp # avoid making a merge commit for branch fork
209 else:
210 # newly created branch without parent: feed full revision
211 full_rev=True
212 elif last.get(branch,revision) != parents[pidx1] and parents[pidx1] > 0 and revision > 0:
213 pm=get_parent_mark(parents[pidx1],marks)
214 sys.stderr.write('%s: Placing commit [r%d] in branch [%s] on top of [r%d]\n' %
215 (branch,revision,branch,parents[pidx1]));
216 wr('from %s' % pm)
217
218 if parents[pidx2] > 0:
219 pm=get_parent_mark(parents[pidx2],marks)
220 sys.stderr.write('%s: Merging with parent [%s] from [r%d]\n' %
221 (branch,pm,parents[pidx2]))
222 wr('merge %s' % pm)
223
224 last[branch]=revision
225 heads[branch]=''
226 # we need this later to write out tags
227 marks[str(revision)]=':%d'%(revision+1)
228
229 ctx=repo.changectx(str(revision))
230 man=ctx.manifest()
231 added,changed,removed,type=[],[],[],''
232
233 if full_rev:
234 # first revision: feed in full manifest
235 added=man.keys()
236 added.sort()
237 type='full'
238 elif is_merge(parents):
239 # later merge revision: feed in changed manifest
240 # for many files comparing checksums is expensive so only do it for
241 # merges where we really need it due to hg's revlog logic
242 added,changed,removed=get_filechanges(repo,revision,parents,man)
243 type='thorough delta'
244 else:
245 # later non-merge revision: feed in changed manifest
246 # if we have exactly one parent, just take the changes from the
247 # manifest without expensively comparing checksums
248 f=repo.status(repo.lookup(parents[0]),revnode)[:3]
249 added,changed,removed=f[1],f[0],f[2]
250 type='simple delta'
251
252 sys.stderr.write('%s: Exporting %s revision %d/%d with %d/%d/%d added/changed/removed files\n' %
253 (branch,type,revision+1,max,len(added),len(changed),len(removed)))
254
255 map(lambda r: wr('D %s' % r),removed)
256 export_file_contents(ctx,man,added)
257 export_file_contents(ctx,man,changed)
258 wr()
259
260 return checkpoint(count)
261
262def export_tags(ui,repo,marks_cache,mapping_cache,count,authors):
263 l=repo.tagslist()
264 for tag,node in l:
265 tag=sanitize_name(tag,"tag")
266 # ignore latest revision
267 if tag=='tip': continue
268 # ignore tags to nodes that are missing (ie, 'in the future')
269 if node.encode('hex_codec') not in mapping_cache:
270 sys.stderr.write('Tag %s refers to unseen node %s\n' % (tag, node.encode('hex_codec')))
271 continue
272
273 rev=int(mapping_cache[node.encode('hex_codec')])
274
275 ref=marks_cache.get(str(rev),':%d' % (rev))
276 if ref==None:
277 sys.stderr.write('Failed to find reference for creating tag'
278 ' %s at r%d\n' % (tag,rev))
279 continue
280 sys.stderr.write('Exporting tag [%s] at [hg r%d] [git %s]\n' % (tag,rev,ref))
281 wr('reset refs/tags/%s' % tag)
282 wr('from %s' % ref)
283 wr()
284 count=checkpoint(count)
285 return count
286
287def load_authors(filename):
288 cache={}
289 if not os.path.exists(filename):
290 return cache
291 f=open(filename,'r')
292 l=0
293 lre=re.compile('^([^=]+)[ ]*=[ ]*(.+)$')
294 for line in f.readlines():
295 l+=1
296 m=lre.match(line)
297 if m==None:
298 sys.stderr.write('Invalid file format in [%s], line %d\n' % (filename,l))
299 continue
300 # put key:value in cache, key without ^:
301 cache[m.group(1).strip()]=m.group(2).strip()
302 f.close()
303 sys.stderr.write('Loaded %d authors\n' % l)
304 return cache
305
306def verify_heads(ui,repo,cache,force):
307 branches=repo.branchtags()
308 l=[(-repo.changelog.rev(n), n, t) for t, n in branches.items()]
309 l.sort()
310
311 # get list of hg's branches to verify, don't take all git has
312 for _,_,b in l:
313 b=get_branch(b)
314 sha1=get_git_sha1(b)
315 c=cache.get(b)
316 if sha1!=None and c!=None:
317 sys.stderr.write('Verifying branch [%s]\n' % b)
318 if sha1!=c:
319 sys.stderr.write('Error: Branch [%s] modified outside hg-fast-export:'
320 '\n%s (repo) != %s (cache)\n' % (b,sha1,c))
321 if not force: return False
322
323 # verify that branch has exactly one head
324 t={}
325 for h in repo.heads():
326 (_,_,_,_,_,_,branch,_)=get_changeset(ui,repo,h)
327 if t.get(branch,False):
328 sys.stderr.write('Error: repository has at least one unnamed head: hg r%s\n' %
329 repo.changelog.rev(h))
330 if not force: return False
331 t[branch]=True
332
333 return True
334
335def mangle_mark(mark):
336 return str(int(mark)-1)
337
338def hg2git(repourl,m,marksfile,mappingfile,headsfile,tipfile,authors={},sob=False,force=False):
339 _max=int(m)
340
341 try:
342 import msvcrt
343 msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY)
344 except ImportError:
345 pass
346
347 marks_cache=load_cache(marksfile,mangle_mark)
348 mapping_cache=load_cache(mappingfile)
349 heads_cache=load_cache(headsfile)
350 state_cache=load_cache(tipfile)
351
352 ui,repo=setup_repo(repourl)
353
354 if not verify_heads(ui,repo,heads_cache,force):
355 return 1
356
357 try:
358 tip=repo.changelog.count()
359 except AttributeError:
360 tip=len(repo)
361
362 min=int(state_cache.get('tip',0))
363 max=_max
364 if _max<0 or max>tip:
365 max=tip
366
367 for rev in range(0,max):
368 (revnode,_,_,_,_,_,_,_)=get_changeset(ui,repo,rev,authors)
369 mapping_cache[revnode.encode('hex_codec')] = str(rev)
370
371
372 c=0
373 last={}
374 brmap={}
375 for rev in range(min,max):
376 c=export_commit(ui,repo,rev,marks_cache,mapping_cache,heads_cache,last,max,c,authors,sob,brmap)
377
378 state_cache['tip']=max
379 state_cache['repo']=repourl
380 save_cache(tipfile,state_cache)
381 save_cache(mappingfile,mapping_cache)
382
383 c=export_tags(ui,repo,marks_cache,mapping_cache,c,authors)
384
385 sys.stderr.write('Issued %d commands\n' % c)
386
387 return 0
388
389if __name__=='__main__':
390 def bail(parser,opt):
391 sys.stderr.write('Error: No %s option given\n' % opt)
392 parser.print_help()
393 sys.exit(2)
394
395 parser=OptionParser()
396
397 parser.add_option("-m","--max",type="int",dest="max",
398 help="Maximum hg revision to import")
399 parser.add_option("--mapping",dest="mappingfile",
400 help="File to read last run's hg-to-git SHA1 mapping")
401 parser.add_option("--marks",dest="marksfile",
402 help="File to read git-fast-import's marks from")
403 parser.add_option("--heads",dest="headsfile",
404 help="File to read last run's git heads from")
405 parser.add_option("--status",dest="statusfile",
406 help="File to read status from")
407 parser.add_option("-r","--repo",dest="repourl",
408 help="URL of repo to import")
409 parser.add_option("-s",action="store_true",dest="sob",
410 default=False,help="Enable parsing Signed-off-by lines")
411 parser.add_option("-A","--authors",dest="authorfile",
412 help="Read authormap from AUTHORFILE")
413 parser.add_option("-f","--force",action="store_true",dest="force",
414 default=False,help="Ignore validation errors by force")
415 parser.add_option("-M","--default-branch",dest="default_branch",
416 help="Set the default branch")
417 parser.add_option("-o","--origin",dest="origin_name",
418 help="use <name> as namespace to track upstream")
419
420 (options,args)=parser.parse_args()
421
422 m=-1
423 if options.max!=None: m=options.max
424
425 if options.marksfile==None: options.marksfile = 'hg-export.marks'
426 if options.mappingfile==None: options.mappingfile = 'hg-export.mapping'
427 if options.headsfile==None: options.headsfile = 'hg-export.heads'
428 if options.statusfile==None: options.statusfile = 'hg-export.status'
429 if options.repourl==None: bail(parser,'--repo')
430
431 a={}
432 if options.authorfile!=None:
433 a=load_authors(options.authorfile)
434
435 if options.default_branch!=None:
436 set_default_branch(options.default_branch)
437
438 if options.origin_name!=None:
439 set_origin_name(options.origin_name)
440
441 sys.exit(hg2git(options.repourl,m,options.marksfile,options.mappingfile,options.headsfile,
442 options.statusfile,authors=a,sob=options.sob,force=options.force))
4430
=== removed file 'exporters/hg-fast-export.sh'
--- exporters/hg-fast-export.sh 2009-02-12 01:55:46 +0000
+++ exporters/hg-fast-export.sh 1970-01-01 00:00:00 +0000
@@ -1,100 +0,0 @@
1#!/bin/sh
2
3# Copyright (c) 2007, 2008 Rocco Rutte <pdmef@gmx.net> and others.
4# License: MIT <http://www.opensource.org/licenses/mit-license.php>
5
6ROOT="`dirname $0`"
7REPO=""
8PFX="hg2git"
9SFX_MAPPING="mapping"
10SFX_MARKS="marks"
11SFX_HEADS="heads"
12SFX_STATE="state"
13QUIET=""
14PYTHON=${PYTHON:-python}
15
16USAGE="[--quiet] [-r <repo>] [-m <max>] [-s] [-A <file>] [-M <name>] [-o <name>]"
17LONG_USAGE="Import hg repository <repo> up to either tip or <max>
18If <repo> is omitted, use last hg repository as obtained from state file,
19GIT_DIR/$PFX-$SFX_STATE by default.
20
21Note: The argument order matters.
22
23Options:
24 -m Maximum revision to import
25 --quiet Passed to git-fast-import(1)
26 -s Enable parsing Signed-off-by lines
27 -A Read author map from file
28 (Same as in git-svnimport(1) and git-cvsimport(1))
29 -r Mercurial repository to import
30 -M Set the default branch name (default to 'master')
31 -o Use <name> as branch namespace to track upstream (eg 'origin')
32"
33
34. "$(git --exec-path)/git-sh-setup"
35cd_to_toplevel
36
37while case "$#" in 0) break ;; esac
38do
39 case "$1" in
40 -r|--r|--re|--rep|--repo)
41 shift
42 REPO="$1"
43 ;;
44 --q|--qu|--qui|--quie|--quiet)
45 QUIET="--quiet"
46 ;;
47 -*)
48 # pass any other options down to hg2git.py
49 break
50 ;;
51 *)
52 break
53 ;;
54 esac
55 shift
56done
57
58# for convenience: get default repo from state file
59if [ x"$REPO" = x -a -f "$GIT_DIR/$PFX-$SFX_STATE" ] ; then
60 REPO="`egrep '^:repo ' "$GIT_DIR/$PFX-$SFX_STATE" | cut -d ' ' -f 2`"
61 echo "Using last hg repository \"$REPO\""
62fi
63
64# make sure we have a marks cache
65if [ ! -f "$GIT_DIR/$PFX-$SFX_MARKS" ] ; then
66 touch "$GIT_DIR/$PFX-$SFX_MARKS"
67fi
68
69GIT_DIR="$GIT_DIR" $PYTHON "$ROOT/hg-fast-export.py" \
70 --repo "$REPO" \
71 --marks "$GIT_DIR/$PFX-$SFX_MARKS" \
72 --mapping "$GIT_DIR/$PFX-$SFX_MAPPING" \
73 --heads "$GIT_DIR/$PFX-$SFX_HEADS" \
74 --status "$GIT_DIR/$PFX-$SFX_STATE" \
75 "$@" \
76| git fast-import $QUIET --export-marks="$GIT_DIR/$PFX-$SFX_MARKS.tmp"
77
78# move recent marks cache out of the way...
79if [ -f "$GIT_DIR/$PFX-$SFX_MARKS" ] ; then
80 mv "$GIT_DIR/$PFX-$SFX_MARKS" "$GIT_DIR/$PFX-$SFX_MARKS.old"
81else
82 touch "$GIT_DIR/$PFX-$SFX_MARKS.old"
83fi
84
85# ...to create a new merged one
86cat "$GIT_DIR/$PFX-$SFX_MARKS.old" "$GIT_DIR/$PFX-$SFX_MARKS.tmp" \
87| uniq > "$GIT_DIR/$PFX-$SFX_MARKS"
88
89# cleanup
90rm -rf "$GIT_DIR/$PFX-$SFX_MARKS.old" "$GIT_DIR/$PFX-$SFX_MARKS.tmp"
91
92# save SHA1s of current heads for incremental imports
93# and connectivity (plus sanity checking)
94for head in `git branch | sed 's#^..##'` ; do
95 id="`git rev-parse $head`"
96 echo ":$head $id"
97done > "$GIT_DIR/$PFX-$SFX_HEADS"
98
99# check diff with color:
100# ( for i in `find . -type f | grep -v '\.git'` ; do diff -u $i $REPO/$i ; done | cdiff ) | less -r
1010
=== removed file 'exporters/hg2git.py'
--- exporters/hg2git.py 2011-10-06 21:39:31 +0000
+++ exporters/hg2git.py 1970-01-01 00:00:00 +0000
@@ -1,112 +0,0 @@
1
2# Copyright (c) 2007, 2008 Rocco Rutte <pdmef@gmx.net> and others.
3# License: MIT <http://www.opensource.org/licenses/mit-license.php>
4
5from mercurial import repo,hg,cmdutil,util,ui,revlog,node
6import re
7import os
8import sys
9
10# default git branch name
11cfg_master='master'
12# default origin name
13origin_name=''
14# silly regex to see if user field has email address
15user_re=re.compile('([^<]+) (<[^>]+>)$')
16# silly regex to clean out user names
17user_clean_re=re.compile('^["]([^"]+)["]$')
18
19def set_default_branch(name):
20 global cfg_master
21 cfg_master = name
22
23def set_origin_name(name):
24 global origin_name
25 origin_name = name
26
27def setup_repo(url):
28 try:
29 myui=ui.ui(interactive=False)
30 except TypeError:
31 myui=ui.ui()
32 myui.setconfig('ui', 'interactive', 'off')
33 return myui,hg.repository(myui,url)
34
35def fixup_user(user,authors):
36 if authors!=None:
37 # if we have an authors table, try to get mapping
38 # by defaulting to the current value of 'user'
39 user=authors.get(user,user)
40 name,mail,m='','',user_re.match(user)
41 if m==None:
42 # if we don't have 'Name <mail>' syntax, use 'user
43 # <devnull@localhost>' if use contains no at and
44 # 'user <user>' otherwise
45 name=user
46 if '@' not in user:
47 mail='<devnull@localhost>'
48 else:
49 mail='<%s>' % user
50 else:
51 # if we have 'Name <mail>' syntax, everything is fine :)
52 name,mail=m.group(1),m.group(2)
53
54 # remove any silly quoting from username
55 m2=user_clean_re.match(name)
56 if m2!=None:
57 name=m2.group(1)
58 return '%s %s' % (name,mail)
59
60def get_branch(name):
61 # 'HEAD' is the result of a bug in mutt's cvs->hg conversion,
62 # other CVS imports may need it, too
63 if name=='HEAD' or name=='default' or name=='':
64 name=cfg_master
65 if origin_name:
66 return origin_name + '/' + name
67 return name
68
69def get_changeset(ui,repo,revision,authors={}):
70 node=repo.lookup(revision)
71 (manifest,user,(time,timezone),files,desc,extra)=repo.changelog.read(node)
72 tz="%+03d%02d" % (-timezone / 3600, ((-timezone % 3600) / 60))
73 branch=get_branch(extra.get('branch','master'))
74 return (node,manifest,fixup_user(user,authors),(time,tz),files,desc,branch,extra)
75
76def mangle_key(key):
77 return key
78
79def load_cache(filename,get_key=mangle_key):
80 cache={}
81 if not os.path.exists(filename):
82 return cache
83 f=open(filename,'r')
84 l=0
85 for line in f.readlines():
86 l+=1
87 fields=line.split(' ')
88 if fields==None or not len(fields)==2 or fields[0][0]!=':':
89 sys.stderr.write('Invalid file format in [%s], line %d\n' % (filename,l))
90 continue
91 # put key:value in cache, key without ^:
92 cache[get_key(fields[0][1:])]=fields[1].split('\n')[0]
93 f.close()
94 return cache
95
96def save_cache(filename,cache):
97 f=open(filename,'w+')
98 map(lambda x: f.write(':%s %s\n' % (str(x),str(cache.get(x)))),cache.keys())
99 f.close()
100
101def get_git_sha1(name,type='heads'):
102 try:
103 # use git-rev-parse to support packed refs
104 cmd="GIT_DIR='%s' git rev-parse --verify refs/%s/%s 2>/dev/null" % (os.getenv('GIT_DIR','/dev/null'),type,name)
105 p=os.popen(cmd)
106 l=p.readline()
107 p.close()
108 if l == None or len(l) == 0:
109 return None
110 return l[0:40]
111 except IOError:
112 return None
1130
=== removed file 'exporters/svn-archive.c'
--- exporters/svn-archive.c 2008-03-14 19:17:42 +0000
+++ exporters/svn-archive.c 1970-01-01 00:00:00 +0000
@@ -1,240 +0,0 @@
1/*
2 * svn-archive.c
3 * ----------
4 * Walk through a given revision of a local Subversion repository and export
5 * all of the contents as a tarfile.
6 *
7 * Author: Chris Lee <clee@kde.org>
8 * License: MIT <http://www.opensource.org/licenses/mit-license.php>
9 */
10
11#define _XOPEN_SOURCE
12#include <unistd.h>
13#include <string.h>
14#include <stdio.h>
15#include <time.h>
16
17#ifndef PATH_MAX
18#define PATH_MAX 4096
19#endif
20
21#include <apr_general.h>
22#include <apr_strings.h>
23#include <apr_getopt.h>
24#include <apr_lib.h>
25
26#include <svn_types.h>
27#include <svn_pools.h>
28#include <svn_repos.h>
29#include <svn_fs.h>
30
31#undef SVN_ERR
32#define SVN_ERR(expr) SVN_INT_ERR(expr)
33#define apr_sane_push(arr, contents) *(char **)apr_array_push(arr) = contents
34
35#define TRUNK "/trunk"
36
37static time_t archive_time;
38
39time_t get_epoch(char *svn_date)
40{
41 struct tm tm = {0};
42 char *date = malloc(strlen(svn_date) * sizeof(char *));
43 strncpy(date, svn_date, strlen(svn_date) - 8);
44 strptime(date, "%Y-%m-%dT%H:%M:%S", &tm);
45 free(date);
46 return mktime(&tm);
47}
48
49int tar_header(apr_pool_t *pool, char *path, char *node, size_t f_size)
50{
51 char buf[512];
52 unsigned int i, checksum;
53 svn_boolean_t is_dir;
54
55 memset(buf, 0, sizeof(buf));
56
57 if ((strlen(path) == 0) && (strlen(node) == 0)) {
58 return 0;
59 }
60
61 if (strlen(node) == 0) {
62 is_dir = 1;
63 } else {
64 is_dir = 0;
65 }
66
67 if (strlen(path) == 0) {
68 strncpy(buf, apr_psprintf(pool, "%s", node), 99);
69 } else if (strlen(path) + strlen(node) < 100) {
70 strncpy(buf, apr_psprintf(pool, "%s/%s", path+1, node), 99);
71 } else {
72 fprintf(stderr, "really long file path...\n");
73 strncpy(&buf[0], node, 99);
74 strncpy(&buf[345], path+1, 154);
75 }
76
77 strncpy(&buf[100], apr_psprintf(pool, "%07o", (is_dir ? 0755 : 0644)), 7);
78 strncpy(&buf[108], apr_psprintf(pool, "%07o", 1000), 7);
79 strncpy(&buf[116], apr_psprintf(pool, "%07o", 1000), 7);
80 strncpy(&buf[124], apr_psprintf(pool, "%011lo", f_size), 11);
81 strncpy(&buf[136], apr_psprintf(pool, "%011lo", archive_time), 11);
82 strncpy(&buf[156], (is_dir ? "5" : "0"), 1);
83 strncpy(&buf[257], "ustar ", 8);
84 strncpy(&buf[265], "clee", 31);
85 strncpy(&buf[297], "clee", 31);
86 // strncpy(&buf[329], apr_psprintf(pool, "%07o", 0), 7);
87 // strncpy(&buf[337], apr_psprintf(pool, "%07o", 0), 7);
88
89 strncpy(&buf[148], " ", 8);
90 checksum = 0;
91 for (i = 0; i < sizeof(buf); i++) {
92 checksum += buf[i];
93 }
94 strncpy(&buf[148], apr_psprintf(pool, "%07o", checksum & 0x1fffff), 7);
95
96 fwrite(buf, sizeof(char), sizeof(buf), stdout);
97
98 return 0;
99}
100
101int tar_footer()
102{
103 char block[1024];
104 memset(block, 0, sizeof(block));
105 fwrite(block, sizeof(char), sizeof(block), stdout);
106}
107
108int dump_blob(svn_fs_root_t *root, char *prefix, char *path, char *node, apr_pool_t *pool)
109{
110 char *full_path, buf[512];
111 apr_size_t len;
112 svn_stream_t *stream;
113 svn_filesize_t stream_length;
114
115 full_path = apr_psprintf(pool, "%s%s/%s", prefix, path, node);
116
117 SVN_ERR(svn_fs_file_length(&stream_length, root, full_path, pool));
118 SVN_ERR(svn_fs_file_contents(&stream, root, full_path, pool));
119
120 tar_header(pool, path, node, stream_length);
121
122 do {
123 len = sizeof(buf);
124 memset(buf, '\0', sizeof(buf));
125 SVN_ERR(svn_stream_read(stream, buf, &len));
126 fwrite(buf, sizeof(char), sizeof(buf), stdout);
127 } while (len == sizeof(buf));
128
129 return 0;
130}
131
132int dump_tree(svn_fs_root_t *root, char *prefix, char *path, apr_pool_t *pool)
133{
134 const void *key;
135 void *val;
136 char *node, *subpath, *full_path;
137
138 apr_pool_t *subpool;
139 apr_hash_t *dir_entries;
140 apr_hash_index_t *i;
141
142 svn_boolean_t is_dir;
143
144 tar_header(pool, path, "", 0);
145
146 SVN_ERR(svn_fs_dir_entries(&dir_entries, root, apr_psprintf(pool, "%s/%s", prefix, path), pool));
147
148 subpool = svn_pool_create(pool);
149
150 for (i = apr_hash_first(pool, dir_entries); i; i = apr_hash_next(i)) {
151 svn_pool_clear(subpool);
152 apr_hash_this(i, &key, NULL, &val);
153 node = (char *)key;
154
155 subpath = apr_psprintf(subpool, "%s/%s", path, node);
156 full_path = apr_psprintf(subpool, "%s%s", prefix, subpath);
157
158 svn_fs_is_dir(&is_dir, root, full_path, subpool);
159
160 if (is_dir) {
161 dump_tree(root, prefix, subpath, subpool);
162 } else {
163 dump_blob(root, prefix, path, node, subpool);
164 }
165 }
166
167 svn_pool_destroy(subpool);
168
169 return 0;
170}
171
172int crawl_filesystem(char *repos_path, char *root_path, apr_pool_t *pool)
173{
174 char *path;
175
176 apr_hash_t *props;
177 apr_hash_index_t *i;
178
179 svn_repos_t *repos;
180 svn_fs_t *fs;
181 svn_string_t *svndate;
182 svn_revnum_t youngest_rev, export_rev;
183 svn_fs_root_t *fs_root;
184
185 SVN_ERR(svn_fs_initialize(pool));
186 SVN_ERR(svn_repos_open(&repos, repos_path, pool));
187 if ((fs = svn_repos_fs(repos)) == NULL)
188 return -1;
189 SVN_ERR(svn_fs_youngest_rev(&youngest_rev, fs, pool));
190
191 export_rev = youngest_rev;
192
193 SVN_ERR(svn_fs_revision_root(&fs_root, fs, export_rev, pool));
194 SVN_ERR(svn_fs_revision_proplist(&props, fs, export_rev, pool));
195
196 svndate = apr_hash_get(props, "svn:date", APR_HASH_KEY_STRING);
197 archive_time = get_epoch((char *)svndate->data);
198
199 fprintf(stderr, "Exporting archive of r%ld... \n", export_rev);
200
201 dump_tree(fs_root, root_path, "", pool);
202
203 tar_footer();
204
205 fprintf(stderr, "done!\n");
206
207 return 0;
208}
209
210int main(int argc, char *argv[])
211{
212 apr_pool_t *pool;
213 apr_getopt_t *options;
214
215 apr_getopt_option_t long_options[] = {
216 { "help", 'h', 0 },
217 { "prefix", 'p', 0 },
218 { "basename", 'b', 0 },
219 { "revision", 'r', 0 },
220 { NULL, 0, 0 }
221 };
222
223 if (argc < 2) {
224 fprintf(stderr, "usage: %s REPOS_PATH [prefix]\n", argv[0]);
225 return -1;
226 }
227
228 if (apr_initialize() != APR_SUCCESS) {
229 fprintf(stderr, "You lose at apr_initialize().\n");
230 return -1;
231 }
232
233 pool = svn_pool_create(NULL);
234
235 crawl_filesystem(argv[1], (argc == 3 ? argv[2] : TRUNK), pool);
236
237 apr_terminate();
238
239 return 0;
240}
2410
=== removed file 'exporters/svn-fast-export.README'
--- exporters/svn-fast-export.README 2009-10-13 02:02:22 +0000
+++ exporters/svn-fast-export.README 1970-01-01 00:00:00 +0000
@@ -1,12 +0,0 @@
1To compile svn-fast-export.c, use make. You'll need to install
2some packages first using the package manager on your OS:
3
4* libsvn-dev - the Subversion libraries
5* libapr1-dev - the Apache Portable Runtime libraries
6
7Note: If someone with good knowledge of the Subversion
8Python bindings could rewrite svn-fast-export.py so that
9https://bugs.launchpad.net/bzr-fastimport/+bug/273361
10went away, then there would be much rejoicing throughout
11the land and the need for svn-fast-export.c would largely
12disappear.
130
=== removed file 'exporters/svn-fast-export.c'
--- exporters/svn-fast-export.c 2008-03-14 19:17:42 +0000
+++ exporters/svn-fast-export.c 1970-01-01 00:00:00 +0000
@@ -1,187 +0,0 @@
1/*
2 * svn-fast-export.c
3 * ----------
4 * Walk through each revision of a local Subversion repository and export it
5 * in a stream that git-fast-import can consume.
6 *
7 * Author: Chris Lee <clee@kde.org>
8 * License: MIT <http://www.opensource.org/licenses/mit-license.php>
9 */
10
11#define _XOPEN_SOURCE
12#include <unistd.h>
13#include <string.h>
14#include <stdio.h>
15#include <time.h>
16
17#ifndef PATH_MAX
18#define PATH_MAX 4096
19#endif
20
21#include <apr_lib.h>
22#include <apr_getopt.h>
23#include <apr_general.h>
24
The diff has been truncated for viewing.

Subscribers

People subscribed via source and target branches