@matheusbsbs / matheus-bagliano / commits / fc47391e24
Fork 0

drop vcs-svn experiment

The code in vcs-svn was started in 2010 as an attempt to build a remote-helper for interacting with svn repositories (as opposed to git-svn). However, we never got as far as shipping a mature remote helper, and the last substantive commit was e99d012a6bc in 2012. We do have a git-remote-testsvn, and it is even installed as part of "make install". But given the name, it seems unlikely to be used by anybody (you'd have to explicitly "git clone testsvn::$url", and there have been zero mentions of that on the mailing list since 2013, and even that includes the phrase "you might need to hack a bit to get it working properly"[1]). We also ship contrib/svn-fe, which builds on the vcs-svn work. However, it does not seem to build out of the box for me, as the link step misses some required libraries for using libgit.a. Curiously, the original build breakage bisects for me to eff80a9fd9 (Allow custom "comment char", 2013-01-16), which seems unrelated. There was an attempt to fix it in da011cb0e7 (contrib/svn-fe: fix Makefile, 2014-08-28), but on my system that only switches the error message. So it seems like the result is not really usable by anybody in practice. It would be wonderful if somebody wanted to pick up the topic again, and potentially it's worth carrying around for that reason. But the flip side is that people doing tree-wide operations have to deal with this code. And you can see the list with (replace "HEAD" with this commit as appropriate): { echo "--" git diff-tree --diff-filter=D -r --name-only HEAD^ HEAD } | git log --no-merges --oneline e99d012a6bc.. --stdin which shows 58 times somebody had to deal with the code, generally due to a compile or test failure, or a tree-wide style fix or API change. Let's drop it and let anybody who wants to pick it up do so by resurrecting it from the git history. As a bonus, this also reduces the size of a stripped installation of Git from 21MB to 19MB. [1] https://lore.kernel.org/git/CALkWK0mPHzKfzFKKpZkfAus3YVC9NFYDbFnt+5JQYVKipk3bQQ@mail.gmail.com/ Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Jeff King committed Aug 13, 2020 at 11:00 UTC fc47391e2478b26d33cae033f13405b6ee6af97b
24 files changed +7 -3856
.gitignore
-1
@@ -134,7 +134,6 @@
134 /git-remote-fd
135 /git-remote-ext
136 /git-remote-testpy
137 -/git-remote-testsvn
137 /git-repack
138 /git-replace
139 /git-request-pull
Makefile
+1 -25
@@ -569,7 +569,6 @@ BUILT_INS =
569 COMPAT_CFLAGS =
570 COMPAT_OBJS =
571 XDIFF_OBJS =
572 -VCSSVN_OBJS =
572 GENERATED_H =
573 EXTRA_CPPFLAGS =
574 FUZZ_OBJS =
@@ -674,7 +673,6 @@ PROGRAMS += $(EXTRA_PROGRAMS)
673 PROGRAM_OBJS += daemon.o
674 PROGRAM_OBJS += http-backend.o
675 PROGRAM_OBJS += imap-send.o
677 -PROGRAM_OBJS += remote-testsvn.o
676 PROGRAM_OBJS += sh-i18n--envsubst.o
677 PROGRAM_OBJS += shell.o
678
@@ -746,8 +744,6 @@ TEST_BUILTINS_OBJS += test-xml-encode.o
744 # Do not add more tests here unless they have extra dependencies. Add
745 # them in TEST_BUILTINS_OBJS above.
746 TEST_PROGRAMS_NEED_X += test-fake-ssh
749 -TEST_PROGRAMS_NEED_X += test-line-buffer
750 -TEST_PROGRAMS_NEED_X += test-svn-fe
747 TEST_PROGRAMS_NEED_X += test-tool
748
749 TEST_PROGRAMS = $(patsubst %,t/helper/%$X,$(TEST_PROGRAMS_NEED_X))
@@ -803,7 +799,6 @@ TEST_SHELL_PATH = $(SHELL_PATH)
799
800 LIB_FILE = libgit.a
801 XDIFF_LIB = xdiff/lib.a
806 -VCSSVN_LIB = vcs-svn/lib.a
802
803 GENERATED_H += config-list.h
804 GENERATED_H += command-list.h
@@ -2345,16 +2340,9 @@ XDIFF_OBJS += xdiff/xpatience.o
2340 XDIFF_OBJS += xdiff/xprepare.o
2341 XDIFF_OBJS += xdiff/xutils.o
2342
2348 -VCSSVN_OBJS += vcs-svn/fast_export.o
2349 -VCSSVN_OBJS += vcs-svn/line_buffer.o
2350 -VCSSVN_OBJS += vcs-svn/sliding_window.o
2351 -VCSSVN_OBJS += vcs-svn/svndiff.o
2352 -VCSSVN_OBJS += vcs-svn/svndump.o
2353 -
2343 TEST_OBJS := $(patsubst %$X,%.o,$(TEST_PROGRAMS)) $(patsubst %,t/helper/%,$(TEST_BUILTINS_OBJS))
2344 OBJECTS := $(LIB_OBJS) $(BUILTIN_OBJS) $(PROGRAM_OBJS) $(TEST_OBJS) \
2345 $(XDIFF_OBJS) \
2357 - $(VCSSVN_OBJS) \
2346 $(FUZZ_OBJS) \
2347 common-main.o \
2348 git.o
@@ -2469,10 +2457,6 @@ git-http-push$X: http.o http-push.o GIT-LDFLAGS $(GITLIBS)
2457 $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) \
2458 $(CURL_LIBCURL) $(EXPAT_LIBEXPAT) $(LIBS)
2459
2472 -git-remote-testsvn$X: remote-testsvn.o GIT-LDFLAGS $(GITLIBS) $(VCSSVN_LIB)
2473 - $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(LIBS) \
2474 - $(VCSSVN_LIB)
2475 -
2460 $(REMOTE_CURL_ALIASES): $(REMOTE_CURL_PRIMARY)
2461 $(QUIET_LNCP)$(RM) $@ && \
2462 ln $< $@ 2>/dev/null || \
@@ -2489,9 +2473,6 @@ $(LIB_FILE): $(LIB_OBJS)
2473 $(XDIFF_LIB): $(XDIFF_OBJS)
2474 $(QUIET_AR)$(RM) $@ && $(AR) $(ARFLAGS) $@ $^
2475
2492 -$(VCSSVN_LIB): $(VCSSVN_OBJS)
2493 - $(QUIET_AR)$(RM) $@ && $(AR) $(ARFLAGS) $@ $^
2494 -
2476 export DEFAULT_EDITOR DEFAULT_PAGER
2477
2478 Documentation/GIT-EXCLUDED-PROGRAMS: FORCE
@@ -2766,10 +2747,6 @@ perf: all
2747
2748 .PHONY: test perf
2749
2769 -t/helper/test-line-buffer$X: $(VCSSVN_LIB)
2770 -
2771 -t/helper/test-svn-fe$X: $(VCSSVN_LIB)
2772 -
2750 .PRECIOUS: $(TEST_OBJS)
2751
2752 t/helper/test-tool$X: $(patsubst %,t/helper/%,$(TEST_BUILTINS_OBJS))
@@ -2902,7 +2879,6 @@ ifdef MSVC
2879 $(INSTALL) git-http-push.pdb '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
2880 $(INSTALL) git-imap-send.pdb '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
2881 $(INSTALL) git-remote-http.pdb '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
2905 - $(INSTALL) git-remote-testsvn.pdb '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
2882 $(INSTALL) git-sh-i18n--envsubst.pdb '$(DESTDIR_SQ)$(gitexec_instdir_SQ)'
2883 ifndef DEBUG
2884 $(INSTALL) $(vcpkg_rel_bin)/*.dll '$(DESTDIR_SQ)$(bindir_SQ)'
@@ -3103,7 +3079,7 @@ cocciclean:
3079 clean: profile-clean coverage-clean cocciclean
3080 $(RM) *.res
3081 $(RM) $(OBJECTS)
3106 - $(RM) $(LIB_FILE) $(XDIFF_LIB) $(VCSSVN_LIB)
3082 + $(RM) $(LIB_FILE) $(XDIFF_LIB)
3083 $(RM) $(ALL_PROGRAMS) $(SCRIPT_LIB) $(BUILT_INS) git$X
3084 $(RM) $(TEST_PROGRAMS)
3085 $(RM) $(FUZZ_PROGRAMS)
contrib/buildsystems/CMakeLists.txt
+5 -21
@@ -502,7 +502,7 @@ unset(CMAKE_REQUIRED_INCLUDES)
502 #programs
503 set(PROGRAMS_BUILT
504 git git-daemon git-http-backend git-sh-i18n--envsubst
505 - git-shell git-remote-testsvn)
505 + git-shell)
506
507 if(NOT CURL_FOUND)
508 list(APPEND excluded_progs git-http-fetch git-http-push)
@@ -568,12 +568,6 @@ parse_makefile_for_sources(libxdiff_SOURCES "XDIFF_OBJS")
568 list(TRANSFORM libxdiff_SOURCES PREPEND "${CMAKE_SOURCE_DIR}/")
569 add_library(xdiff STATIC ${libxdiff_SOURCES})
570
571 -#libvcs-svn
572 -parse_makefile_for_sources(libvcs-svn_SOURCES "VCSSVN_OBJS")
573 -
574 -list(TRANSFORM libvcs-svn_SOURCES PREPEND "${CMAKE_SOURCE_DIR}/")
575 -add_library(vcs-svn STATIC ${libvcs-svn_SOURCES})
576 -
571 if(WIN32)
572 if(NOT MSVC)#use windres when compiling with gcc and clang
573 add_custom_command(OUTPUT ${CMAKE_BINARY_DIR}/git.res
@@ -654,9 +648,6 @@ if(CURL_FOUND)
648 endif()
649 endif()
650
657 -add_executable(git-remote-testsvn ${CMAKE_SOURCE_DIR}/remote-testsvn.c)
658 -target_link_libraries(git-remote-testsvn common-main vcs-svn)
659 -
651 set(git_builtin_extra
652 cherry cherry-pick format-patch fsck-objects
653 init merge-subtree restore show
@@ -832,12 +823,6 @@ if(BUILD_TESTING)
823 add_executable(test-fake-ssh ${CMAKE_SOURCE_DIR}/t/helper/test-fake-ssh.c)
824 target_link_libraries(test-fake-ssh common-main)
825
835 -add_executable(test-line-buffer ${CMAKE_SOURCE_DIR}/t/helper/test-line-buffer.c)
836 -target_link_libraries(test-line-buffer common-main vcs-svn)
837 -
838 -add_executable(test-svn-fe ${CMAKE_SOURCE_DIR}/t/helper/test-svn-fe.c)
839 -target_link_libraries(test-svn-fe common-main vcs-svn)
840 -
826 #test-tool
827 parse_makefile_for_sources(test-tool_SOURCES "TEST_BUILTINS_OBJS")
828
@@ -845,13 +830,13 @@ list(TRANSFORM test-tool_SOURCES PREPEND "${CMAKE_SOURCE_DIR}/t/helper/")
830 add_executable(test-tool ${CMAKE_SOURCE_DIR}/t/helper/test-tool.c ${test-tool_SOURCES})
831 target_link_libraries(test-tool common-main)
832
848 -set_target_properties(test-fake-ssh test-line-buffer test-svn-fe test-tool
833 +set_target_properties(test-fake-ssh test-tool
834 PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/t/helper)
835
836 if(MSVC)
852 - set_target_properties(test-fake-ssh test-line-buffer test-svn-fe test-tool
837 + set_target_properties(test-fake-ssh test-tool
838 PROPERTIES RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/t/helper)
854 - set_target_properties(test-fake-ssh test-line-buffer test-svn-fe test-tool
839 + set_target_properties(test-fake-ssh test-tool
840 PROPERTIES RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/t/helper)
841 endif()
842
@@ -860,7 +845,7 @@ set(wrapper_scripts
845 git git-upload-pack git-receive-pack git-upload-archive git-shell git-remote-ext)
846
847 set(wrapper_test_scripts
863 - test-fake-ssh test-line-buffer test-svn-fe test-tool)
848 + test-fake-ssh test-tool)
849
850
851 foreach(script ${wrapper_scripts})
@@ -961,7 +946,6 @@ if(NOT ${CMAKE_BINARY_DIR}/CMakeCache.txt STREQUAL ${CACHE_PATH})
946 file(COPY ${CMAKE_SOURCE_DIR}/mergetools/tkdiff DESTINATION ${CMAKE_BINARY_DIR}/mergetools/)
947 file(COPY ${CMAKE_SOURCE_DIR}/contrib/completion/git-prompt.sh DESTINATION ${CMAKE_BINARY_DIR}/contrib/completion/)
948 file(COPY ${CMAKE_SOURCE_DIR}/contrib/completion/git-completion.bash DESTINATION ${CMAKE_BINARY_DIR}/contrib/completion/)
964 - file(COPY ${CMAKE_SOURCE_DIR}/contrib/svn-fe/svnrdump_sim.py DESTINATION ${CMAKE_BINARY_DIR}/contrib/svn-fe/)
949 endif()
950
951 file(GLOB test_scipts "${CMAKE_SOURCE_DIR}/t/t[0-9]*.sh")
contrib/svn-fe/.gitignore deleted
-4
@@ -1,4 +0,0 @@
1 -/*.xml
2 -/*.1
3 -/*.html
4 -/svn-fe
contrib/svn-fe/Makefile deleted
-105
@@ -1,105 +0,0 @@
1 -all:: svn-fe$X
2 -
3 -CC = cc
4 -RM = rm -f
5 -MV = mv
6 -
7 -CFLAGS = -g -O2 -Wall
8 -LDFLAGS =
9 -EXTLIBS = -lz
10 -
11 -include ../../config.mak.uname
12 --include ../../config.mak.autogen
13 --include ../../config.mak
14 -
15 -ifeq ($(uname_S),Darwin)
16 - ifndef NO_FINK
17 - ifeq ($(shell test -d /sw/lib && echo y),y)
18 - CFLAGS += -I/sw/include
19 - LDFLAGS += -L/sw/lib
20 - endif
21 - endif
22 - ifndef NO_DARWIN_PORTS
23 - ifeq ($(shell test -d /opt/local/lib && echo y),y)
24 - CFLAGS += -I/opt/local/include
25 - LDFLAGS += -L/opt/local/lib
26 - endif
27 - endif
28 -endif
29 -
30 -ifndef NO_OPENSSL
31 - EXTLIBS += -lssl
32 - ifdef NEEDS_CRYPTO_WITH_SSL
33 - EXTLIBS += -lcrypto
34 - endif
35 -endif
36 -
37 -ifndef NO_PTHREADS
38 - CFLAGS += $(PTHREADS_CFLAGS)
39 - EXTLIBS += $(PTHREAD_LIBS)
40 -endif
41 -
42 -ifdef HAVE_CLOCK_GETTIME
43 - CFLAGS += -DHAVE_CLOCK_GETTIME
44 - EXTLIBS += -lrt
45 -endif
46 -
47 -ifdef NEEDS_LIBICONV
48 - EXTLIBS += -liconv
49 -endif
50 -
51 -GIT_LIB = ../../libgit.a
52 -VCSSVN_LIB = ../../vcs-svn/lib.a
53 -XDIFF_LIB = ../../xdiff/lib.a
54 -
55 -LIBS = $(VCSSVN_LIB) $(GIT_LIB) $(XDIFF_LIB)
56 -
57 -QUIET_SUBDIR0 = +$(MAKE) -C # space to separate -C and subdir
58 -QUIET_SUBDIR1 =
59 -
60 -ifneq ($(findstring $(MAKEFLAGS),w),w)
61 -PRINT_DIR = --no-print-directory
62 -else # "make -w"
63 -NO_SUBDIR = :
64 -endif
65 -
66 -ifneq ($(findstring $(MAKEFLAGS),s),s)
67 -ifndef V
68 - QUIET_CC = @echo ' ' CC $@;
69 - QUIET_LINK = @echo ' ' LINK $@;
70 - QUIET_SUBDIR0 = +@subdir=
71 - QUIET_SUBDIR1 = ;$(NO_SUBDIR) echo ' ' SUBDIR $$subdir; \
72 - $(MAKE) $(PRINT_DIR) -C $$subdir
73 -endif
74 -endif
75 -
76 -svn-fe$X: svn-fe.o $(VCSSVN_LIB) $(XDIFF_LIB) $(GIT_LIB)
77 - $(QUIET_LINK)$(CC) $(CFLAGS) $(LDFLAGS) $(EXTLIBS) -o $@ svn-fe.o $(LIBS)
78 -
79 -svn-fe.o: svn-fe.c ../../vcs-svn/svndump.h
80 - $(QUIET_CC)$(CC) $(CFLAGS) -I../../vcs-svn -o $*.o -c $<
81 -
82 -svn-fe.html: svn-fe.txt
83 - $(QUIET_SUBDIR0)../../Documentation $(QUIET_SUBDIR1) \
84 - MAN_TXT=../contrib/svn-fe/svn-fe.txt \
85 - ../contrib/svn-fe/$@
86 -
87 -svn-fe.1: svn-fe.txt
88 - $(QUIET_SUBDIR0)../../Documentation $(QUIET_SUBDIR1) \
89 - MAN_TXT=../contrib/svn-fe/svn-fe.txt \
90 - ../contrib/svn-fe/$@
91 - $(MV) ../../Documentation/svn-fe.1 .
92 -
93 -../../vcs-svn/lib.a: FORCE
94 - $(QUIET_SUBDIR0)../.. $(QUIET_SUBDIR1) vcs-svn/lib.a
95 -
96 -../../xdiff/lib.a: FORCE
97 - $(QUIET_SUBDIR0)../.. $(QUIET_SUBDIR1) xdiff/lib.a
98 -
99 -../../libgit.a: FORCE
100 - $(QUIET_SUBDIR0)../.. $(QUIET_SUBDIR1) libgit.a
101 -
102 -clean:
103 - $(RM) svn-fe$X svn-fe.o svn-fe.html svn-fe.xml svn-fe.1
104 -
105 -.PHONY: all clean FORCE
contrib/svn-fe/svn-fe.c deleted
-18
@@ -1,18 +0,0 @@
1 -/*
2 - * This file is in the public domain.
3 - * You may freely use, modify, distribute, and relicense it.
4 - */
5 -
6 -#include <stdlib.h>
7 -#include "svndump.h"
8 -
9 -int main(int argc, char **argv)
10 -{
11 - if (svndump_init(NULL))
12 - return 1;
13 - svndump_read((argc > 1) ? argv[1] : NULL, "refs/heads/master",
14 - "refs/notes/svn/revs");
15 - svndump_deinit();
16 - svndump_reset();
17 - return 0;
18 -}
contrib/svn-fe/svn-fe.txt deleted
-71
@@ -1,71 +0,0 @@
1 -svn-fe(1)
2 -=========
3 -
4 -NAME
5 -----
6 -svn-fe - convert an SVN "dumpfile" to a fast-import stream
7 -
8 -SYNOPSIS
9 ---------
10 -[verse]
11 -mkfifo backchannel &&
12 -svnadmin dump --deltas REPO |
13 - svn-fe [url] 3<backchannel |
14 - git fast-import --cat-blob-fd=3 3>backchannel
15 -
16 -DESCRIPTION
17 ------------
18 -
19 -Converts a Subversion dumpfile into input suitable for
20 -git-fast-import(1) and similar importers. REPO is a path to a
21 -Subversion repository mirrored on the local disk. Remote Subversion
22 -repositories can be mirrored on local disk using the `svnsync`
23 -command.
24 -
25 -Note: this tool is very young. The details of its commandline
26 -interface may change in backward incompatible ways.
27 -
28 -INPUT FORMAT
29 -------------
30 -Subversion's repository dump format is documented in full in
31 -`notes/dump-load-format.txt` from the Subversion source tree.
32 -Files in this format can be generated using the 'svnadmin dump' or
33 -'svk admin dump' command.
34 -
35 -OUTPUT FORMAT
36 --------------
37 -The fast-import format is documented by the git-fast-import(1)
38 -manual page.
39 -
40 -NOTES
41 ------
42 -Subversion dumps do not record a separate author and committer for
43 -each revision, nor do they record a separate display name and email
44 -address for each author. Like git-svn(1), 'svn-fe' will use the name
45 -
46 ----------
47 -user <user@UUID>
48 ----------
49 -
50 -as committer, where 'user' is the value of the `svn:author` property
51 -and 'UUID' the repository's identifier.
52 -
53 -To support incremental imports, 'svn-fe' puts a `git-svn-id` line at
54 -the end of each commit log message if passed a URL on the command
55 -line. This line has the form `git-svn-id: URL@REVNO UUID`.
56 -
57 -The resulting repository will generally require further processing
58 -to put each project in its own repository and to separate the history
59 -of each branch. The 'git filter-repo --subdirectory-filter' command
60 -may be useful for this purpose.
61 -
62 -BUGS
63 -----
64 -Empty directories and unknown properties are silently discarded.
65 -
66 -The exit status does not reflect whether an error was detected.
67 -
68 -SEE ALSO
69 ---------
70 -git-svn(1), svn2git(1), svk(1), git-filter-repo(1), git-fast-import(1),
71 -https://svn.apache.org/repos/asf/subversion/trunk/notes/dump-load-format.txt
contrib/svn-fe/svnrdump_sim.py deleted
-68
@@ -1,68 +0,0 @@
1 -#!/usr/bin/env python
2 -"""
3 -Simulates svnrdump by replaying an existing dump from a file, taking care
4 -of the specified revision range.
5 -To simulate incremental imports the environment variable SVNRMAX can be set
6 -to the highest revision that should be available.
7 -"""
8 -import sys
9 -import os
10 -
11 -if sys.hexversion < 0x02040000:
12 - # The limiter is the ValueError() calls. This may be too conservative
13 - sys.stderr.write("svnrdump-sim.py: requires Python 2.4 or later.\n")
14 - sys.exit(1)
15 -
16 -
17 -def getrevlimit():
18 - var = 'SVNRMAX'
19 - if var in os.environ:
20 - return os.environ[var]
21 - return None
22 -
23 -
24 -def writedump(url, lower, upper):
25 - if url.startswith('sim://'):
26 - filename = url[6:]
27 - if filename[-1] == '/':
28 - filename = filename[:-1] # remove terminating slash
29 - else:
30 - raise ValueError('sim:// url required')
31 - f = open(filename, 'r')
32 - state = 'header'
33 - wroterev = False
34 - while(True):
35 - l = f.readline()
36 - if l == '':
37 - break
38 - if state == 'header' and l.startswith('Revision-number: '):
39 - state = 'prefix'
40 - if state == 'prefix' and l == 'Revision-number: %s\n' % lower:
41 - state = 'selection'
42 - if not upper == 'HEAD' and state == 'selection' and \
43 - l == 'Revision-number: %s\n' % upper:
44 - break
45 -
46 - if state == 'header' or state == 'selection':
47 - if state == 'selection':
48 - wroterev = True
49 - sys.stdout.write(l)
50 - return wroterev
51 -
52 -if __name__ == "__main__":
53 - if not (len(sys.argv) in (3, 4, 5)):
54 - print("usage: %s dump URL -rLOWER:UPPER")
55 - sys.exit(1)
56 - if not sys.argv[1] == 'dump':
57 - raise NotImplementedError('only "dump" is supported.')
58 - url = sys.argv[2]
59 - r = ('0', 'HEAD')
60 - if len(sys.argv) == 4 and sys.argv[3][0:2] == '-r':
61 - r = sys.argv[3][2:].lstrip().split(':')
62 - if not getrevlimit() is None:
63 - r[1] = getrevlimit()
64 - if writedump(url, r[0], r[1]):
65 - ret = 0
66 - else:
67 - ret = 1
68 - sys.exit(ret)
remote-testsvn.c deleted
-341
@@ -1,341 +0,0 @@
1 -#include "cache.h"
2 -#include "refs.h"
3 -#include "remote.h"
4 -#include "object-store.h"
5 -#include "strbuf.h"
6 -#include "url.h"
7 -#include "exec-cmd.h"
8 -#include "run-command.h"
9 -#include "vcs-svn/svndump.h"
10 -#include "notes.h"
11 -#include "strvec.h"
12 -
13 -static const char *url;
14 -static int dump_from_file;
15 -static const char *private_ref;
16 -static char *remote_ref;
17 -static const char *marksfilename, *notes_ref;
18 -struct rev_note { unsigned int rev_nr; };
19 -
20 -static int cmd_capabilities(const char *line);
21 -static int cmd_import(const char *line);
22 -static int cmd_list(const char *line);
23 -
24 -typedef int (*input_command_handler)(const char *);
25 -struct input_command_entry {
26 - const char *name;
27 - input_command_handler fn;
28 - unsigned char batchable; /* whether the command starts or is part of a batch */
29 -};
30 -
31 -static const struct input_command_entry input_command_list[] = {
32 - { "capabilities", cmd_capabilities, 0 },
33 - { "import", cmd_import, 1 },
34 - { "list", cmd_list, 0 },
35 - { NULL, NULL }
36 -};
37 -
38 -static int cmd_capabilities(const char *line)
39 -{
40 - printf("import\n");
41 - printf("bidi-import\n");
42 - printf("refspec %s:%s\n\n", remote_ref, private_ref);
43 - fflush(stdout);
44 - return 0;
45 -}
46 -
47 -static void terminate_batch(void)
48 -{
49 - /* terminate a current batch's fast-import stream */
50 - printf("done\n");
51 - fflush(stdout);
52 -}
53 -
54 -/* NOTE: 'ref' refers to a git reference, while 'rev' refers to a svn revision. */
55 -static char *read_ref_note(const struct object_id *oid)
56 -{
57 - const struct object_id *note_oid;
58 - char *msg = NULL;
59 - unsigned long msglen;
60 - enum object_type type;
61 -
62 - init_notes(NULL, notes_ref, NULL, 0);
63 - if (!(note_oid = get_note(NULL, oid)))
64 - return NULL; /* note tree not found */
65 - if (!(msg = read_object_file(note_oid, &type, &msglen)))
66 - error("Empty notes tree. %s", notes_ref);
67 - else if (!msglen || type != OBJ_BLOB) {
68 - error("Note contains unusable content. "
69 - "Is something else using this notes tree? %s", notes_ref);
70 - FREE_AND_NULL(msg);
71 - }
72 - free_notes(NULL);
73 - return msg;
74 -}
75 -
76 -static int parse_rev_note(const char *msg, struct rev_note *res)
77 -{
78 - const char *key, *value, *end;
79 - size_t len;
80 -
81 - while (*msg) {
82 - end = strchrnul(msg, '\n');
83 - len = end - msg;
84 -
85 - key = "Revision-number: ";
86 - if (starts_with(msg, key)) {
87 - long i;
88 - char *end;
89 - value = msg + strlen(key);
90 - i = strtol(value, &end, 0);
91 - if (end == value || i < 0 || i > UINT32_MAX)
92 - return -1;
93 - res->rev_nr = i;
94 - return 0;
95 - }
96 - msg += len + 1;
97 - }
98 - /* didn't find it */
99 - return -1;
100 -}
101 -
102 -static int note2mark_cb(const struct object_id *object_oid,
103 - const struct object_id *note_oid, char *note_path,
104 - void *cb_data)
105 -{
106 - FILE *file = (FILE *)cb_data;
107 - char *msg;
108 - unsigned long msglen;
109 - enum object_type type;
110 - struct rev_note note;
111 -
112 - if (!(msg = read_object_file(note_oid, &type, &msglen)) ||
113 - !msglen || type != OBJ_BLOB) {
114 - free(msg);
115 - return 1;
116 - }
117 - if (parse_rev_note(msg, &note))
118 - return 2;
119 - if (fprintf(file, ":%d %s\n", note.rev_nr, oid_to_hex(object_oid)) < 1)
120 - return 3;
121 - return 0;
122 -}
123 -
124 -static void regenerate_marks(void)
125 -{
126 - int ret;
127 - FILE *marksfile = xfopen(marksfilename, "w+");
128 -
129 - ret = for_each_note(NULL, 0, note2mark_cb, marksfile);
130 - if (ret)
131 - die("Regeneration of marks failed, returned %d.", ret);
132 - fclose(marksfile);
133 -}
134 -
135 -static void check_or_regenerate_marks(int latestrev)
136 -{
137 - FILE *marksfile;
138 - struct strbuf sb = STRBUF_INIT;
139 - struct strbuf line = STRBUF_INIT;
140 - int found = 0;
141 -
142 - if (latestrev < 1)
143 - return;
144 -
145 - init_notes(NULL, notes_ref, NULL, 0);
146 - marksfile = fopen(marksfilename, "r");
147 - if (!marksfile) {
148 - regenerate_marks();
149 - marksfile = xfopen(marksfilename, "r");
150 - fclose(marksfile);
151 - } else {
152 - strbuf_addf(&sb, ":%d ", latestrev);
153 - while (strbuf_getline_lf(&line, marksfile) != EOF) {
154 - if (starts_with(line.buf, sb.buf)) {
155 - found++;
156 - break;
157 - }
158 - }
159 - fclose(marksfile);
160 - if (!found)
161 - regenerate_marks();
162 - }
163 - free_notes(NULL);
164 - strbuf_release(&sb);
165 - strbuf_release(&line);
166 -}
167 -
168 -static int cmd_import(const char *line)
169 -{
170 - int code;
171 - int dumpin_fd;
172 - char *note_msg;
173 - struct object_id head_oid;
174 - unsigned int startrev;
175 - struct child_process svndump_proc = CHILD_PROCESS_INIT;
176 - const char *command = "svnrdump";
177 -
178 - if (read_ref(private_ref, &head_oid))
179 - startrev = 0;
180 - else {
181 - note_msg = read_ref_note(&head_oid);
182 - if(note_msg == NULL) {
183 - warning("No note found for %s.", private_ref);
184 - startrev = 0;
185 - } else {
186 - struct rev_note note = { 0 };
187 - if (parse_rev_note(note_msg, &note))
188 - die("Revision number couldn't be parsed from note.");
189 - startrev = note.rev_nr + 1;
190 - free(note_msg);
191 - }
192 - }
193 - check_or_regenerate_marks(startrev - 1);
194 -
195 - if (dump_from_file) {
196 - dumpin_fd = open(url, O_RDONLY);
197 - if(dumpin_fd < 0)
198 - die_errno("Couldn't open svn dump file %s.", url);
199 - } else {
200 - svndump_proc.out = -1;
201 - strvec_push(&svndump_proc.args, command);
202 - strvec_push(&svndump_proc.args, "dump");
203 - strvec_push(&svndump_proc.args, url);
204 - strvec_pushf(&svndump_proc.args, "-r%u:HEAD", startrev);
205 -
206 - code = start_command(&svndump_proc);
207 - if (code)
208 - die("Unable to start %s, code %d", command, code);
209 - dumpin_fd = svndump_proc.out;
210 - }
211 - /* setup marks file import/export */
212 - printf("feature import-marks-if-exists=%s\n"
213 - "feature export-marks=%s\n", marksfilename, marksfilename);
214 -
215 - svndump_init_fd(dumpin_fd, STDIN_FILENO);
216 - svndump_read(url, private_ref, notes_ref);
217 - svndump_deinit();
218 - svndump_reset();
219 -
220 - close(dumpin_fd);
221 - if (!dump_from_file) {
222 - code = finish_command(&svndump_proc);
223 - if (code)
224 - warning("%s, returned %d", command, code);
225 - }
226 -
227 - return 0;
228 -}
229 -
230 -static int cmd_list(const char *line)
231 -{
232 - printf("? %s\n\n", remote_ref);
233 - fflush(stdout);
234 - return 0;
235 -}
236 -
237 -static int do_command(struct strbuf *line)
238 -{
239 - const struct input_command_entry *p = input_command_list;
240 - static struct string_list batchlines = STRING_LIST_INIT_DUP;
241 - static const struct input_command_entry *batch_cmd;
242 - /*
243 - * commands can be grouped together in a batch.
244 - * Batches are ended by \n. If no batch is active the program ends.
245 - * During a batch all lines are buffered and passed to the handler function
246 - * when the batch is terminated.
247 - */
248 - if (line->len == 0) {
249 - if (batch_cmd) {
250 - struct string_list_item *item;
251 - for_each_string_list_item(item, &batchlines)
252 - batch_cmd->fn(item->string);
253 - terminate_batch();
254 - batch_cmd = NULL;
255 - string_list_clear(&batchlines, 0);
256 - return 0; /* end of the batch, continue reading other commands. */
257 - }
258 - return 1; /* end of command stream, quit */
259 - }
260 - if (batch_cmd) {
261 - if (!starts_with(batch_cmd->name, line->buf))
262 - die("Active %s batch interrupted by %s", batch_cmd->name, line->buf);
263 - /* buffer batch lines */
264 - string_list_append(&batchlines, line->buf);
265 - return 0;
266 - }
267 -
268 - for (p = input_command_list; p->name; p++) {
269 - if (starts_with(line->buf, p->name) && (strlen(p->name) == line->len ||
270 - line->buf[strlen(p->name)] == ' ')) {
271 - if (p->batchable) {
272 - batch_cmd = p;
273 - string_list_append(&batchlines, line->buf);
274 - return 0;
275 - }
276 - return p->fn(line->buf);
277 - }
278 - }
279 - die("Unknown command '%s'\n", line->buf);
280 - return 0;
281 -}
282 -
283 -int cmd_main(int argc, const char **argv)
284 -{
285 - struct strbuf buf = STRBUF_INIT, url_sb = STRBUF_INIT,
286 - private_ref_sb = STRBUF_INIT, marksfilename_sb = STRBUF_INIT,
287 - notes_ref_sb = STRBUF_INIT;
288 - static struct remote *remote;
289 - const char *url_in, *remote_ref_short;
290 -
291 - setup_git_directory();
292 - if (argc < 2 || argc > 3) {
293 - usage("git-remote-svn <remote-name> [<url>]");
294 - return 1;
295 - }
296 -
297 - remote_ref_short = git_default_branch_name();
298 - remote_ref = xstrfmt("refs/heads/%s", remote_ref_short);
299 -
300 - remote = remote_get(argv[1]);
301 - url_in = (argc == 3) ? argv[2] : remote->url[0];
302 -
303 - if (starts_with(url_in, "file://")) {
304 - dump_from_file = 1;
305 - url = url_decode(url_in + sizeof("file://")-1);
306 - } else {
307 - dump_from_file = 0;
308 - end_url_with_slash(&url_sb, url_in);
309 - url = url_sb.buf;
310 - }
311 -
312 - strbuf_addf(&private_ref_sb, "refs/svn/%s/%s",
313 - remote->name, remote_ref_short);
314 - private_ref = private_ref_sb.buf;
315 -
316 - strbuf_addf(&notes_ref_sb, "refs/notes/%s/revs", remote->name);
317 - notes_ref = notes_ref_sb.buf;
318 -
319 - strbuf_addf(&marksfilename_sb, "%s/info/fast-import/remote-svn/%s.marks",
320 - get_git_dir(), remote->name);
321 - marksfilename = marksfilename_sb.buf;
322 -
323 - while (1) {
324 - if (strbuf_getline_lf(&buf, stdin) == EOF) {
325 - if (ferror(stdin))
326 - die("Error reading command stream");
327 - else
328 - die("Unexpected end of command stream");
329 - }
330 - if (do_command(&buf))
331 - break;
332 - strbuf_reset(&buf);
333 - }
334 -
335 - strbuf_release(&buf);
336 - strbuf_release(&url_sb);
337 - strbuf_release(&private_ref_sb);
338 - strbuf_release(&notes_ref_sb);
339 - strbuf_release(&marksfilename_sb);
340 - return 0;
341 -}
t/helper/.gitignore
-2
@@ -1,4 +1,2 @@
1 /test-tool
2 /test-fake-ssh
3 -/test-line-buffer
4 -/test-svn-fe
t/helper/test-line-buffer.c deleted
-81
@@ -1,81 +0,0 @@
1 -/*
2 - * test-line-buffer.c: code to exercise the svn importer's input helper
3 - */
4 -
5 -#include "git-compat-util.h"
6 -#include "strbuf.h"
7 -#include "vcs-svn/line_buffer.h"
8 -
9 -static uint32_t strtouint32(const char *s)
10 -{
11 - char *end;
12 - uintmax_t n = strtoumax(s, &end, 10);
13 - if (*s == '\0' || *end != '\0')
14 - die("invalid count: %s", s);
15 - return (uint32_t) n;
16 -}
17 -
18 -static void handle_command(const char *command, const char *arg, struct line_buffer *buf)
19 -{
20 - if (starts_with(command, "binary ")) {
21 - struct strbuf sb = STRBUF_INIT;
22 - strbuf_addch(&sb, '>');
23 - buffer_read_binary(buf, &sb, strtouint32(arg));
24 - fwrite(sb.buf, 1, sb.len, stdout);
25 - strbuf_release(&sb);
26 - } else if (starts_with(command, "copy ")) {
27 - buffer_copy_bytes(buf, strtouint32(arg));
28 - } else if (starts_with(command, "skip ")) {
29 - buffer_skip_bytes(buf, strtouint32(arg));
30 - } else {
31 - die("unrecognized command: %s", command);
32 - }
33 -}
34 -
35 -static void handle_line(const char *line, struct line_buffer *stdin_buf)
36 -{
37 - const char *arg = strchr(line, ' ');
38 - if (!arg)
39 - die("no argument in line: %s", line);
40 - handle_command(line, arg + 1, stdin_buf);
41 -}
42 -
43 -int cmd_main(int argc, const char **argv)
44 -{
45 - struct line_buffer stdin_buf = LINE_BUFFER_INIT;
46 - struct line_buffer file_buf = LINE_BUFFER_INIT;
47 - struct line_buffer *input = &stdin_buf;
48 - const char *filename;
49 - char *s;
50 -
51 - if (argc == 1)
52 - filename = NULL;
53 - else if (argc == 2)
54 - filename = argv[1];
55 - else
56 - usage("test-line-buffer [file | &fd] < script");
57 -
58 - if (buffer_init(&stdin_buf, NULL))
59 - die_errno("open error");
60 - if (filename) {
61 - if (*filename == '&') {
62 - if (buffer_fdinit(&file_buf, strtouint32(filename + 1)))
63 - die_errno("error opening fd %s", filename + 1);
64 - } else {
65 - if (buffer_init(&file_buf, filename))
66 - die_errno("error opening %s", filename);
67 - }
68 - input = &file_buf;
69 - }
70 -
71 - while ((s = buffer_read_line(&stdin_buf)))
72 - handle_line(s, input);
73 -
74 - if (filename && buffer_deinit(&file_buf))
75 - die("error reading from %s", filename);
76 - if (buffer_deinit(&stdin_buf))
77 - die("input error");
78 - if (ferror(stdout))
79 - die("output error");
80 - return 0;
81 -}
t/helper/test-svn-fe.c deleted
-52
@@ -1,52 +0,0 @@
1 -/*
2 - * test-svn-fe: Code to exercise the svn import lib
3 - */
4 -
5 -#include "git-compat-util.h"
6 -#include "vcs-svn/svndump.h"
7 -#include "vcs-svn/svndiff.h"
8 -#include "vcs-svn/sliding_window.h"
9 -#include "vcs-svn/line_buffer.h"
10 -
11 -static const char test_svnfe_usage[] =
12 - "test-svn-fe (<dumpfile> | [-d] <preimage> <delta> <len>)";
13 -
14 -static int apply_delta(int argc, const char **argv)
15 -{
16 - struct line_buffer preimage = LINE_BUFFER_INIT;
17 - struct line_buffer delta = LINE_BUFFER_INIT;
18 - struct sliding_view preimage_view = SLIDING_VIEW_INIT(&preimage, -1);
19 -
20 - if (argc != 5)
21 - usage(test_svnfe_usage);
22 -
23 - if (buffer_init(&preimage, argv[2]))
24 - die_errno("cannot open preimage");
25 - if (buffer_init(&delta, argv[3]))
26 - die_errno("cannot open delta");
27 - if (svndiff0_apply(&delta, (off_t) strtoumax(argv[4], NULL, 0),
28 - &preimage_view, stdout))
29 - return 1;
30 - if (buffer_deinit(&preimage))
31 - die_errno("cannot close preimage");
32 - if (buffer_deinit(&delta))
33 - die_errno("cannot close delta");
34 - strbuf_release(&preimage_view.buf);
35 - return 0;
36 -}
37 -
38 -int cmd_main(int argc, const char **argv)
39 -{
40 - if (argc == 2) {
41 - if (svndump_init(argv[1]))
42 - return 1;
43 - svndump_read(NULL, "refs/heads/master", "refs/notes/svn/revs");
44 - svndump_deinit();
45 - svndump_reset();
46 - return 0;
47 - }
48 -
49 - if (argc >= 2 && !strcmp(argv[1], "-d"))
50 - return apply_delta(argc, argv);
51 - usage(test_svnfe_usage);
52 -}
t/t0081-line-buffer.sh deleted
-90
@@ -1,90 +0,0 @@
1 -#!/bin/sh
2 -
3 -test_description="Test the svn importer's input handling routines.
4 -
5 -These tests provide some simple checks that the line_buffer API
6 -behaves as advertised.
7 -
8 -While at it, check that input of newlines and null bytes are handled
9 -correctly.
10 -"
11 -. ./test-lib.sh
12 -
13 -test_expect_success 'hello world' '
14 - echo ">HELLO" >expect &&
15 - test-line-buffer <<-\EOF >actual &&
16 - binary 6
17 - HELLO
18 - EOF
19 - test_cmp expect actual
20 -'
21 -
22 -test_expect_success '0-length read, send along greeting' '
23 - echo ">HELLO" >expect &&
24 - test-line-buffer <<-\EOF >actual &&
25 - binary 0
26 - copy 6
27 - HELLO
28 - EOF
29 - test_cmp expect actual
30 -'
31 -
32 -test_expect_success !MINGW 'read from file descriptor' '
33 - rm -f input &&
34 - echo hello >expect &&
35 - echo hello >input &&
36 - echo copy 6 |
37 - test-line-buffer "&4" 4<input >actual &&
38 - test_cmp expect actual
39 -'
40 -
41 -test_expect_success 'skip, copy null byte' '
42 - echo Q | q_to_nul >expect &&
43 - q_to_nul <<-\EOF | test-line-buffer >actual &&
44 - skip 2
45 - Q
46 - copy 2
47 - Q
48 - EOF
49 - test_cmp expect actual
50 -'
51 -
52 -test_expect_success 'read null byte' '
53 - echo ">QhelloQ" | q_to_nul >expect &&
54 - q_to_nul <<-\EOF | test-line-buffer >actual &&
55 - binary 8
56 - QhelloQ
57 - EOF
58 - test_cmp expect actual
59 -'
60 -
61 -test_expect_success 'long reads are truncated' '
62 - echo ">foo" >expect &&
63 - test-line-buffer <<-\EOF >actual &&
64 - binary 5
65 - foo
66 - EOF
67 - test_cmp expect actual
68 -'
69 -
70 -test_expect_success 'long copies are truncated' '
71 - printf "%s\n" ">" foo >expect &&
72 - test-line-buffer <<-\EOF >actual &&
73 - binary 1
74 -
75 - copy 5
76 - foo
77 - EOF
78 - test_cmp expect actual
79 -'
80 -
81 -test_expect_success 'long binary reads are truncated' '
82 - echo ">foo" >expect &&
83 - test-line-buffer <<-\EOF >actual &&
84 - binary 5
85 - foo
86 - EOF
87 - test_cmp expect actual
88 -'
89 -
90 -test_done
t/t9010-svn-fe.sh deleted
-1105
@@ -1,1105 +0,0 @@
1 -#!/bin/sh
2 -
3 -test_description='check svn dumpfile importer'
4 -
5 -. ./test-lib.sh
6 -
7 -if test_have_prereq !PIPE
8 -then
9 - skip_all="svn dumpfile importer testing requires the PIPE prerequisite"
10 - test_done
11 -fi
12 -
13 -reinit_git () {
14 - rm -fr .git &&
15 - rm -f stream backflow &&
16 - git init &&
17 - mkfifo stream backflow
18 -}
19 -
20 -try_dump () {
21 - input=$1 &&
22 - maybe_fail_svnfe=${2:+test_$2} &&
23 - maybe_fail_fi=${3:+test_$3} &&
24 -
25 - {
26 - $maybe_fail_svnfe test-svn-fe "$input" >stream 3<backflow &
27 - } &&
28 - $maybe_fail_fi git fast-import --cat-blob-fd=3 <stream 3>backflow &&
29 - wait $!
30 -}
31 -
32 -properties () {
33 - while test "$#" -ne 0
34 - do
35 - property="$1" &&
36 - value="$2" &&
37 - printf "%s\n" "K ${#property}" &&
38 - printf "%s\n" "$property" &&
39 - printf "%s\n" "V ${#value}" &&
40 - printf "%s\n" "$value" &&
41 - shift 2 ||
42 - return 1
43 - done
44 -}
45 -
46 -text_no_props () {
47 - text="$1
48 -" &&
49 - printf "%s\n" "Prop-content-length: 10" &&
50 - printf "%s\n" "Text-content-length: ${#text}" &&
51 - printf "%s\n" "Content-length: $((${#text} + 10))" &&
52 - printf "%s\n" "" "PROPS-END" &&
53 - printf "%s\n" "$text"
54 -}
55 -
56 -test_expect_success 'empty dump' '
57 - reinit_git &&
58 - echo "SVN-fs-dump-format-version: 2" >input &&
59 - try_dump input
60 -'
61 -
62 -test_expect_success 'v4 dumps not supported' '
63 - reinit_git &&
64 - echo "SVN-fs-dump-format-version: 4" >v4.dump &&
65 - try_dump v4.dump must_fail
66 -'
67 -
68 -test_expect_failure 'empty revision' '
69 - reinit_git &&
70 - printf "rev <nobody, nobody@local>: %s\n" "" "" >expect &&
71 - cat >emptyrev.dump <<-\EOF &&
72 - SVN-fs-dump-format-version: 3
73 -
74 - Revision-number: 1
75 - Prop-content-length: 0
76 - Content-length: 0
77 -
78 - Revision-number: 2
79 - Prop-content-length: 0
80 - Content-length: 0
81 -
82 - EOF
83 - try_dump emptyrev.dump &&
84 - git log -p --format="rev <%an, %ae>: %s" HEAD >actual &&
85 - test_cmp expect actual
86 -'
87 -
88 -test_expect_success 'empty properties' '
89 - reinit_git &&
90 - printf "rev <nobody, nobody@local>: %s\n" "" "" >expect &&
91 - cat >emptyprop.dump <<-\EOF &&
92 - SVN-fs-dump-format-version: 3
93 -
94 - Revision-number: 1
95 - Prop-content-length: 10
96 - Content-length: 10
97 -
98 - PROPS-END
99 -
100 - Revision-number: 2
101 - Prop-content-length: 10
102 - Content-length: 10
103 -
104 - PROPS-END
105 - EOF
106 - try_dump emptyprop.dump &&
107 - git log -p --format="rev <%an, %ae>: %s" HEAD >actual &&
108 - test_cmp expect actual
109 -'
110 -
111 -test_expect_success 'author name and commit message' '
112 - reinit_git &&
113 - echo "<author@example.com, author@example.com@local>" >expect.author &&
114 - cat >message <<-\EOF &&
115 - A concise summary of the change
116 -
117 - A detailed description of the change, why it is needed, what
118 - was broken and why applying this is the best course of action.
119 -
120 - * file.c
121 - Details pertaining to an individual file.
122 - EOF
123 - {
124 - properties \
125 - svn:author author@example.com \
126 - svn:log "$(cat message)" &&
127 - echo PROPS-END
128 - } >props &&
129 - {
130 - echo "SVN-fs-dump-format-version: 3" &&
131 - echo &&
132 - echo "Revision-number: 1" &&
133 - echo Prop-content-length: $(wc -c <props) &&
134 - echo Content-length: $(wc -c <props) &&
135 - echo &&
136 - cat props
137 - } >log.dump &&
138 - try_dump log.dump &&
139 - git log -p --format="%B" HEAD >actual.log &&
140 - git log --format="<%an, %ae>" >actual.author &&
141 - test_cmp message actual.log &&
142 - test_cmp expect.author actual.author
143 -'
144 -
145 -test_expect_success 'unsupported properties are ignored' '
146 - reinit_git &&
147 - echo author >expect &&
148 - cat >extraprop.dump <<-\EOF &&
149 - SVN-fs-dump-format-version: 3
150 -
151 - Revision-number: 1
152 - Prop-content-length: 56
153 - Content-length: 56
154 -
155 - K 8
156 - nonsense
157 - V 1
158 - y
159 - K 10
160 - svn:author
161 - V 6
162 - author
163 - PROPS-END
164 - EOF
165 - try_dump extraprop.dump &&
166 - git log -p --format=%an HEAD >actual &&
167 - test_cmp expect actual
168 -'
169 -
170 -test_expect_failure 'timestamp and empty file' '
171 - echo author@example.com >expect.author &&
172 - echo 1999-01-01 >expect.date &&
173 - echo file >expect.files &&
174 - reinit_git &&
175 - {
176 - properties \
177 - svn:author author@example.com \
178 - svn:date "1999-01-01T00:01:002.000000Z" \
179 - svn:log "add empty file" &&
180 - echo PROPS-END
181 - } >props &&
182 - {
183 - cat <<-EOF &&
184 - SVN-fs-dump-format-version: 3
185 -
186 - Revision-number: 1
187 - EOF
188 - echo Prop-content-length: $(wc -c <props) &&
189 - echo Content-length: $(wc -c <props) &&
190 - echo &&
191 - cat props &&
192 - cat <<-\EOF
193 -
194 - Node-path: empty-file
195 - Node-kind: file
196 - Node-action: add
197 - Content-length: 0
198 -
199 - EOF
200 - } >emptyfile.dump &&
201 - try_dump emptyfile.dump &&
202 - git log --format=%an HEAD >actual.author &&
203 - git log --date=short --format=%ad HEAD >actual.date &&
204 - git ls-tree -r --name-only HEAD >actual.files &&
205 - test_cmp expect.author actual.author &&
206 - test_cmp expect.date actual.date &&
207 - test_cmp expect.files actual.files &&
208 - git checkout HEAD empty-file &&
209 - test_must_be_empty file
210 -'
211 -
212 -test_expect_success 'directory with files' '
213 - reinit_git &&
214 - printf "%s\n" directory/file1 directory/file2 >expect.files &&
215 - echo hi >hi &&
216 - echo hello >hello &&
217 - {
218 - properties \
219 - svn:author author@example.com \
220 - svn:date "1999-02-01T00:01:002.000000Z" \
221 - svn:log "add directory with some files in it" &&
222 - echo PROPS-END
223 - } >props &&
224 - {
225 - cat <<-EOF &&
226 - SVN-fs-dump-format-version: 3
227 -
228 - Revision-number: 1
229 - EOF
230 - echo Prop-content-length: $(wc -c <props) &&
231 - echo Content-length: $(wc -c <props) &&
232 - echo &&
233 - cat props &&
234 - cat <<-\EOF &&
235 -
236 - Node-path: directory
237 - Node-kind: dir
238 - Node-action: add
239 - Prop-content-length: 10
240 - Content-length: 10
241 -
242 - PROPS-END
243 -
244 - Node-path: directory/file1
245 - Node-kind: file
246 - Node-action: add
247 - EOF
248 - text_no_props hello &&
249 - cat <<-\EOF &&
250 - Node-path: directory/file2
251 - Node-kind: file
252 - Node-action: add
253 - EOF
254 - text_no_props hi
255 - } >directory.dump &&
256 - try_dump directory.dump &&
257 -
258 - git ls-tree -r --name-only HEAD >actual.files &&
259 - git checkout HEAD directory &&
260 - test_cmp expect.files actual.files &&
261 - test_cmp hello directory/file1 &&
262 - test_cmp hi directory/file2
263 -'
264 -
265 -test_expect_success 'branch name with backslash' '
266 - reinit_git &&
267 - sort <<-\EOF >expect.branch-files &&
268 - trunk/file1
269 - trunk/file2
270 - "branches/UpdateFOPto094\\/file1"
271 - "branches/UpdateFOPto094\\/file2"
272 - EOF
273 -
274 - echo hi >hi &&
275 - echo hello >hello &&
276 - {
277 - properties \
278 - svn:author author@example.com \
279 - svn:date "1999-02-02T00:01:02.000000Z" \
280 - svn:log "add directory with some files in it" &&
281 - echo PROPS-END
282 - } >props.setup &&
283 - {
284 - properties \
285 - svn:author brancher@example.com \
286 - svn:date "2007-12-06T21:38:34.000000Z" \
287 - svn:log "Updating fop to .94 and adjust fo-stylesheets" &&
288 - echo PROPS-END
289 - } >props.branch &&
290 - {
291 - cat <<-EOF &&
292 - SVN-fs-dump-format-version: 3
293 -
294 - Revision-number: 1
295 - EOF
296 - echo Prop-content-length: $(wc -c <props.setup) &&
297 - echo Content-length: $(wc -c <props.setup) &&
298 - echo &&
299 - cat props.setup &&
300 - cat <<-\EOF &&
301 -
302 - Node-path: trunk
303 - Node-kind: dir
304 - Node-action: add
305 - Prop-content-length: 10
306 - Content-length: 10
307 -
308 - PROPS-END
309 -
310 - Node-path: branches
311 - Node-kind: dir
312 - Node-action: add
313 - Prop-content-length: 10
314 - Content-length: 10
315 -
316 - PROPS-END
317 -
318 - Node-path: trunk/file1
319 - Node-kind: file
320 - Node-action: add
321 - EOF
322 - text_no_props hello &&
323 - cat <<-\EOF &&
324 - Node-path: trunk/file2
325 - Node-kind: file
326 - Node-action: add
327 - EOF
328 - text_no_props hi &&
329 - cat <<-\EOF &&
330 -
331 - Revision-number: 2
332 - EOF
333 - echo Prop-content-length: $(wc -c <props.branch) &&
334 - echo Content-length: $(wc -c <props.branch) &&
335 - echo &&
336 - cat props.branch &&
337 - cat <<-\EOF
338 -
339 - Node-path: branches/UpdateFOPto094\
340 - Node-kind: dir
341 - Node-action: add
342 - Node-copyfrom-rev: 1
343 - Node-copyfrom-path: trunk
344 -
345 - Node-kind: dir
346 - Node-action: add
347 - Prop-content-length: 34
348 - Content-length: 34
349 -
350 - K 13
351 - svn:mergeinfo
352 - V 0
353 -
354 - PROPS-END
355 - EOF
356 - } >branch.dump &&
357 - try_dump branch.dump &&
358 -
359 - git ls-tree -r --name-only HEAD |
360 - sort >actual.branch-files &&
361 - test_cmp expect.branch-files actual.branch-files
362 -'
363 -
364 -test_expect_success 'node without action' '
365 - reinit_git &&
366 - cat >inaction.dump <<-\EOF &&
367 - SVN-fs-dump-format-version: 3
368 -
369 - Revision-number: 1
370 - Prop-content-length: 10
371 - Content-length: 10
372 -
373 - PROPS-END
374 -
375 - Node-path: directory
376 - Node-kind: dir
377 - Prop-content-length: 10
378 - Content-length: 10
379 -
380 - PROPS-END
381 - EOF
382 - try_dump inaction.dump must_fail
383 -'
384 -
385 -test_expect_success 'action: add node without text' '
386 - reinit_git &&
387 - cat >textless.dump <<-\EOF &&
388 - SVN-fs-dump-format-version: 3
389 -
390 - Revision-number: 1
391 - Prop-content-length: 10
392 - Content-length: 10
393 -
394 - PROPS-END
395 -
396 - Node-path: textless
397 - Node-kind: file
398 - Node-action: add
399 - Prop-content-length: 10
400 - Content-length: 10
401 -
402 - PROPS-END
403 - EOF
404 - try_dump textless.dump must_fail
405 -'
406 -
407 -test_expect_failure 'change file mode but keep old content' '
408 - reinit_git &&
409 - cat >expect <<-\EOF &&
410 - OBJID
411 - :120000 100644 OBJID OBJID T greeting
412 - OBJID
413 - :100644 120000 OBJID OBJID T greeting
414 - OBJID
415 - :000000 100644 OBJID OBJID A greeting
416 - EOF
417 - echo "link hello" >expect.blob &&
418 - echo hello >hello &&
419 - cat >filemode.dump <<-\EOF &&
420 - SVN-fs-dump-format-version: 3
421 -
422 - Revision-number: 1
423 - Prop-content-length: 10
424 - Content-length: 10
425 -
426 - PROPS-END
427 -
428 - Node-path: greeting
429 - Node-kind: file
430 - Node-action: add
431 - Prop-content-length: 10
432 - Text-content-length: 11
433 - Content-length: 21
434 -
435 - PROPS-END
436 - link hello
437 -
438 - Revision-number: 2
439 - Prop-content-length: 10
440 - Content-length: 10
441 -
442 - PROPS-END
443 -
444 - Node-path: greeting
445 - Node-kind: file
446 - Node-action: change
447 - Prop-content-length: 33
448 - Content-length: 33
449 -
450 - K 11
451 - svn:special
452 - V 1
453 - *
454 - PROPS-END
455 -
456 - Revision-number: 3
457 - Prop-content-length: 10
458 - Content-length: 10
459 -
460 - PROPS-END
461 -
462 - Node-path: greeting
463 - Node-kind: file
464 - Node-action: change
465 - Prop-content-length: 10
466 - Content-length: 10
467 -
468 - PROPS-END
469 - EOF
470 - try_dump filemode.dump &&
471 - {
472 - git rev-list HEAD |
473 - git diff-tree --root --stdin |
474 - sed "s/$OID_REGEX/OBJID/g"
475 - } >actual &&
476 - git show HEAD:greeting >actual.blob &&
477 - git show HEAD^:greeting >actual.target &&
478 - test_cmp expect actual &&
479 - test_cmp expect.blob actual.blob &&
480 - test_cmp hello actual.target
481 -'
482 -
483 -test_expect_success 'NUL in property value' '
484 - reinit_git &&
485 - echo "commit message" >expect.message &&
486 - {
487 - properties \
488 - unimportant "something with a NUL (Q)" \
489 - svn:log "commit message" &&
490 - echo PROPS-END
491 - } |
492 - q_to_nul >props &&
493 - {
494 - cat <<-\EOF &&
495 - SVN-fs-dump-format-version: 3
496 -
497 - Revision-number: 1
498 - EOF
499 - echo Prop-content-length: $(wc -c <props) &&
500 - echo Content-length: $(wc -c <props) &&
501 - echo &&
502 - cat props
503 - } >nulprop.dump &&
504 - try_dump nulprop.dump &&
505 - git diff-tree --always -s --format=%s HEAD >actual.message &&
506 - test_cmp expect.message actual.message
507 -'
508 -
509 -test_expect_success 'NUL in log message, file content, and property name' '
510 - # Caveat: svnadmin 1.6.16 (r1073529) truncates at \0 in the
511 - # svn:specialQnotreally example.
512 - reinit_git &&
513 - cat >expect <<-\EOF &&
514 - OBJID
515 - :100644 100644 OBJID OBJID M greeting
516 - OBJID
517 - :000000 100644 OBJID OBJID A greeting
518 - EOF
519 - printf "\n%s\n" "something with an ASCII NUL (Q)" >expect.message &&
520 - printf "%s\n" "helQo" >expect.hello1 &&
521 - printf "%s\n" "link hello" >expect.hello2 &&
522 - {
523 - properties svn:log "something with an ASCII NUL (Q)" &&
524 - echo PROPS-END
525 - } |
526 - q_to_nul >props &&
527 - {
528 - q_to_nul <<-\EOF &&
529 - SVN-fs-dump-format-version: 3
530 -
531 - Revision-number: 1
532 - Prop-content-length: 10
533 - Content-length: 10
534 -
535 - PROPS-END
536 -
537 - Node-path: greeting
538 - Node-kind: file
539 - Node-action: add
540 - Prop-content-length: 10
541 - Text-content-length: 6
542 - Content-length: 16
543 -
544 - PROPS-END
545 - helQo
546 -
547 - Revision-number: 2
548 - EOF
549 - echo Prop-content-length: $(wc -c <props) &&
550 - echo Content-length: $(wc -c <props) &&
551 - echo &&
552 - cat props &&
553 - q_to_nul <<-\EOF
554 -
555 - Node-path: greeting
556 - Node-kind: file
557 - Node-action: change
558 - Prop-content-length: 43
559 - Text-content-length: 11
560 - Content-length: 54
561 -
562 - K 21
563 - svn:specialQnotreally
564 - V 1
565 - *
566 - PROPS-END
567 - link hello
568 - EOF
569 - } >8bitclean.dump &&
570 - try_dump 8bitclean.dump &&
571 - {
572 - git rev-list HEAD |
573 - git diff-tree --root --stdin |
574 - sed "s/$OID_REGEX/OBJID/g"
575 - } >actual &&
576 - {
577 - git cat-file commit HEAD | nul_to_q &&
578 - echo
579 - } |
580 - sed -ne "/^\$/,\$ p" >actual.message &&
581 - git cat-file blob HEAD^:greeting | nul_to_q >actual.hello1 &&
582 - git cat-file blob HEAD:greeting | nul_to_q >actual.hello2 &&
583 - test_cmp expect actual &&
584 - test_cmp expect.message actual.message &&
585 - test_cmp expect.hello1 actual.hello1 &&
586 - test_cmp expect.hello2 actual.hello2
587 -'
588 -
589 -test_expect_success 'change file mode and reiterate content' '
590 - reinit_git &&
591 - cat >expect <<-\EOF &&
592 - OBJID
593 - :120000 100644 OBJID OBJID T greeting
594 - OBJID
595 - :100644 120000 OBJID OBJID T greeting
596 - OBJID
597 - :000000 100644 OBJID OBJID A greeting
598 - EOF
599 - echo "link hello" >expect.blob &&
600 - echo hello >hello &&
601 - cat >filemode2.dump <<-\EOF &&
602 - SVN-fs-dump-format-version: 3
603 -
604 - Revision-number: 1
605 - Prop-content-length: 10
606 - Content-length: 10
607 -
608 - PROPS-END
609 -
610 - Node-path: greeting
611 - Node-kind: file
612 - Node-action: add
613 - Prop-content-length: 10
614 - Text-content-length: 11
615 - Content-length: 21
616 -
617 - PROPS-END
618 - link hello
619 -
620 - Revision-number: 2
621 - Prop-content-length: 10
622 - Content-length: 10
623 -
624 - PROPS-END
625 -
626 - Node-path: greeting
627 - Node-kind: file
628 - Node-action: change
629 - Prop-content-length: 33
630 - Text-content-length: 11
631 - Content-length: 44
632 -
633 - K 11
634 - svn:special
635 - V 1
636 - *
637 - PROPS-END
638 - link hello
639 -
640 - Revision-number: 3
641 - Prop-content-length: 10
642 - Content-length: 10
643 -
644 - PROPS-END
645 -
646 - Node-path: greeting
647 - Node-kind: file
648 - Node-action: change
649 - Prop-content-length: 10
650 - Text-content-length: 11
651 - Content-length: 21
652 -
653 - PROPS-END
654 - link hello
655 - EOF
656 - try_dump filemode2.dump &&
657 - {
658 - git rev-list HEAD |
659 - git diff-tree --root --stdin |
660 - sed "s/$OID_REGEX/OBJID/g"
661 - } >actual &&
662 - git show HEAD:greeting >actual.blob &&
663 - git show HEAD^:greeting >actual.target &&
664 - test_cmp expect actual &&
665 - test_cmp expect.blob actual.blob &&
666 - test_cmp hello actual.target
667 -'
668 -
669 -test_expect_success 'deltas supported' '
670 - reinit_git &&
671 - {
672 - # (old) h + (inline) ello + (old) \n
673 - printf "SVNQ%b%b%s" "Q\003\006\005\004" "\001Q\0204\001\002" "ello" |
674 - q_to_nul
675 - } >delta &&
676 - {
677 - properties \
678 - svn:author author@example.com \
679 - svn:date "1999-01-05T00:01:002.000000Z" \
680 - svn:log "add greeting" &&
681 - echo PROPS-END
682 - } >props &&
683 - {
684 - properties \
685 - svn:author author@example.com \
686 - svn:date "1999-01-06T00:01:002.000000Z" \
687 - svn:log "change it" &&
688 - echo PROPS-END
689 - } >props2 &&
690 - {
691 - echo SVN-fs-dump-format-version: 3 &&
692 - echo &&
693 - echo Revision-number: 1 &&
694 - echo Prop-content-length: $(wc -c <props) &&
695 - echo Content-length: $(wc -c <props) &&
696 - echo &&
697 - cat props &&
698 - cat <<-\EOF &&
699 -
700 - Node-path: hello
701 - Node-kind: file
702 - Node-action: add
703 - Prop-content-length: 10
704 - Text-content-length: 3
705 - Content-length: 13
706 -
707 - PROPS-END
708 - hi
709 -
710 - EOF
711 - echo Revision-number: 2 &&
712 - echo Prop-content-length: $(wc -c <props2) &&
713 - echo Content-length: $(wc -c <props2) &&
714 - echo &&
715 - cat props2 &&
716 - cat <<-\EOF &&
717 -
718 - Node-path: hello
719 - Node-kind: file
720 - Node-action: change
721 - Text-delta: true
722 - Prop-content-length: 10
723 - EOF
724 - echo Text-content-length: $(wc -c <delta) &&
725 - echo Content-length: $((10 + $(wc -c <delta))) &&
726 - echo &&
727 - echo PROPS-END &&
728 - cat delta
729 - } >delta.dump &&
730 - try_dump delta.dump
731 -'
732 -
733 -test_expect_success 'property deltas supported' '
734 - reinit_git &&
735 - cat >expect <<-\EOF &&
736 - OBJID
737 - :100755 100644 OBJID OBJID M script.sh
738 - EOF
739 - {
740 - properties \
741 - svn:author author@example.com \
742 - svn:date "1999-03-06T00:01:002.000000Z" \
743 - svn:log "make an executable, or chmod -x it" &&
744 - echo PROPS-END
745 - } >revprops &&
746 - {
747 - echo SVN-fs-dump-format-version: 3 &&
748 - echo &&
749 - echo Revision-number: 1 &&
750 - echo Prop-content-length: $(wc -c <revprops) &&
751 - echo Content-length: $(wc -c <revprops) &&
752 - echo &&
753 - cat revprops &&
754 - echo &&
755 - cat <<-\EOF &&
756 - Node-path: script.sh
757 - Node-kind: file
758 - Node-action: add
759 - Text-content-length: 0
760 - Prop-content-length: 39
761 - Content-length: 39
762 -
763 - K 14
764 - svn:executable
765 - V 4
766 - true
767 - PROPS-END
768 -
769 - EOF
770 - echo Revision-number: 2 &&
771 - echo Prop-content-length: $(wc -c <revprops) &&
772 - echo Content-length: $(wc -c <revprops) &&
773 - echo &&
774 - cat revprops &&
775 - echo &&
776 - cat <<-\EOF
777 - Node-path: script.sh
778 - Node-kind: file
779 - Node-action: change
780 - Prop-delta: true
781 - Prop-content-length: 30
782 - Content-length: 30
783 -
784 - D 14
785 - svn:executable
786 - PROPS-END
787 - EOF
788 - } >propdelta.dump &&
789 - try_dump propdelta.dump &&
790 - {
791 - git rev-list HEAD |
792 - git diff-tree --stdin |
793 - sed "s/$OID_REGEX/OBJID/g"
794 - } >actual &&
795 - test_cmp expect actual
796 -'
797 -
798 -test_expect_success 'properties on /' '
799 - reinit_git &&
800 - cat <<-\EOF >expect &&
801 - OBJID
802 - OBJID
803 - :000000 100644 OBJID OBJID A greeting
804 - EOF
805 - sed -e "s/X$//" <<-\EOF >changeroot.dump &&
806 - SVN-fs-dump-format-version: 3
807 -
808 - Revision-number: 1
809 - Prop-content-length: 10
810 - Content-length: 10
811 -
812 - PROPS-END
813 -
814 - Node-path: greeting
815 - Node-kind: file
816 - Node-action: add
817 - Text-content-length: 0
818 - Prop-content-length: 10
819 - Content-length: 10
820 -
821 - PROPS-END
822 -
823 - Revision-number: 2
824 - Prop-content-length: 10
825 - Content-length: 10
826 -
827 - PROPS-END
828 -
829 - Node-path: X
830 - Node-kind: dir
831 - Node-action: change
832 - Prop-delta: true
833 - Prop-content-length: 43
834 - Content-length: 43
835 -
836 - K 10
837 - svn:ignore
838 - V 11
839 - build-area
840 -
841 - PROPS-END
842 - EOF
843 - try_dump changeroot.dump &&
844 - {
845 - git rev-list HEAD |
846 - git diff-tree --root --always --stdin |
847 - sed "s/$OID_REGEX/OBJID/g"
848 - } >actual &&
849 - test_cmp expect actual
850 -'
851 -
852 -test_expect_success 'deltas for typechange' '
853 - reinit_git &&
854 - cat >expect <<-\EOF &&
855 - OBJID
856 - :120000 100644 OBJID OBJID T test-file
857 - OBJID
858 - :100755 120000 OBJID OBJID T test-file
859 - OBJID
860 - :000000 100755 OBJID OBJID A test-file
861 - EOF
862 - cat >deleteprop.dump <<-\EOF &&
863 - SVN-fs-dump-format-version: 3
864 -
865 - Revision-number: 1
866 - Prop-content-length: 10
867 - Content-length: 10
868 -
869 - PROPS-END
870 -
871 - Node-path: test-file
872 - Node-kind: file
873 - Node-action: add
874 - Prop-delta: true
875 - Prop-content-length: 35
876 - Text-content-length: 17
877 - Content-length: 52
878 -
879 - K 14
880 - svn:executable
881 - V 0
882 -
883 - PROPS-END
884 - link testing 123
885 -
886 - Revision-number: 2
887 - Prop-content-length: 10
888 - Content-length: 10
889 -
890 - PROPS-END
891 -
892 - Node-path: test-file
893 - Node-kind: file
894 - Node-action: change
895 - Prop-delta: true
896 - Prop-content-length: 53
897 - Text-content-length: 17
898 - Content-length: 70
899 -
900 - K 11
901 - svn:special
902 - V 1
903 - *
904 - D 14
905 - svn:executable
906 - PROPS-END
907 - link testing 231
908 -
909 - Revision-number: 3
910 - Prop-content-length: 10
911 - Content-length: 10
912 -
913 - PROPS-END
914 -
915 - Node-path: test-file
916 - Node-kind: file
917 - Node-action: change
918 - Prop-delta: true
919 - Prop-content-length: 27
920 - Text-content-length: 17
921 - Content-length: 44
922 -
923 - D 11
924 - svn:special
925 - PROPS-END
926 - link testing 321
927 - EOF
928 - try_dump deleteprop.dump &&
929 - {
930 - git rev-list HEAD |
931 - git diff-tree --root --stdin |
932 - sed "s/$OID_REGEX/OBJID/g"
933 - } >actual &&
934 - test_cmp expect actual
935 -'
936 -
937 -test_expect_success 'deltas need not consume the whole preimage' '
938 - reinit_git &&
939 - cat >expect <<-\EOF &&
940 - OBJID
941 - :120000 100644 OBJID OBJID T postimage
942 - OBJID
943 - :100644 120000 OBJID OBJID T postimage
944 - OBJID
945 - :000000 100644 OBJID OBJID A postimage
946 - EOF
947 - echo "first preimage" >expect.1 &&
948 - printf target >expect.2 &&
949 - printf lnk >expect.3 &&
950 - {
951 - printf "SVNQ%b%b%b" "QQ\017\001\017" "\0217" "first preimage\n" |
952 - q_to_nul
953 - } >delta.1 &&
954 - {
955 - properties svn:special "*" &&
956 - echo PROPS-END
957 - } >symlink.props &&
958 - {
959 - printf "SVNQ%b%b%b" "Q\002\013\004\012" "\0201\001\001\0211" "lnk target" |
960 - q_to_nul
961 - } >delta.2 &&
962 - {
963 - printf "SVNQ%b%b" "Q\004\003\004Q" "\001Q\002\002" |
964 - q_to_nul
965 - } >delta.3 &&
966 - {
967 - cat <<-\EOF &&
968 - SVN-fs-dump-format-version: 3
969 -
970 - Revision-number: 1
971 - Prop-content-length: 10
972 - Content-length: 10
973 -
974 - PROPS-END
975 -
976 - Node-path: postimage
977 - Node-kind: file
978 - Node-action: add
979 - Text-delta: true
980 - Prop-content-length: 10
981 - EOF
982 - echo Text-content-length: $(wc -c <delta.1) &&
983 - echo Content-length: $((10 + $(wc -c <delta.1))) &&
984 - echo &&
985 - echo PROPS-END &&
986 - cat delta.1 &&
987 - cat <<-\EOF &&
988 -
989 - Revision-number: 2
990 - Prop-content-length: 10
991 - Content-length: 10
992 -
993 - PROPS-END
994 -
995 - Node-path: postimage
996 - Node-kind: file
997 - Node-action: change
998 - Text-delta: true
999 - EOF
1000 - echo Prop-content-length: $(wc -c <symlink.props) &&
1001 - echo Text-content-length: $(wc -c <delta.2) &&
1002 - echo Content-length: $(($(wc -c <symlink.props) + $(wc -c <delta.2))) &&
1003 - echo &&
1004 - cat symlink.props &&
1005 - cat delta.2 &&
1006 - cat <<-\EOF &&
1007 -
1008 - Revision-number: 3
1009 - Prop-content-length: 10
1010 - Content-length: 10
1011 -
1012 - PROPS-END
1013 -
1014 - Node-path: postimage
1015 - Node-kind: file
1016 - Node-action: change
1017 - Text-delta: true
1018 - Prop-content-length: 10
1019 - EOF
1020 - echo Text-content-length: $(wc -c <delta.3) &&
1021 - echo Content-length: $((10 + $(wc -c <delta.3))) &&
1022 - echo &&
1023 - echo PROPS-END &&
1024 - cat delta.3 &&
1025 - echo
1026 - } >deltapartial.dump &&
1027 - try_dump deltapartial.dump &&
1028 - {
1029 - git rev-list HEAD |
1030 - git diff-tree --root --stdin |
1031 - sed "s/$OID_REGEX/OBJID/g"
1032 - } >actual &&
1033 - test_cmp expect actual &&
1034 - git show HEAD:postimage >actual.3 &&
1035 - git show HEAD^:postimage >actual.2 &&
1036 - git show HEAD^^:postimage >actual.1 &&
1037 - test_cmp expect.1 actual.1 &&
1038 - test_cmp expect.2 actual.2 &&
1039 - test_cmp expect.3 actual.3
1040 -'
1041 -
1042 -test_expect_success 'no hang for delta trying to read past end of preimage' '
1043 - reinit_git &&
1044 - {
1045 - # COPY 1
1046 - printf "SVNQ%b%b" "Q\001\001\002Q" "\001Q" |
1047 - q_to_nul
1048 - } >greedy.delta &&
1049 - {
1050 - cat <<-\EOF &&
1051 - SVN-fs-dump-format-version: 3
1052 -
1053 - Revision-number: 1
1054 - Prop-content-length: 10
1055 - Content-length: 10
1056 -
1057 - PROPS-END
1058 -
1059 - Node-path: bootstrap
1060 - Node-kind: file
1061 - Node-action: add
1062 - Text-delta: true
1063 - Prop-content-length: 10
1064 - EOF
1065 - echo Text-content-length: $(wc -c <greedy.delta) &&
1066 - echo Content-length: $((10 + $(wc -c <greedy.delta))) &&
1067 - echo &&
1068 - echo PROPS-END &&
1069 - cat greedy.delta &&
1070 - echo
1071 - } >greedydelta.dump &&
1072 - try_dump greedydelta.dump must_fail might_fail
1073 -'
1074 -
1075 -test_expect_success 'set up svn repo' '
1076 - svnconf=$PWD/svnconf &&
1077 - mkdir -p "$svnconf" &&
1078 -
1079 - if
1080 - svnadmin -h >/dev/null 2>&1 &&
1081 - svnadmin create simple-svn &&
1082 - svnadmin load simple-svn <"$TEST_DIRECTORY/t9135/svn.dump" &&
1083 - svn export --config-dir "$svnconf" "file://$PWD/simple-svn" simple-svnco
1084 - then
1085 - test_set_prereq SVNREPO
1086 - fi
1087 -'
1088 -
1089 -test_expect_success SVNREPO 't9135/svn.dump' '
1090 - mkdir -p simple-git &&
1091 - (
1092 - cd simple-git &&
1093 - reinit_git &&
1094 - try_dump "$TEST_DIRECTORY/t9135/svn.dump"
1095 - ) &&
1096 - (
1097 - cd simple-svnco &&
1098 - git init &&
1099 - git add . &&
1100 - git fetch ../simple-git master &&
1101 - git diff --exit-code FETCH_HEAD
1102 - )
1103 -'
1104 -
1105 -test_done
t/t9011-svn-da.sh deleted
-248
@@ -1,248 +0,0 @@
1 -#!/bin/sh
2 -
3 -test_description='test parsing of svndiff0 files
4 -
5 -Using the "test-svn-fe -d" helper, check that svn-fe correctly
6 -interprets deltas using various facilities (some from the spec,
7 -some only learned from practice).
8 -'
9 -. ./test-lib.sh
10 -
11 ->empty
12 -printf foo >preimage
13 -
14 -test_expect_success 'reject empty delta' '
15 - test_must_fail test-svn-fe -d preimage empty 0
16 -'
17 -
18 -test_expect_success 'delta can empty file' '
19 - printf "SVNQ" | q_to_nul >clear.delta &&
20 - test-svn-fe -d preimage clear.delta 4 >actual &&
21 - test_must_be_empty actual
22 -'
23 -
24 -test_expect_success 'reject svndiff2' '
25 - printf "SVN\002" >bad.filetype &&
26 - test_must_fail test-svn-fe -d preimage bad.filetype 4
27 -'
28 -
29 -test_expect_success 'one-window empty delta' '
30 - printf "SVNQ%s" "QQQQQ" | q_to_nul >clear.onewindow &&
31 - test-svn-fe -d preimage clear.onewindow 9 >actual &&
32 - test_must_be_empty actual
33 -'
34 -
35 -test_expect_success 'reject incomplete window header' '
36 - printf "SVNQ%s" "QQQQQ" | q_to_nul >clear.onewindow &&
37 - printf "SVNQ%s" "QQ" | q_to_nul >clear.partialwindow &&
38 - test_must_fail test-svn-fe -d preimage clear.onewindow 6 &&
39 - test_must_fail test-svn-fe -d preimage clear.partialwindow 6
40 -'
41 -
42 -test_expect_success 'reject declared delta longer than actual delta' '
43 - printf "SVNQ%s" "QQQQQ" | q_to_nul >clear.onewindow &&
44 - printf "SVNQ%s" "QQ" | q_to_nul >clear.partialwindow &&
45 - test_must_fail test-svn-fe -d preimage clear.onewindow 14 &&
46 - test_must_fail test-svn-fe -d preimage clear.partialwindow 9
47 -'
48 -
49 -test_expect_success 'two-window empty delta' '
50 - printf "SVNQ%s%s" "QQQQQ" "QQQQQ" | q_to_nul >clear.twowindow &&
51 - test-svn-fe -d preimage clear.twowindow 14 >actual &&
52 - test_must_fail test-svn-fe -d preimage clear.twowindow 13 &&
53 - test_must_be_empty actual
54 -'
55 -
56 -test_expect_success 'noisy zeroes' '
57 - printf "SVNQ%s" \
58 - "RRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRRQQQQQ" |
59 - tr R "\200" |
60 - q_to_nul >clear.noisy &&
61 - len=$(wc -c <clear.noisy) &&
62 - test-svn-fe -d preimage clear.noisy $len &&
63 - test_must_be_empty actual
64 -'
65 -
66 -test_expect_success 'reject variable-length int in magic' '
67 - printf "SVNRQ" | tr R "\200" | q_to_nul >clear.badmagic &&
68 - test_must_fail test-svn-fe -d preimage clear.badmagic 5
69 -'
70 -
71 -test_expect_success 'reject truncated integer' '
72 - printf "SVNQ%s%s" "QQQQQ" "QQQQRRQ" |
73 - tr R "\200" |
74 - q_to_nul >clear.fullint &&
75 - printf "SVNQ%s%s" "QQQQQ" "QQQQRR" |
76 - tr RT "\201" |
77 - q_to_nul >clear.partialint &&
78 - test_must_fail test-svn-fe -d preimage clear.fullint 15 &&
79 - test-svn-fe -d preimage clear.fullint 16 &&
80 - test_must_fail test-svn-fe -d preimage clear.partialint 15
81 -'
82 -
83 -test_expect_success 'nonempty (but unused) preimage view' '
84 - printf "SVNQ%b" "Q\003QQQ" | q_to_nul >clear.readpreimage &&
85 - test-svn-fe -d preimage clear.readpreimage 9 >actual &&
86 - test_must_be_empty actual
87 -'
88 -
89 -test_expect_success 'preimage view: right endpoint cannot backtrack' '
90 - printf "SVNQ%b%b" "Q\003QQQ" "Q\002QQQ" |
91 - q_to_nul >clear.backtrack &&
92 - test_must_fail test-svn-fe -d preimage clear.backtrack 14
93 -'
94 -
95 -test_expect_success 'preimage view: left endpoint can advance' '
96 - printf "SVNQ%b%b" "Q\003QQQ" "\001\002QQQ" |
97 - q_to_nul >clear.preshrink &&
98 - printf "SVNQ%b%b" "Q\003QQQ" "\001\001QQQ" |
99 - q_to_nul >clear.shrinkbacktrack &&
100 - test-svn-fe -d preimage clear.preshrink 14 >actual &&
101 - test_must_fail test-svn-fe -d preimage clear.shrinkbacktrack 14 &&
102 - test_must_be_empty actual
103 -'
104 -
105 -test_expect_success 'preimage view: offsets compared by value' '
106 - printf "SVNQ%b%b" "\001\001QQQ" "\0200Q\003QQQ" |
107 - q_to_nul >clear.noisybacktrack &&
108 - printf "SVNQ%b%b" "\001\001QQQ" "\0200\001\002QQQ" |
109 - q_to_nul >clear.noisyadvance &&
110 - test_must_fail test-svn-fe -d preimage clear.noisybacktrack 15 &&
111 - test-svn-fe -d preimage clear.noisyadvance 15 &&
112 - test_must_be_empty actual
113 -'
114 -
115 -test_expect_success 'preimage view: reject truncated preimage' '
116 - printf "SVNQ%b" "\010QQQQ" | q_to_nul >clear.lateemptyread &&
117 - printf "SVNQ%b" "\010\001QQQ" | q_to_nul >clear.latenonemptyread &&
118 - printf "SVNQ%b" "\001\010QQQ" | q_to_nul >clear.longread &&
119 - test_must_fail test-svn-fe -d preimage clear.lateemptyread 9 &&
120 - test_must_fail test-svn-fe -d preimage clear.latenonemptyread 9 &&
121 - test_must_fail test-svn-fe -d preimage clear.longread 9
122 -'
123 -
124 -test_expect_success 'forbid unconsumed inline data' '
125 - printf "SVNQ%b%s%b%s" "QQQQ\003" "bar" "QQQQ\001" "x" |
126 - q_to_nul >inline.clear &&
127 - test_must_fail test-svn-fe -d preimage inline.clear 18 >actual
128 -'
129 -
130 -test_expect_success 'reject truncated inline data' '
131 - printf "SVNQ%b%s" "QQQQ\003" "b" | q_to_nul >inline.trunc &&
132 - test_must_fail test-svn-fe -d preimage inline.trunc 10
133 -'
134 -
135 -test_expect_success 'reject truncated inline data (after instruction section)' '
136 - printf "SVNQ%b%b%s" "QQ\001\001\003" "\0201" "b" | q_to_nul >insn.trunc &&
137 - test_must_fail test-svn-fe -d preimage insn.trunc 11
138 -'
139 -
140 -test_expect_success 'copyfrom_data' '
141 - echo hi >expect &&
142 - printf "SVNQ%b%b%b" "QQ\003\001\003" "\0203" "hi\n" | q_to_nul >copydat &&
143 - test-svn-fe -d preimage copydat 13 >actual &&
144 - test_cmp expect actual
145 -'
146 -
147 -test_expect_success 'multiple copyfrom_data' '
148 - echo hi >expect &&
149 - printf "SVNQ%b%b%b%b%b" "QQ\003\002\003" "\0201\0202" "hi\n" \
150 - "QQQ\002Q" "\0200Q" | q_to_nul >copy.multi &&
151 - len=$(wc -c <copy.multi) &&
152 - test-svn-fe -d preimage copy.multi $len >actual &&
153 - test_cmp expect actual
154 -'
155 -
156 -test_expect_success 'incomplete multiple insn' '
157 - printf "SVNQ%b%b%b" "QQ\003\002\003" "\0203\0200" "hi\n" |
158 - q_to_nul >copy.partial &&
159 - len=$(wc -c <copy.partial) &&
160 - test_must_fail test-svn-fe -d preimage copy.partial $len
161 -'
162 -
163 -test_expect_success 'catch attempt to copy missing data' '
164 - printf "SVNQ%b%b%s%b%s" "QQ\002\002\001" "\0201\0201" "X" \
165 - "QQQQ\002" "YZ" |
166 - q_to_nul >copy.incomplete &&
167 - len=$(wc -c <copy.incomplete) &&
168 - test_must_fail test-svn-fe -d preimage copy.incomplete $len
169 -'
170 -
171 -test_expect_success 'copyfrom target to repeat data' '
172 - printf foofoo >expect &&
173 - printf "SVNQ%b%b%s" "QQ\006\004\003" "\0203\0100\003Q" "foo" |
174 - q_to_nul >copytarget.repeat &&
175 - len=$(wc -c <copytarget.repeat) &&
176 - test-svn-fe -d preimage copytarget.repeat $len >actual &&
177 - test_cmp expect actual
178 -'
179 -
180 -test_expect_success 'copyfrom target out of order' '
181 - printf foooof >expect &&
182 - printf "SVNQ%b%b%s" \
183 - "QQ\006\007\003" "\0203\0101\002\0101\001\0101Q" "foo" |
184 - q_to_nul >copytarget.reverse &&
185 - len=$(wc -c <copytarget.reverse) &&
186 - test-svn-fe -d preimage copytarget.reverse $len >actual &&
187 - test_cmp expect actual
188 -'
189 -
190 -test_expect_success 'catch copyfrom future' '
191 - printf "SVNQ%b%b%s" "QQ\004\004\003" "\0202\0101\002\0201" "XYZ" |
192 - q_to_nul >copytarget.infuture &&
193 - len=$(wc -c <copytarget.infuture) &&
194 - test_must_fail test-svn-fe -d preimage copytarget.infuture $len
195 -'
196 -
197 -test_expect_success 'copy to sustain' '
198 - printf XYXYXYXYXYXZ >expect &&
199 - printf "SVNQ%b%b%s" "QQ\014\004\003" "\0202\0111Q\0201" "XYZ" |
200 - q_to_nul >copytarget.sustain &&
201 - len=$(wc -c <copytarget.sustain) &&
202 - test-svn-fe -d preimage copytarget.sustain $len >actual &&
203 - test_cmp expect actual
204 -'
205 -
206 -test_expect_success 'catch copy that overflows' '
207 - printf "SVNQ%b%b%s" "QQ\003\003\001" "\0201\0177Q" X |
208 - q_to_nul >copytarget.overflow &&
209 - len=$(wc -c <copytarget.overflow) &&
210 - test_must_fail test-svn-fe -d preimage copytarget.overflow $len
211 -'
212 -
213 -test_expect_success 'copyfrom source' '
214 - printf foo >expect &&
215 - printf "SVNQ%b%b" "Q\003\003\002Q" "\003Q" | q_to_nul >copysource.all &&
216 - test-svn-fe -d preimage copysource.all 11 >actual &&
217 - test_cmp expect actual
218 -'
219 -
220 -test_expect_success 'copy backwards' '
221 - printf oof >expect &&
222 - printf "SVNQ%b%b" "Q\003\003\006Q" "\001\002\001\001\001Q" |
223 - q_to_nul >copysource.rev &&
224 - test-svn-fe -d preimage copysource.rev 15 >actual &&
225 - test_cmp expect actual
226 -'
227 -
228 -test_expect_success 'offsets are relative to window' '
229 - printf fo >expect &&
230 - printf "SVNQ%b%b%b%b" "Q\003\001\002Q" "\001Q" \
231 - "\002\001\001\002Q" "\001Q" |
232 - q_to_nul >copysource.two &&
233 - test-svn-fe -d preimage copysource.two 18 >actual &&
234 - test_cmp expect actual
235 -'
236 -
237 -test_expect_success 'example from notes/svndiff' '
238 - printf aaaaccccdddddddd >expect &&
239 - printf aaaabbbbcccc >source &&
240 - printf "SVNQ%b%b%s" "Q\014\020\007\001" \
241 - "\004Q\004\010\0201\0107\010" d |
242 - q_to_nul >delta.example &&
243 - len=$(wc -c <delta.example) &&
244 - test-svn-fe -d source delta.example $len >actual &&
245 - test_cmp expect actual
246 -'
247 -
248 -test_done
t/t9020-remote-svn.sh deleted
-95
@@ -1,95 +0,0 @@
1 -#!/bin/sh
2 -
3 -test_description='tests remote-svn'
4 -
5 -. ./test-lib.sh
6 -
7 -MARKSPATH=.git/info/fast-import/remote-svn
8 -
9 -if ! test_have_prereq PYTHON
10 -then
11 - skip_all='skipping remote-svn tests, python not available'
12 - test_done
13 -fi
14 -
15 -# Override svnrdump with our simulator
16 -PATH="$HOME:$PATH"
17 -export PATH PYTHON_PATH GIT_BUILD_DIR
18 -
19 -write_script "$HOME/svnrdump" <<\EOF
20 -exec "$PYTHON_PATH" "$GIT_BUILD_DIR/contrib/svn-fe/svnrdump_sim.py" "$@"
21 -EOF
22 -
23 -init_git () {
24 - rm -fr .git &&
25 - git init &&
26 - #git remote add svnsim testsvn::sim:///$TEST_DIRECTORY/t9020/example.svnrdump
27 - # let's reuse an existing dump file!?
28 - git remote add svnsim "testsvn::sim://$TEST_DIRECTORY/t9154/svn.dump"
29 - git remote add svnfile "testsvn::file://$TEST_DIRECTORY/t9154/svn.dump"
30 -}
31 -
32 -if test -e "$GIT_BUILD_DIR/git-remote-testsvn"
33 -then
34 - test_set_prereq REMOTE_SVN
35 -fi
36 -
37 -test_debug '
38 - git --version
39 - type git
40 - type svnrdump
41 -'
42 -
43 -test_expect_success REMOTE_SVN 'simple fetch' '
44 - init_git &&
45 - git fetch svnsim &&
46 - test_cmp .git/refs/svn/svnsim/master .git/refs/remotes/svnsim/master &&
47 - cp .git/refs/remotes/svnsim/master master.good
48 -'
49 -
50 -test_debug '
51 - git show-ref -s refs/svn/svnsim/master
52 - git show-ref -s refs/remotes/svnsim/master
53 -'
54 -
55 -test_expect_success REMOTE_SVN 'repeated fetch, nothing shall change' '
56 - git fetch svnsim &&
57 - test_cmp master.good .git/refs/remotes/svnsim/master
58 -'
59 -
60 -test_expect_success REMOTE_SVN 'fetch from a file:// url gives the same result' '
61 - git fetch svnfile
62 -'
63 -
64 -test_expect_failure REMOTE_SVN 'the sha1 differ because the git-svn-id line in the commit msg contains the url' '
65 - test_cmp .git/refs/remotes/svnfile/master .git/refs/remotes/svnsim/master
66 -'
67 -
68 -test_expect_success REMOTE_SVN 'mark-file regeneration' '
69 - # filter out any other marks, that can not be regenerated. Only up to 3 digit revisions are allowed here
70 - grep ":[0-9]\{1,3\} " $MARKSPATH/svnsim.marks > $MARKSPATH/svnsim.marks.old &&
71 - rm $MARKSPATH/svnsim.marks &&
72 - git fetch svnsim &&
73 - test_cmp $MARKSPATH/svnsim.marks.old $MARKSPATH/svnsim.marks
74 -'
75 -
76 -test_expect_success REMOTE_SVN 'incremental imports must lead to the same head' '
77 - SVNRMAX=3 &&
78 - export SVNRMAX &&
79 - init_git &&
80 - git fetch svnsim &&
81 - test_cmp .git/refs/svn/svnsim/master .git/refs/remotes/svnsim/master &&
82 - unset SVNRMAX &&
83 - git fetch svnsim &&
84 - test_cmp master.good .git/refs/remotes/svnsim/master
85 -'
86 -
87 -test_expect_success REMOTE_SVN 'respects configured default initial branch' '
88 - git -c init.defaultBranch=trunk remote add -f trunk \
89 - "testsvn::file://$TEST_DIRECTORY/t9154/svn.dump" &&
90 - git rev-parse --verify refs/remotes/trunk/trunk
91 -'
92 -
93 -test_debug 'git branch -a'
94 -
95 -test_done
t/test-lib-functions.sh
+1 -1
@@ -820,7 +820,7 @@ test_must_fail_acceptable () {
820 fi
821
822 case "$1" in
823 - git|__git*|test-tool|test-svn-fe|test_terminal)
823 + git|__git*|test-tool|test_terminal)
824 return 0
825 ;;
826 *)
vcs-svn/LICENSE deleted
-32
@@ -1,32 +0,0 @@
1 -Copyright (C) 2010 David Barr <david.barr@cordelta.com>.
2 -All rights reserved.
3 -
4 -Copyright (C) 2010 Jonathan Nieder <jrnieder@gmail.com>.
5 -
6 -Copyright (C) 2005 Stefan Hegny, hydrografix Consulting GmbH,
7 -Frankfurt/Main, Germany
8 -and others, see http://svn2cc.sarovar.org
9 -
10 -Redistribution and use in source and binary forms, with or without
11 -modification, are permitted provided that the following conditions
12 -are met:
13 -1. Redistributions of source code must retain the above copyright
14 - notice(s), this list of conditions and the following disclaimer
15 - unmodified other than the allowable addition of one or more
16 - copyright notices.
17 -2. Redistributions in binary form must reproduce the above copyright
18 - notice(s), this list of conditions and the following disclaimer in
19 - the documentation and/or other materials provided with the
20 - distribution.
21 -
22 -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) ``AS IS'' AND ANY
23 -EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25 -PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) BE
26 -LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
27 -CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
28 -SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
29 -BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
30 -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
31 -OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
32 -EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
vcs-svn/fast_export.c deleted
-365
@@ -1,365 +0,0 @@
1 -/*
2 - * Licensed under a two-clause BSD-style license.
3 - * See LICENSE for details.
4 - */
5 -
6 -#include "cache.h"
7 -#include "quote.h"
8 -#include "fast_export.h"
9 -#include "strbuf.h"
10 -#include "svndiff.h"
11 -#include "sliding_window.h"
12 -#include "line_buffer.h"
13 -
14 -#define MAX_GITSVN_LINE_LEN 4096
15 -
16 -static uint32_t first_commit_done;
17 -static struct line_buffer postimage = LINE_BUFFER_INIT;
18 -static struct line_buffer report_buffer = LINE_BUFFER_INIT;
19 -
20 -/* NEEDSWORK: move to fast_export_init() */
21 -static int init_postimage(void)
22 -{
23 - static int postimage_initialized;
24 - if (postimage_initialized)
25 - return 0;
26 - postimage_initialized = 1;
27 - return buffer_tmpfile_init(&postimage);
28 -}
29 -
30 -void fast_export_init(int fd)
31 -{
32 - first_commit_done = 0;
33 - if (buffer_fdinit(&report_buffer, fd))
34 - die_errno("cannot read from file descriptor %d", fd);
35 -}
36 -
37 -void fast_export_deinit(void)
38 -{
39 - if (buffer_deinit(&report_buffer))
40 - die_errno("error closing fast-import feedback stream");
41 -}
42 -
43 -void fast_export_delete(const char *path)
44 -{
45 - putchar('D');
46 - putchar(' ');
47 - quote_c_style(path, NULL, stdout, 0);
48 - putchar('\n');
49 -}
50 -
51 -static void fast_export_truncate(const char *path, uint32_t mode)
52 -{
53 - fast_export_modify(path, mode, "inline");
54 - printf("data 0\n\n");
55 -}
56 -
57 -void fast_export_modify(const char *path, uint32_t mode, const char *dataref)
58 -{
59 - /* Mode must be 100644, 100755, 120000, or 160000. */
60 - if (!dataref) {
61 - fast_export_truncate(path, mode);
62 - return;
63 - }
64 - printf("M %06"PRIo32" %s ", mode, dataref);
65 - quote_c_style(path, NULL, stdout, 0);
66 - putchar('\n');
67 -}
68 -
69 -void fast_export_begin_note(uint32_t revision, const char *author,
70 - const char *log, timestamp_t timestamp, const char *note_ref)
71 -{
72 - static int firstnote = 1;
73 - size_t loglen = strlen(log);
74 - printf("commit %s\n", note_ref);
75 - printf("committer %s <%s@%s> %"PRItime" +0000\n", author, author, "local", timestamp);
76 - printf("data %"PRIuMAX"\n", (uintmax_t)loglen);
77 - fwrite(log, loglen, 1, stdout);
78 - if (firstnote) {
79 - if (revision > 1)
80 - printf("from %s^0", note_ref);
81 - firstnote = 0;
82 - }
83 - fputc('\n', stdout);
84 -}
85 -
86 -void fast_export_note(const char *committish, const char *dataref)
87 -{
88 - printf("N %s %s\n", dataref, committish);
89 -}
90 -
91 -static char gitsvnline[MAX_GITSVN_LINE_LEN];
92 -void fast_export_begin_commit(uint32_t revision, const char *author,
93 - const struct strbuf *log,
94 - const char *uuid, const char *url,
95 - timestamp_t timestamp, const char *local_ref)
96 -{
97 - static const struct strbuf empty = STRBUF_INIT;
98 - if (!log)
99 - log = &empty;
100 - if (*uuid && *url) {
101 - snprintf(gitsvnline, MAX_GITSVN_LINE_LEN,
102 - "\n\ngit-svn-id: %s@%"PRIu32" %s\n",
103 - url, revision, uuid);
104 - } else {
105 - *gitsvnline = '\0';
106 - }
107 - printf("commit %s\n", local_ref);
108 - printf("mark :%"PRIu32"\n", revision);
109 - printf("committer %s <%s@%s> %"PRItime" +0000\n",
110 - *author ? author : "nobody",
111 - *author ? author : "nobody",
112 - *uuid ? uuid : "local", timestamp);
113 - printf("data %"PRIuMAX"\n",
114 - (uintmax_t) (log->len + strlen(gitsvnline)));
115 - fwrite(log->buf, log->len, 1, stdout);
116 - printf("%s\n", gitsvnline);
117 - if (!first_commit_done) {
118 - if (revision > 1)
119 - printf("from :%"PRIu32"\n", revision - 1);
120 - first_commit_done = 1;
121 - }
122 -}
123 -
124 -void fast_export_end_commit(uint32_t revision)
125 -{
126 - printf("progress Imported commit %"PRIu32".\n\n", revision);
127 -}
128 -
129 -static void ls_from_rev(uint32_t rev, const char *path)
130 -{
131 - /* ls :5 path/to/old/file */
132 - printf("ls :%"PRIu32" ", rev);
133 - quote_c_style(path, NULL, stdout, 0);
134 - putchar('\n');
135 - fflush(stdout);
136 -}
137 -
138 -static void ls_from_active_commit(const char *path)
139 -{
140 - /* ls "path/to/file" */
141 - printf("ls \"");
142 - quote_c_style(path, NULL, stdout, 1);
143 - printf("\"\n");
144 - fflush(stdout);
145 -}
146 -
147 -static const char *get_response_line(void)
148 -{
149 - const char *line = buffer_read_line(&report_buffer);
150 - if (line)
151 - return line;
152 - if (buffer_ferror(&report_buffer))
153 - die_errno("error reading from fast-import");
154 - die("unexpected end of fast-import feedback");
155 -}
156 -
157 -static void die_short_read(struct line_buffer *input)
158 -{
159 - if (buffer_ferror(input))
160 - die_errno("error reading dump file");
161 - die("invalid dump: unexpected end of file");
162 -}
163 -
164 -static int parse_cat_response_line(const char *header, off_t *len)
165 -{
166 - uintmax_t n;
167 - const char *type;
168 - const char *end;
169 -
170 - if (ends_with(header, " missing"))
171 - return error("cat-blob reports missing blob: %s", header);
172 - type = strstr(header, " blob ");
173 - if (!type)
174 - return error("cat-blob header has wrong object type: %s", header);
175 - n = strtoumax(type + strlen(" blob "), (char **) &end, 10);
176 - if (end == type + strlen(" blob "))
177 - return error("cat-blob header does not contain length: %s", header);
178 - if (memchr(type + strlen(" blob "), '-', end - type - strlen(" blob ")))
179 - return error("cat-blob header contains negative length: %s", header);
180 - if (n == UINTMAX_MAX || n > maximum_signed_value_of_type(off_t))
181 - return error("blob too large for current definition of off_t");
182 - *len = n;
183 - if (*end)
184 - return error("cat-blob header contains garbage after length: %s", header);
185 - return 0;
186 -}
187 -
188 -static void check_preimage_overflow(off_t a, off_t b)
189 -{
190 - if (signed_add_overflows(a, b))
191 - die("blob too large for current definition of off_t");
192 -}
193 -
194 -static long apply_delta(off_t len, struct line_buffer *input,
195 - const char *old_data, uint32_t old_mode)
196 -{
197 - long ret;
198 - struct sliding_view preimage = SLIDING_VIEW_INIT(&report_buffer, 0);
199 - FILE *out;
200 -
201 - if (init_postimage() || !(out = buffer_tmpfile_rewind(&postimage)))
202 - die("cannot open temporary file for blob retrieval");
203 - if (old_data) {
204 - const char *response;
205 - printf("cat-blob %s\n", old_data);
206 - fflush(stdout);
207 - response = get_response_line();
208 - if (parse_cat_response_line(response, &preimage.max_off))
209 - die("invalid cat-blob response: %s", response);
210 - check_preimage_overflow(preimage.max_off, 1);
211 - }
212 - if (old_mode == S_IFLNK) {
213 - strbuf_addstr(&preimage.buf, "link ");
214 - check_preimage_overflow(preimage.max_off, strlen("link "));
215 - preimage.max_off += strlen("link ");
216 - check_preimage_overflow(preimage.max_off, 1);
217 - }
218 - if (svndiff0_apply(input, len, &preimage, out))
219 - die("cannot apply delta");
220 - if (old_data) {
221 - /* Read the remainder of preimage and trailing newline. */
222 - assert(!signed_add_overflows(preimage.max_off, 1));
223 - preimage.max_off++; /* room for newline */
224 - if (move_window(&preimage, preimage.max_off - 1, 1))
225 - die("cannot seek to end of input");
226 - if (preimage.buf.buf[0] != '\n')
227 - die("missing newline after cat-blob response");
228 - }
229 - ret = buffer_tmpfile_prepare_to_read(&postimage);
230 - if (ret < 0)
231 - die("cannot read temporary file for blob retrieval");
232 - strbuf_release(&preimage.buf);
233 - return ret;
234 -}
235 -
236 -void fast_export_buf_to_data(const struct strbuf *data)
237 -{
238 - printf("data %"PRIuMAX"\n", (uintmax_t)data->len);
239 - fwrite(data->buf, data->len, 1, stdout);
240 - fputc('\n', stdout);
241 -}
242 -
243 -void fast_export_data(uint32_t mode, off_t len, struct line_buffer *input)
244 -{
245 - assert(len >= 0);
246 - if (mode == S_IFLNK) {
247 - /* svn symlink blobs start with "link " */
248 - if (len < 5)
249 - die("invalid dump: symlink too short for \"link\" prefix");
250 - len -= 5;
251 - if (buffer_skip_bytes(input, 5) != 5)
252 - die_short_read(input);
253 - }
254 - printf("data %"PRIuMAX"\n", (uintmax_t) len);
255 - if (buffer_copy_bytes(input, len) != len)
256 - die_short_read(input);
257 - fputc('\n', stdout);
258 -}
259 -
260 -static int parse_ls_response(const char *response, uint32_t *mode,
261 - struct strbuf *dataref)
262 -{
263 - const char *tab;
264 - const char *response_end;
265 -
266 - assert(response);
267 - response_end = response + strlen(response);
268 -
269 - if (*response == 'm') { /* Missing. */
270 - errno = ENOENT;
271 - return -1;
272 - }
273 -
274 - /* Mode. */
275 - if (response_end - response < (signed) strlen("100644") ||
276 - response[strlen("100644")] != ' ')
277 - die("invalid ls response: missing mode: %s", response);
278 - *mode = 0;
279 - for (; *response != ' '; response++) {
280 - char ch = *response;
281 - if (ch < '0' || ch > '7')
282 - die("invalid ls response: mode is not octal: %s", response);
283 - *mode *= 8;
284 - *mode += ch - '0';
285 - }
286 -
287 - /* ' blob ' or ' tree ' */
288 - if (response_end - response < (signed) strlen(" blob ") ||
289 - (response[1] != 'b' && response[1] != 't'))
290 - die("unexpected ls response: not a tree or blob: %s", response);
291 - response += strlen(" blob ");
292 -
293 - /* Dataref. */
294 - tab = memchr(response, '\t', response_end - response);
295 - if (!tab)
296 - die("invalid ls response: missing tab: %s", response);
297 - strbuf_add(dataref, response, tab - response);
298 - return 0;
299 -}
300 -
301 -int fast_export_ls_rev(uint32_t rev, const char *path,
302 - uint32_t *mode, struct strbuf *dataref)
303 -{
304 - ls_from_rev(rev, path);
305 - return parse_ls_response(get_response_line(), mode, dataref);
306 -}
307 -
308 -int fast_export_ls(const char *path, uint32_t *mode, struct strbuf *dataref)
309 -{
310 - ls_from_active_commit(path);
311 - return parse_ls_response(get_response_line(), mode, dataref);
312 -}
313 -
314 -const char *fast_export_read_path(const char *path, uint32_t *mode_out)
315 -{
316 - int err;
317 - static struct strbuf buf = STRBUF_INIT;
318 -
319 - strbuf_reset(&buf);
320 - err = fast_export_ls(path, mode_out, &buf);
321 - if (err) {
322 - if (errno != ENOENT)
323 - BUG("unexpected fast_export_ls error: %s",
324 - strerror(errno));
325 - /* Treat missing paths as directories. */
326 - *mode_out = S_IFDIR;
327 - return NULL;
328 - }
329 - return buf.buf;
330 -}
331 -
332 -void fast_export_copy(uint32_t revision, const char *src, const char *dst)
333 -{
334 - int err;
335 - uint32_t mode;
336 - static struct strbuf data = STRBUF_INIT;
337 -
338 - strbuf_reset(&data);
339 - err = fast_export_ls_rev(revision, src, &mode, &data);
340 - if (err) {
341 - if (errno != ENOENT)
342 - BUG("unexpected fast_export_ls_rev error: %s",
343 - strerror(errno));
344 - fast_export_delete(dst);
345 - return;
346 - }
347 - fast_export_modify(dst, mode, data.buf);
348 -}
349 -
350 -void fast_export_blob_delta(uint32_t mode,
351 - uint32_t old_mode, const char *old_data,
352 - off_t len, struct line_buffer *input)
353 -{
354 - long postimage_len;
355 -
356 - assert(len >= 0);
357 - postimage_len = apply_delta(len, input, old_data, old_mode);
358 - if (mode == S_IFLNK) {
359 - buffer_skip_bytes(&postimage, strlen("link "));
360 - postimage_len -= strlen("link ");
361 - }
362 - printf("data %ld\n", postimage_len);
363 - buffer_copy_bytes(&postimage, postimage_len);
364 - fputc('\n', stdout);
365 -}
vcs-svn/line_buffer.c deleted
-126
@@ -1,126 +0,0 @@
1 -/*
2 - * Licensed under a two-clause BSD-style license.
3 - * See LICENSE for details.
4 - */
5 -
6 -#include "git-compat-util.h"
7 -#include "line_buffer.h"
8 -#include "strbuf.h"
9 -
10 -#define COPY_BUFFER_LEN 4096
11 -
12 -int buffer_init(struct line_buffer *buf, const char *filename)
13 -{
14 - buf->infile = filename ? fopen(filename, "r") : stdin;
15 - if (!buf->infile)
16 - return -1;
17 - return 0;
18 -}
19 -
20 -int buffer_fdinit(struct line_buffer *buf, int fd)
21 -{
22 - buf->infile = fdopen(fd, "r");
23 - if (!buf->infile)
24 - return -1;
25 - return 0;
26 -}
27 -
28 -int buffer_tmpfile_init(struct line_buffer *buf)
29 -{
30 - buf->infile = tmpfile();
31 - if (!buf->infile)
32 - return -1;
33 - return 0;
34 -}
35 -
36 -int buffer_deinit(struct line_buffer *buf)
37 -{
38 - int err;
39 - if (buf->infile == stdin)
40 - return ferror(buf->infile);
41 - err = ferror(buf->infile);
42 - err |= fclose(buf->infile);
43 - return err;
44 -}
45 -
46 -FILE *buffer_tmpfile_rewind(struct line_buffer *buf)
47 -{
48 - rewind(buf->infile);
49 - return buf->infile;
50 -}
51 -
52 -long buffer_tmpfile_prepare_to_read(struct line_buffer *buf)
53 -{
54 - long pos = ftell(buf->infile);
55 - if (pos < 0)
56 - return error_errno("ftell error");
57 - if (fseek(buf->infile, 0, SEEK_SET))
58 - return error_errno("seek error");
59 - return pos;
60 -}
61 -
62 -int buffer_ferror(struct line_buffer *buf)
63 -{
64 - return ferror(buf->infile);
65 -}
66 -
67 -int buffer_read_char(struct line_buffer *buf)
68 -{
69 - return fgetc(buf->infile);
70 -}
71 -
72 -/* Read a line without trailing newline. */
73 -char *buffer_read_line(struct line_buffer *buf)
74 -{
75 - char *end;
76 - if (!fgets(buf->line_buffer, sizeof(buf->line_buffer), buf->infile))
77 - /* Error or data exhausted. */
78 - return NULL;
79 - end = buf->line_buffer + strlen(buf->line_buffer);
80 - if (end[-1] == '\n')
81 - end[-1] = '\0';
82 - else if (feof(buf->infile))
83 - ; /* No newline at end of file. That's fine. */
84 - else
85 - /*
86 - * Line was too long.
87 - * There is probably a saner way to deal with this,
88 - * but for now let's return an error.
89 - */
90 - return NULL;
91 - return buf->line_buffer;
92 -}
93 -
94 -size_t buffer_read_binary(struct line_buffer *buf,
95 - struct strbuf *sb, size_t size)
96 -{
97 - return strbuf_fread(sb, size, buf->infile);
98 -}
99 -
100 -off_t buffer_copy_bytes(struct line_buffer *buf, off_t nbytes)
101 -{
102 - char byte_buffer[COPY_BUFFER_LEN];
103 - off_t done = 0;
104 - while (done < nbytes && !feof(buf->infile) && !ferror(buf->infile)) {
105 - off_t len = nbytes - done;
106 - size_t in = len < COPY_BUFFER_LEN ? len : COPY_BUFFER_LEN;
107 - in = fread(byte_buffer, 1, in, buf->infile);
108 - done += in;
109 - fwrite(byte_buffer, 1, in, stdout);
110 - if (ferror(stdout))
111 - return done + buffer_skip_bytes(buf, nbytes - done);
112 - }
113 - return done;
114 -}
115 -
116 -off_t buffer_skip_bytes(struct line_buffer *buf, off_t nbytes)
117 -{
118 - char byte_buffer[COPY_BUFFER_LEN];
119 - off_t done = 0;
120 - while (done < nbytes && !feof(buf->infile) && !ferror(buf->infile)) {
121 - off_t len = nbytes - done;
122 - size_t in = len < COPY_BUFFER_LEN ? len : COPY_BUFFER_LEN;
123 - done += fread(byte_buffer, 1, in, buf->infile);
124 - }
125 - return done;
126 -}
vcs-svn/line_buffer.txt deleted
-77
@@ -1,77 +0,0 @@
1 -line_buffer API
2 -===============
3 -
4 -The line_buffer library provides a convenient interface for
5 -mostly-line-oriented input.
6 -
7 -Each line is not permitted to exceed 10000 bytes. The provided
8 -functions are not thread-safe or async-signal-safe, and like
9 -`fgets()`, they generally do not function correctly if interrupted
10 -by a signal without SA_RESTART set.
11 -
12 -Calling sequence
13 -----------------
14 -
15 -The calling program:
16 -
17 - - initializes a `struct line_buffer` to LINE_BUFFER_INIT
18 - - specifies a file to read with `buffer_init`
19 - - processes input with `buffer_read_line`, `buffer_skip_bytes`,
20 - and `buffer_copy_bytes`
21 - - closes the file with `buffer_deinit`, perhaps to start over and
22 - read another file.
23 -
24 -When finished, the caller can use `buffer_reset` to deallocate
25 -resources.
26 -
27 -Using temporary files
28 ----------------------
29 -
30 -Temporary files provide a place to store data that should not outlive
31 -the calling program. A program
32 -
33 - - initializes a `struct line_buffer` to LINE_BUFFER_INIT
34 - - requests a temporary file with `buffer_tmpfile_init`
35 - - acquires an output handle by calling `buffer_tmpfile_rewind`
36 - - uses standard I/O functions like `fprintf` and `fwrite` to fill
37 - the temporary file
38 - - declares writing is over with `buffer_tmpfile_prepare_to_read`
39 - - can re-read what was written with `buffer_read_line`,
40 - `buffer_copy_bytes`, and so on
41 - - can reuse the temporary file by calling `buffer_tmpfile_rewind`
42 - again
43 - - removes the temporary file with `buffer_deinit`, perhaps to
44 - reuse the line_buffer for some other file.
45 -
46 -When finished, the calling program can use `buffer_reset` to deallocate
47 -resources.
48 -
49 -Functions
50 ----------
51 -
52 -`buffer_init`, `buffer_fdinit`::
53 - Open the named file or file descriptor for input.
54 - buffer_init(buf, NULL) prepares to read from stdin.
55 - On failure, returns -1 (with errno indicating the nature
56 - of the failure).
57 -
58 -`buffer_deinit`::
59 - Stop reading from the current file (closing it unless
60 - it was stdin). Returns nonzero if `fclose` fails or
61 - the error indicator was set.
62 -
63 -`buffer_read_line`::
64 - Read a line and strip off the trailing newline.
65 - On failure or end of file, returns NULL.
66 -
67 -`buffer_copy_bytes`::
68 - Read `len` bytes of input and dump them to the standard output
69 - stream. Returns early for error or end of file.
70 -
71 -`buffer_skip_bytes`::
72 - Discards `len` bytes from the input stream (stopping early
73 - if necessary because of an error or eof). Return value is
74 - the number of bytes successfully read.
75 -
76 -`buffer_reset`::
77 - Deallocates non-static buffers.
vcs-svn/sliding_window.c deleted
-79
@@ -1,79 +0,0 @@
1 -/*
2 - * Licensed under a two-clause BSD-style license.
3 - * See LICENSE for details.
4 - */
5 -
6 -#include "git-compat-util.h"
7 -#include "sliding_window.h"
8 -#include "line_buffer.h"
9 -#include "strbuf.h"
10 -
11 -static int input_error(struct line_buffer *file)
12 -{
13 - if (!buffer_ferror(file))
14 - return error("delta preimage ends early");
15 - return error_errno("cannot read delta preimage");
16 -}
17 -
18 -static int skip_or_whine(struct line_buffer *file, off_t gap)
19 -{
20 - if (buffer_skip_bytes(file, gap) != gap)
21 - return input_error(file);
22 - return 0;
23 -}
24 -
25 -static int read_to_fill_or_whine(struct line_buffer *file,
26 - struct strbuf *buf, size_t width)
27 -{
28 - buffer_read_binary(file, buf, width - buf->len);
29 - if (buf->len != width)
30 - return input_error(file);
31 - return 0;
32 -}
33 -
34 -static int check_offset_overflow(off_t offset, uintmax_t len)
35 -{
36 - if (len > maximum_signed_value_of_type(off_t))
37 - return error("unrepresentable length in delta: "
38 - "%"PRIuMAX" > OFF_MAX", len);
39 - if (signed_add_overflows(offset, (off_t) len))
40 - return error("unrepresentable offset in delta: "
41 - "%"PRIuMAX" + %"PRIuMAX" > OFF_MAX",
42 - (uintmax_t) offset, len);
43 - return 0;
44 -}
45 -
46 -int move_window(struct sliding_view *view, off_t off, size_t width)
47 -{
48 - off_t file_offset;
49 - assert(view);
50 - assert(view->width <= view->buf.len);
51 - assert(!check_offset_overflow(view->off, view->buf.len));
52 -
53 - if (check_offset_overflow(off, width))
54 - return -1;
55 - if (off < view->off || off + width < view->off + view->width)
56 - return error("invalid delta: window slides left");
57 - if (view->max_off >= 0 && view->max_off < off + (off_t) width)
58 - return error("delta preimage ends early");
59 -
60 - file_offset = view->off + view->buf.len;
61 - if (off < file_offset) {
62 - /* Move the overlapping region into place. */
63 - strbuf_remove(&view->buf, 0, off - view->off);
64 - } else {
65 - /* Seek ahead to skip the gap. */
66 - if (skip_or_whine(view->file, off - file_offset))
67 - return -1;
68 - strbuf_setlen(&view->buf, 0);
69 - }
70 -
71 - if (view->buf.len > width)
72 - ; /* Already read. */
73 - else if (read_to_fill_or_whine(view->file, &view->buf, width))
74 - return -1;
75 -
76 - view->off = off;
77 - view->width = width;
78 - return 0;
79 -}
vcs-svn/svndiff.c deleted
-309
@@ -1,309 +0,0 @@
1 -/*
2 - * Licensed under a two-clause BSD-style license.
3 - * See LICENSE for details.
4 - */
5 -
6 -#include "git-compat-util.h"
7 -#include "sliding_window.h"
8 -#include "line_buffer.h"
9 -#include "svndiff.h"
10 -
11 -/*
12 - * svndiff0 applier
13 - *
14 - * See http://svn.apache.org/repos/asf/subversion/trunk/notes/svndiff.
15 - *
16 - * svndiff0 ::= 'SVN\0' window*
17 - * window ::= int int int int int instructions inline_data;
18 - * instructions ::= instruction*;
19 - * instruction ::= view_selector int int
20 - * | copyfrom_data int
21 - * | packed_view_selector int
22 - * | packed_copyfrom_data
23 - * ;
24 - * view_selector ::= copyfrom_source
25 - * | copyfrom_target
26 - * ;
27 - * copyfrom_source ::= # binary 00 000000;
28 - * copyfrom_target ::= # binary 01 000000;
29 - * copyfrom_data ::= # binary 10 000000;
30 - * packed_view_selector ::= # view_selector OR-ed with 6 bit value;
31 - * packed_copyfrom_data ::= # copyfrom_data OR-ed with 6 bit value;
32 - * int ::= highdigit* lowdigit;
33 - * highdigit ::= # binary 1000 0000 OR-ed with 7 bit value;
34 - * lowdigit ::= # 7 bit value;
35 - */
36 -
37 -#define INSN_MASK 0xc0
38 -#define INSN_COPYFROM_SOURCE 0x00
39 -#define INSN_COPYFROM_TARGET 0x40
40 -#define INSN_COPYFROM_DATA 0x80
41 -#define OPERAND_MASK 0x3f
42 -
43 -#define VLI_CONTINUE 0x80
44 -#define VLI_DIGIT_MASK 0x7f
45 -#define VLI_BITS_PER_DIGIT 7
46 -
47 -struct window {
48 - struct sliding_view *in;
49 - struct strbuf out;
50 - struct strbuf instructions;
51 - struct strbuf data;
52 -};
53 -
54 -#define WINDOW_INIT(w) { (w), STRBUF_INIT, STRBUF_INIT, STRBUF_INIT }
55 -
56 -static void window_release(struct window *ctx)
57 -{
58 - strbuf_release(&ctx->out);
59 - strbuf_release(&ctx->instructions);
60 - strbuf_release(&ctx->data);
61 -}
62 -
63 -static int write_strbuf(struct strbuf *sb, FILE *out)
64 -{
65 - if (fwrite(sb->buf, 1, sb->len, out) == sb->len) /* Success. */
66 - return 0;
67 - return error_errno("cannot write delta postimage");
68 -}
69 -
70 -static int error_short_read(struct line_buffer *input)
71 -{
72 - if (buffer_ferror(input))
73 - return error_errno("error reading delta");
74 - return error("invalid delta: unexpected end of file");
75 -}
76 -
77 -static int read_chunk(struct line_buffer *delta, off_t *delta_len,
78 - struct strbuf *buf, size_t len)
79 -{
80 - assert(*delta_len >= 0);
81 - strbuf_reset(buf);
82 - if (len > (uintmax_t) *delta_len ||
83 - buffer_read_binary(delta, buf, len) != len)
84 - return error_short_read(delta);
85 - *delta_len -= buf->len;
86 - return 0;
87 -}
88 -
89 -static int read_magic(struct line_buffer *in, off_t *len)
90 -{
91 - static const char magic[] = {'S', 'V', 'N', '\0'};
92 - struct strbuf sb = STRBUF_INIT;
93 -
94 - if (read_chunk(in, len, &sb, sizeof(magic))) {
95 - strbuf_release(&sb);
96 - return -1;
97 - }
98 - if (memcmp(sb.buf, magic, sizeof(magic))) {
99 - strbuf_release(&sb);
100 - return error("invalid delta: unrecognized file type");
101 - }
102 - strbuf_release(&sb);
103 - return 0;
104 -}
105 -
106 -static int read_int(struct line_buffer *in, uintmax_t *result, off_t *len)
107 -{
108 - uintmax_t rv = 0;
109 - off_t sz;
110 - for (sz = *len; sz; sz--) {
111 - const int ch = buffer_read_char(in);
112 - if (ch == EOF)
113 - break;
114 -
115 - rv <<= VLI_BITS_PER_DIGIT;
116 - rv += (ch & VLI_DIGIT_MASK);
117 - if (ch & VLI_CONTINUE)
118 - continue;
119 -
120 - *result = rv;
121 - *len = sz - 1;
122 - return 0;
123 - }
124 - return error_short_read(in);
125 -}
126 -
127 -static int parse_int(const char **buf, size_t *result, const char *end)
128 -{
129 - size_t rv = 0;
130 - const char *pos;
131 - for (pos = *buf; pos != end; pos++) {
132 - unsigned char ch = *pos;
133 -
134 - rv <<= VLI_BITS_PER_DIGIT;
135 - rv += (ch & VLI_DIGIT_MASK);
136 - if (ch & VLI_CONTINUE)
137 - continue;
138 -
139 - *result = rv;
140 - *buf = pos + 1;
141 - return 0;
142 - }
143 - return error("invalid delta: unexpected end of instructions section");
144 -}
145 -
146 -static int read_offset(struct line_buffer *in, off_t *result, off_t *len)
147 -{
148 - uintmax_t val;
149 - if (read_int(in, &val, len))
150 - return -1;
151 - if (val > maximum_signed_value_of_type(off_t))
152 - return error("unrepresentable offset in delta: %"PRIuMAX"", val);
153 - *result = val;
154 - return 0;
155 -}
156 -
157 -static int read_length(struct line_buffer *in, size_t *result, off_t *len)
158 -{
159 - uintmax_t val;
160 - if (read_int(in, &val, len))
161 - return -1;
162 - if (val > SIZE_MAX)
163 - return error("unrepresentable length in delta: %"PRIuMAX"", val);
164 - *result = val;
165 - return 0;
166 -}
167 -
168 -static int copyfrom_source(struct window *ctx, const char **instructions,
169 - size_t nbytes, const char *insns_end)
170 -{
171 - size_t offset;
172 - if (parse_int(instructions, &offset, insns_end))
173 - return -1;
174 - if (unsigned_add_overflows(offset, nbytes) ||
175 - offset + nbytes > ctx->in->width)
176 - return error("invalid delta: copies source data outside view");
177 - strbuf_add(&ctx->out, ctx->in->buf.buf + offset, nbytes);
178 - return 0;
179 -}
180 -
181 -static int copyfrom_target(struct window *ctx, const char **instructions,
182 - size_t nbytes, const char *instructions_end)
183 -{
184 - size_t offset;
185 - if (parse_int(instructions, &offset, instructions_end))
186 - return -1;
187 - if (offset >= ctx->out.len)
188 - return error("invalid delta: copies from the future");
189 - for (; nbytes > 0; nbytes--)
190 - strbuf_addch(&ctx->out, ctx->out.buf[offset++]);
191 - return 0;
192 -}
193 -
194 -static int copyfrom_data(struct window *ctx, size_t *data_pos, size_t nbytes)
195 -{
196 - const size_t pos = *data_pos;
197 - if (unsigned_add_overflows(pos, nbytes) ||
198 - pos + nbytes > ctx->data.len)
199 - return error("invalid delta: copies unavailable inline data");
200 - strbuf_add(&ctx->out, ctx->data.buf + pos, nbytes);
201 - *data_pos += nbytes;
202 - return 0;
203 -}
204 -
205 -static int parse_first_operand(const char **buf, size_t *out, const char *end)
206 -{
207 - size_t result = (unsigned char) *(*buf)++ & OPERAND_MASK;
208 - if (result) { /* immediate operand */
209 - *out = result;
210 - return 0;
211 - }
212 - return parse_int(buf, out, end);
213 -}
214 -
215 -static int execute_one_instruction(struct window *ctx,
216 - const char **instructions, size_t *data_pos)
217 -{
218 - unsigned int instruction;
219 - const char *insns_end = ctx->instructions.buf + ctx->instructions.len;
220 - size_t nbytes;
221 - assert(ctx);
222 - assert(instructions && *instructions);
223 - assert(data_pos);
224 -
225 - instruction = (unsigned char) **instructions;
226 - if (parse_first_operand(instructions, &nbytes, insns_end))
227 - return -1;
228 - switch (instruction & INSN_MASK) {
229 - case INSN_COPYFROM_SOURCE:
230 - return copyfrom_source(ctx, instructions, nbytes, insns_end);
231 - case INSN_COPYFROM_TARGET:
232 - return copyfrom_target(ctx, instructions, nbytes, insns_end);
233 - case INSN_COPYFROM_DATA:
234 - return copyfrom_data(ctx, data_pos, nbytes);
235 - default:
236 - return error("invalid delta: unrecognized instruction");
237 - }
238 -}
239 -
240 -static int apply_window_in_core(struct window *ctx)
241 -{
242 - const char *instructions;
243 - size_t data_pos = 0;
244 -
245 - /*
246 - * Fill ctx->out.buf using data from the source, target,
247 - * and inline data views.
248 - */
249 - for (instructions = ctx->instructions.buf;
250 - instructions != ctx->instructions.buf + ctx->instructions.len;
251 - )
252 - if (execute_one_instruction(ctx, &instructions, &data_pos))
253 - return -1;
254 - if (data_pos != ctx->data.len)
255 - return error("invalid delta: does not copy all inline data");
256 - return 0;
257 -}
258 -
259 -static int apply_one_window(struct line_buffer *delta, off_t *delta_len,
260 - struct sliding_view *preimage, FILE *out)
261 -{
262 - int rv = -1;
263 - struct window ctx = WINDOW_INIT(preimage);
264 - size_t out_len;
265 - size_t instructions_len;
266 - size_t data_len;
267 - assert(delta_len);
268 -
269 - /* "source view" offset and length already handled; */
270 - if (read_length(delta, &out_len, delta_len) ||
271 - read_length(delta, &instructions_len, delta_len) ||
272 - read_length(delta, &data_len, delta_len) ||
273 - read_chunk(delta, delta_len, &ctx.instructions, instructions_len) ||
274 - read_chunk(delta, delta_len, &ctx.data, data_len))
275 - goto error_out;
276 - strbuf_grow(&ctx.out, out_len);
277 - if (apply_window_in_core(&ctx))
278 - goto error_out;
279 - if (ctx.out.len != out_len) {
280 - rv = error("invalid delta: incorrect postimage length");
281 - goto error_out;
282 - }
283 - if (write_strbuf(&ctx.out, out))
284 - goto error_out;
285 - rv = 0;
286 -error_out:
287 - window_release(&ctx);
288 - return rv;
289 -}
290 -
291 -int svndiff0_apply(struct line_buffer *delta, off_t delta_len,
292 - struct sliding_view *preimage, FILE *postimage)
293 -{
294 - assert(delta && preimage && postimage && delta_len >= 0);
295 -
296 - if (read_magic(delta, &delta_len))
297 - return -1;
298 - while (delta_len) { /* For each window: */
299 - off_t pre_off = -1;
300 - size_t pre_len;
301 -
302 - if (read_offset(delta, &pre_off, &delta_len) ||
303 - read_length(delta, &pre_len, &delta_len) ||
304 - move_window(preimage, pre_off, pre_len) ||
305 - apply_one_window(delta, &delta_len, preimage, postimage))
306 - return -1;
307 - }
308 - return 0;
309 -}
vcs-svn/svndump.c deleted
-540
@@ -1,540 +0,0 @@
1 -/*
2 - * Parse and rearrange a svnadmin dump.
3 - * Create the dump with:
4 - * svnadmin dump --incremental -r<startrev>:<endrev> <repository> >outfile
5 - *
6 - * Licensed under a two-clause BSD-style license.
7 - * See LICENSE for details.
8 - */
9 -
10 -#include "cache.h"
11 -#include "fast_export.h"
12 -#include "line_buffer.h"
13 -#include "strbuf.h"
14 -#include "svndump.h"
15 -
16 -/*
17 - * Compare start of string to literal of equal length;
18 - * must be guarded by length test.
19 - */
20 -#define constcmp(s, ref) memcmp(s, ref, sizeof(ref) - 1)
21 -
22 -#define REPORT_FILENO 3
23 -
24 -#define NODEACT_REPLACE 4
25 -#define NODEACT_DELETE 3
26 -#define NODEACT_ADD 2
27 -#define NODEACT_CHANGE 1
28 -#define NODEACT_UNKNOWN 0
29 -
30 -/* States: */
31 -#define DUMP_CTX 0 /* dump metadata */
32 -#define REV_CTX 1 /* revision metadata */
33 -#define NODE_CTX 2 /* node metadata */
34 -#define INTERNODE_CTX 3 /* between nodes */
35 -
36 -#define DATE_RFC2822_LEN 31
37 -
38 -static struct line_buffer input = LINE_BUFFER_INIT;
39 -
40 -static struct {
41 - uint32_t action, srcRev, type;
42 - off_t prop_length, text_length;
43 - struct strbuf src, dst;
44 - uint32_t text_delta, prop_delta;
45 -} node_ctx;
46 -
47 -static struct {
48 - uint32_t revision;
49 - timestamp_t timestamp;
50 - struct strbuf log, author, note;
51 -} rev_ctx;
52 -
53 -static struct {
54 - uint32_t version;
55 - struct strbuf uuid, url;
56 -} dump_ctx;
57 -
58 -static void reset_node_ctx(char *fname)
59 -{
60 - node_ctx.type = 0;
61 - node_ctx.action = NODEACT_UNKNOWN;
62 - node_ctx.prop_length = -1;
63 - node_ctx.text_length = -1;
64 - strbuf_reset(&node_ctx.src);
65 - node_ctx.srcRev = 0;
66 - strbuf_reset(&node_ctx.dst);
67 - if (fname)
68 - strbuf_addstr(&node_ctx.dst, fname);
69 - node_ctx.text_delta = 0;
70 - node_ctx.prop_delta = 0;
71 -}
72 -
73 -static void reset_rev_ctx(uint32_t revision)
74 -{
75 - rev_ctx.revision = revision;
76 - rev_ctx.timestamp = 0;
77 - strbuf_reset(&rev_ctx.log);
78 - strbuf_reset(&rev_ctx.author);
79 - strbuf_reset(&rev_ctx.note);
80 -}
81 -
82 -static void reset_dump_ctx(const char *url)
83 -{
84 - strbuf_reset(&dump_ctx.url);
85 - if (url)
86 - strbuf_addstr(&dump_ctx.url, url);
87 - dump_ctx.version = 1;
88 - strbuf_reset(&dump_ctx.uuid);
89 -}
90 -
91 -static void handle_property(const struct strbuf *key_buf,
92 - struct strbuf *val,
93 - uint32_t *type_set)
94 -{
95 - const char *key = key_buf->buf;
96 - size_t keylen = key_buf->len;
97 -
98 - switch (keylen + 1) {
99 - case sizeof("svn:log"):
100 - if (constcmp(key, "svn:log"))
101 - break;
102 - if (!val)
103 - die("invalid dump: unsets svn:log");
104 - strbuf_swap(&rev_ctx.log, val);
105 - break;
106 - case sizeof("svn:author"):
107 - if (constcmp(key, "svn:author"))
108 - break;
109 - if (!val)
110 - strbuf_reset(&rev_ctx.author);
111 - else
112 - strbuf_swap(&rev_ctx.author, val);
113 - break;
114 - case sizeof("svn:date"):
115 - if (constcmp(key, "svn:date"))
116 - break;
117 - if (!val)
118 - die("invalid dump: unsets svn:date");
119 - if (parse_date_basic(val->buf, &rev_ctx.timestamp, NULL))
120 - warning("invalid timestamp: %s", val->buf);
121 - break;
122 - case sizeof("svn:executable"):
123 - case sizeof("svn:special"):
124 - if (keylen == strlen("svn:executable") &&
125 - constcmp(key, "svn:executable"))
126 - break;
127 - if (keylen == strlen("svn:special") &&
128 - constcmp(key, "svn:special"))
129 - break;
130 - if (*type_set) {
131 - if (!val)
132 - return;
133 - die("invalid dump: sets type twice");
134 - }
135 - if (!val) {
136 - node_ctx.type = S_IFREG | 0644;
137 - return;
138 - }
139 - *type_set = 1;
140 - node_ctx.type = keylen == strlen("svn:executable") ?
141 - (S_IFREG | 0755) :
142 - S_IFLNK;
143 - }
144 -}
145 -
146 -static void die_short_read(void)
147 -{
148 - if (buffer_ferror(&input))
149 - die_errno("error reading dump file");
150 - die("invalid dump: unexpected end of file");
151 -}
152 -
153 -static void read_props(void)
154 -{
155 - static struct strbuf key = STRBUF_INIT;
156 - static struct strbuf val = STRBUF_INIT;
157 - const char *t;
158 - /*
159 - * NEEDSWORK: to support simple mode changes like
160 - * K 11
161 - * svn:special
162 - * V 1
163 - * *
164 - * D 14
165 - * svn:executable
166 - * we keep track of whether a mode has been set and reset to
167 - * plain file only if not. We should be keeping track of the
168 - * symlink and executable bits separately instead.
169 - */
170 - uint32_t type_set = 0;
171 - while ((t = buffer_read_line(&input)) && strcmp(t, "PROPS-END")) {
172 - uint32_t len;
173 - const char type = t[0];
174 - int ch;
175 -
176 - if (!type || t[1] != ' ')
177 - die("invalid property line: %s", t);
178 - len = atoi(&t[2]);
179 - strbuf_reset(&val);
180 - buffer_read_binary(&input, &val, len);
181 - if (val.len < len)
182 - die_short_read();
183 -
184 - /* Discard trailing newline. */
185 - ch = buffer_read_char(&input);
186 - if (ch == EOF)
187 - die_short_read();
188 - if (ch != '\n')
189 - die("invalid dump: expected newline after %s", val.buf);
190 -
191 - switch (type) {
192 - case 'K':
193 - strbuf_swap(&key, &val);
194 - continue;
195 - case 'D':
196 - handle_property(&val, NULL, &type_set);
197 - continue;
198 - case 'V':
199 - handle_property(&key, &val, &type_set);
200 - strbuf_reset(&key);
201 - continue;
202 - default:
203 - die("invalid property line: %s", t);
204 - }
205 - }
206 -}
207 -
208 -static void handle_node(void)
209 -{
210 - const uint32_t type = node_ctx.type;
211 - const int have_props = node_ctx.prop_length != -1;
212 - const int have_text = node_ctx.text_length != -1;
213 - /*
214 - * Old text for this node:
215 - * NULL - directory or bug
216 - * empty_blob - empty
217 - * "<dataref>" - data retrievable from fast-import
218 - */
219 - static const char *const empty_blob = "::empty::";
220 - const char *old_data = NULL;
221 - uint32_t old_mode = S_IFREG | 0644;
222 -
223 - if (node_ctx.action == NODEACT_DELETE) {
224 - if (have_text || have_props || node_ctx.srcRev)
225 - die("invalid dump: deletion node has "
226 - "copyfrom info, text, or properties");
227 - fast_export_delete(node_ctx.dst.buf);
228 - return;
229 - }
230 - if (node_ctx.action == NODEACT_REPLACE) {
231 - fast_export_delete(node_ctx.dst.buf);
232 - node_ctx.action = NODEACT_ADD;
233 - }
234 - if (node_ctx.srcRev) {
235 - fast_export_copy(node_ctx.srcRev, node_ctx.src.buf, node_ctx.dst.buf);
236 - if (node_ctx.action == NODEACT_ADD)
237 - node_ctx.action = NODEACT_CHANGE;
238 - }
239 - if (have_text && type == S_IFDIR)
240 - die("invalid dump: directories cannot have text attached");
241 -
242 - /*
243 - * Find old content (old_data) and decide on the new mode.
244 - */
245 - if (node_ctx.action == NODEACT_CHANGE && !*node_ctx.dst.buf) {
246 - if (type != S_IFDIR)
247 - die("invalid dump: root of tree is not a regular file");
248 - old_data = NULL;
249 - } else if (node_ctx.action == NODEACT_CHANGE) {
250 - uint32_t mode;
251 - old_data = fast_export_read_path(node_ctx.dst.buf, &mode);
252 - if (mode == S_IFDIR && type != S_IFDIR)
253 - die("invalid dump: cannot modify a directory into a file");
254 - if (mode != S_IFDIR && type == S_IFDIR)
255 - die("invalid dump: cannot modify a file into a directory");
256 - node_ctx.type = mode;
257 - old_mode = mode;
258 - } else if (node_ctx.action == NODEACT_ADD) {
259 - if (type == S_IFDIR)
260 - old_data = NULL;
261 - else if (have_text)
262 - old_data = empty_blob;
263 - else
264 - die("invalid dump: adds node without text");
265 - } else {
266 - die("invalid dump: Node-path block lacks Node-action");
267 - }
268 -
269 - /*
270 - * Adjust mode to reflect properties.
271 - */
272 - if (have_props) {
273 - if (!node_ctx.prop_delta)
274 - node_ctx.type = type;
275 - if (node_ctx.prop_length)
276 - read_props();
277 - }
278 -
279 - /*
280 - * Save the result.
281 - */
282 - if (type == S_IFDIR) /* directories are not tracked. */
283 - return;
284 - assert(old_data);
285 - if (old_data == empty_blob)
286 - /* For the fast_export_* functions, NULL means empty. */
287 - old_data = NULL;
288 - if (!have_text) {
289 - fast_export_modify(node_ctx.dst.buf, node_ctx.type, old_data);
290 - return;
291 - }
292 - if (!node_ctx.text_delta) {
293 - fast_export_modify(node_ctx.dst.buf, node_ctx.type, "inline");
294 - fast_export_data(node_ctx.type, node_ctx.text_length, &input);
295 - return;
296 - }
297 - fast_export_modify(node_ctx.dst.buf, node_ctx.type, "inline");
298 - fast_export_blob_delta(node_ctx.type, old_mode, old_data,
299 - node_ctx.text_length, &input);
300 -}
301 -
302 -static void begin_revision(const char *remote_ref)
303 -{
304 - if (!rev_ctx.revision) /* revision 0 gets no git commit. */
305 - return;
306 - fast_export_begin_commit(rev_ctx.revision, rev_ctx.author.buf,
307 - &rev_ctx.log, dump_ctx.uuid.buf, dump_ctx.url.buf,
308 - rev_ctx.timestamp, remote_ref);
309 -}
310 -
311 -static void end_revision(const char *note_ref)
312 -{
313 - struct strbuf mark = STRBUF_INIT;
314 - if (rev_ctx.revision) {
315 - fast_export_end_commit(rev_ctx.revision);
316 - fast_export_begin_note(rev_ctx.revision, "remote-svn",
317 - "Note created by remote-svn.", rev_ctx.timestamp, note_ref);
318 - strbuf_addf(&mark, ":%"PRIu32, rev_ctx.revision);
319 - fast_export_note(mark.buf, "inline");
320 - fast_export_buf_to_data(&rev_ctx.note);
321 - strbuf_release(&mark);
322 - }
323 -}
324 -
325 -void svndump_read(const char *url, const char *local_ref, const char *notes_ref)
326 -{
327 - char *val;
328 - char *t;
329 - uint32_t active_ctx = DUMP_CTX;
330 - uint32_t len;
331 -
332 - reset_dump_ctx(url);
333 - while ((t = buffer_read_line(&input))) {
334 - val = strchr(t, ':');
335 - if (!val)
336 - continue;
337 - val++;
338 - if (*val != ' ')
339 - continue;
340 - val++;
341 -
342 - /* strlen(key) + 1 */
343 - switch (val - t - 1) {
344 - case sizeof("SVN-fs-dump-format-version"):
345 - if (constcmp(t, "SVN-fs-dump-format-version"))
346 - continue;
347 - dump_ctx.version = atoi(val);
348 - if (dump_ctx.version > 3)
349 - die("expected svn dump format version <= 3, found %"PRIu32,
350 - dump_ctx.version);
351 - break;
352 - case sizeof("UUID"):
353 - if (constcmp(t, "UUID"))
354 - continue;
355 - strbuf_reset(&dump_ctx.uuid);
356 - strbuf_addstr(&dump_ctx.uuid, val);
357 - break;
358 - case sizeof("Revision-number"):
359 - if (constcmp(t, "Revision-number"))
360 - continue;
361 - if (active_ctx == NODE_CTX)
362 - handle_node();
363 - if (active_ctx == REV_CTX)
364 - begin_revision(local_ref);
365 - if (active_ctx != DUMP_CTX)
366 - end_revision(notes_ref);
367 - active_ctx = REV_CTX;
368 - reset_rev_ctx(atoi(val));
369 - strbuf_addf(&rev_ctx.note, "%s\n", t);
370 - break;
371 - case sizeof("Node-path"):
372 - if (constcmp(t, "Node-"))
373 - continue;
374 - if (!constcmp(t + strlen("Node-"), "path")) {
375 - if (active_ctx == NODE_CTX)
376 - handle_node();
377 - if (active_ctx == REV_CTX)
378 - begin_revision(local_ref);
379 - active_ctx = NODE_CTX;
380 - reset_node_ctx(val);
381 - strbuf_addf(&rev_ctx.note, "%s\n", t);
382 - break;
383 - }
384 - if (constcmp(t + strlen("Node-"), "kind"))
385 - continue;
386 - strbuf_addf(&rev_ctx.note, "%s\n", t);
387 - if (!strcmp(val, "dir"))
388 - node_ctx.type = S_IFDIR;
389 - else if (!strcmp(val, "file"))
390 - node_ctx.type = S_IFREG | 0644;
391 - else
392 - fprintf(stderr, "Unknown node-kind: %s\n", val);
393 - break;
394 - case sizeof("Node-action"):
395 - if (constcmp(t, "Node-action"))
396 - continue;
397 - strbuf_addf(&rev_ctx.note, "%s\n", t);
398 - if (!strcmp(val, "delete")) {
399 - node_ctx.action = NODEACT_DELETE;
400 - } else if (!strcmp(val, "add")) {
401 - node_ctx.action = NODEACT_ADD;
402 - } else if (!strcmp(val, "change")) {
403 - node_ctx.action = NODEACT_CHANGE;
404 - } else if (!strcmp(val, "replace")) {
405 - node_ctx.action = NODEACT_REPLACE;
406 - } else {
407 - fprintf(stderr, "Unknown node-action: %s\n", val);
408 - node_ctx.action = NODEACT_UNKNOWN;
409 - }
410 - break;
411 - case sizeof("Node-copyfrom-path"):
412 - if (constcmp(t, "Node-copyfrom-path"))
413 - continue;
414 - strbuf_reset(&node_ctx.src);
415 - strbuf_addstr(&node_ctx.src, val);
416 - strbuf_addf(&rev_ctx.note, "%s\n", t);
417 - break;
418 - case sizeof("Node-copyfrom-rev"):
419 - if (constcmp(t, "Node-copyfrom-rev"))
420 - continue;
421 - node_ctx.srcRev = atoi(val);
422 - strbuf_addf(&rev_ctx.note, "%s\n", t);
423 - break;
424 - case sizeof("Text-content-length"):
425 - if (constcmp(t, "Text") && constcmp(t, "Prop"))
426 - continue;
427 - if (constcmp(t + 4, "-content-length"))
428 - continue;
429 - {
430 - char *end;
431 - uintmax_t len;
432 -
433 - len = strtoumax(val, &end, 10);
434 - if (!isdigit(*val) || *end)
435 - die("invalid dump: non-numeric length %s", val);
436 - if (len > maximum_signed_value_of_type(off_t))
437 - die("unrepresentable length in dump: %s", val);
438 -
439 - if (*t == 'T')
440 - node_ctx.text_length = (off_t) len;
441 - else
442 - node_ctx.prop_length = (off_t) len;
443 - break;
444 - }
445 - case sizeof("Text-delta"):
446 - if (!constcmp(t, "Text-delta")) {
447 - node_ctx.text_delta = !strcmp(val, "true");
448 - break;
449 - }
450 - if (constcmp(t, "Prop-delta"))
451 - continue;
452 - node_ctx.prop_delta = !strcmp(val, "true");
453 - break;
454 - case sizeof("Content-length"):
455 - if (constcmp(t, "Content-length"))
456 - continue;
457 - len = atoi(val);
458 - t = buffer_read_line(&input);
459 - if (!t)
460 - die_short_read();
461 - if (*t)
462 - die("invalid dump: expected blank line after content length header");
463 - if (active_ctx == REV_CTX) {
464 - read_props();
465 - } else if (active_ctx == NODE_CTX) {
466 - handle_node();
467 - active_ctx = INTERNODE_CTX;
468 - } else {
469 - fprintf(stderr, "Unexpected content length header: %"PRIu32"\n", len);
470 - if (buffer_skip_bytes(&input, len) != len)
471 - die_short_read();
472 - }
473 - }
474 - }
475 - if (buffer_ferror(&input))
476 - die_short_read();
477 - if (active_ctx == NODE_CTX)
478 - handle_node();
479 - if (active_ctx == REV_CTX)
480 - begin_revision(local_ref);
481 - if (active_ctx != DUMP_CTX)
482 - end_revision(notes_ref);
483 -}
484 -
485 -static void init(int report_fd)
486 -{
487 - fast_export_init(report_fd);
488 - strbuf_init(&dump_ctx.uuid, 4096);
489 - strbuf_init(&dump_ctx.url, 4096);
490 - strbuf_init(&rev_ctx.log, 4096);
491 - strbuf_init(&rev_ctx.author, 4096);
492 - strbuf_init(&rev_ctx.note, 4096);
493 - strbuf_init(&node_ctx.src, 4096);
494 - strbuf_init(&node_ctx.dst, 4096);
495 - reset_dump_ctx(NULL);
496 - reset_rev_ctx(0);
497 - reset_node_ctx(NULL);
498 - return;
499 -}
500 -
501 -int svndump_init(const char *filename)
502 -{
503 - if (buffer_init(&input, filename))
504 - return error_errno("cannot open %s", filename ? filename : "NULL");
505 - init(REPORT_FILENO);
506 - return 0;
507 -}
508 -
509 -int svndump_init_fd(int in_fd, int back_fd)
510 -{
511 - if(buffer_fdinit(&input, xdup(in_fd)))
512 - return error_errno("cannot open fd %d", in_fd);
513 - init(xdup(back_fd));
514 - return 0;
515 -}
516 -
517 -void svndump_deinit(void)
518 -{
519 - fast_export_deinit();
520 - reset_dump_ctx(NULL);
521 - reset_rev_ctx(0);
522 - reset_node_ctx(NULL);
523 - strbuf_release(&rev_ctx.log);
524 - strbuf_release(&rev_ctx.author);
525 - strbuf_release(&rev_ctx.note);
526 - strbuf_release(&node_ctx.src);
527 - strbuf_release(&node_ctx.dst);
528 - if (buffer_deinit(&input))
529 - fprintf(stderr, "Input error\n");
530 - if (ferror(stdout))
531 - fprintf(stderr, "Output error\n");
532 -}
533 -
534 -void svndump_reset(void)
535 -{
536 - strbuf_release(&dump_ctx.uuid);
537 - strbuf_release(&dump_ctx.url);
538 - strbuf_release(&rev_ctx.log);
539 - strbuf_release(&rev_ctx.author);
540 -}