8
8
#include "line_buffer.h"
9
9
#include "repo_tree.h"
10
10
#include "string_pool.h"
11
+ #include "strbuf.h"
11
12
12
13
#define MAX_GITSVN_LINE_LEN 4096
13
14
@@ -31,30 +32,35 @@ void fast_export_reset(void)
31
32
buffer_reset (& report_buffer );
32
33
}
33
34
34
- void fast_export_delete (uint32_t depth , uint32_t * path )
35
+ void fast_export_delete (uint32_t depth , const uint32_t * path )
35
36
{
36
37
putchar ('D' );
37
38
putchar (' ' );
38
39
pool_print_seq (depth , path , '/' , stdout );
39
40
putchar ('\n' );
40
41
}
41
42
42
- void fast_export_modify (uint32_t depth , uint32_t * path , uint32_t mode ,
43
- uint32_t mark )
43
+ static void fast_export_truncate (uint32_t depth , const uint32_t * path , uint32_t mode )
44
44
{
45
- /* Mode must be 100644, 100755, 120000, or 160000. */
46
- printf ("M %06" PRIo32 " :%" PRIu32 " " , mode , mark );
47
- pool_print_seq (depth , path , '/' , stdout );
48
- putchar ('\n' );
45
+ fast_export_modify (depth , path , mode , "inline" );
46
+ printf ("data 0\n\n" );
49
47
}
50
48
51
- void fast_export_begin_commit (uint32_t revision )
49
+ void fast_export_modify (uint32_t depth , const uint32_t * path , uint32_t mode ,
50
+ const char * dataref )
52
51
{
53
- printf ("# commit %" PRIu32 ".\n" , revision );
52
+ /* Mode must be 100644, 100755, 120000, or 160000. */
53
+ if (!dataref ) {
54
+ fast_export_truncate (depth , path , mode );
55
+ return ;
56
+ }
57
+ printf ("M %06" PRIo32 " %s " , mode , dataref );
58
+ pool_print_seq (depth , path , '/' , stdout );
59
+ putchar ('\n' );
54
60
}
55
61
56
62
static char gitsvnline [MAX_GITSVN_LINE_LEN ];
57
- void fast_export_commit (uint32_t revision , uint32_t author , char * log ,
63
+ void fast_export_begin_commit (uint32_t revision , uint32_t author , char * log ,
58
64
uint32_t uuid , uint32_t url ,
59
65
unsigned long timestamp )
60
66
{
@@ -81,12 +87,31 @@ void fast_export_commit(uint32_t revision, uint32_t author, char *log,
81
87
printf ("from refs/heads/master^0\n" );
82
88
first_commit_done = 1 ;
83
89
}
84
- repo_diff (revision - 1 , revision );
85
- fputc ('\n' , stdout );
90
+ }
86
91
92
+ void fast_export_end_commit (uint32_t revision )
93
+ {
87
94
printf ("progress Imported commit %" PRIu32 ".\n\n" , revision );
88
95
}
89
96
97
+ static void ls_from_rev (uint32_t rev , uint32_t depth , const uint32_t * path )
98
+ {
99
+ /* ls :5 path/to/old/file */
100
+ printf ("ls :%" PRIu32 " " , rev );
101
+ pool_print_seq (depth , path , '/' , stdout );
102
+ putchar ('\n' );
103
+ fflush (stdout );
104
+ }
105
+
106
+ static void ls_from_active_commit (uint32_t depth , const uint32_t * path )
107
+ {
108
+ /* ls "path/to/file" */
109
+ printf ("ls \"" );
110
+ pool_print_seq (depth , path , '/' , stdout );
111
+ printf ("\"\n" );
112
+ fflush (stdout );
113
+ }
114
+
90
115
static const char * get_response_line (void )
91
116
{
92
117
const char * line = buffer_read_line (& report_buffer );
@@ -97,14 +122,69 @@ static const char *get_response_line(void)
97
122
die ("unexpected end of fast-import feedback" );
98
123
}
99
124
100
- void fast_export_blob (uint32_t mode , uint32_t mark , uint32_t len , struct line_buffer * input )
125
+ void fast_export_data (uint32_t mode , uint32_t len , struct line_buffer * input )
101
126
{
102
127
if (mode == REPO_MODE_LNK ) {
103
128
/* svn symlink blobs start with "link " */
104
129
buffer_skip_bytes (input , 5 );
105
130
len -= 5 ;
106
131
}
107
- printf ("blob\nmark : %" PRIu32 "\ndata %" PRIu32 "\n" , mark , len );
132
+ printf ("data %" PRIu32 "\n" , len );
108
133
buffer_copy_bytes (input , len );
109
134
fputc ('\n' , stdout );
110
135
}
136
+
137
+ static int parse_ls_response (const char * response , uint32_t * mode ,
138
+ struct strbuf * dataref )
139
+ {
140
+ const char * tab ;
141
+ const char * response_end ;
142
+
143
+ assert (response );
144
+ response_end = response + strlen (response );
145
+
146
+ if (* response == 'm' ) { /* Missing. */
147
+ errno = ENOENT ;
148
+ return -1 ;
149
+ }
150
+
151
+ /* Mode. */
152
+ if (response_end - response < strlen ("100644" ) ||
153
+ response [strlen ("100644" )] != ' ' )
154
+ die ("invalid ls response: missing mode: %s" , response );
155
+ * mode = 0 ;
156
+ for (; * response != ' ' ; response ++ ) {
157
+ char ch = * response ;
158
+ if (ch < '0' || ch > '7' )
159
+ die ("invalid ls response: mode is not octal: %s" , response );
160
+ * mode *= 8 ;
161
+ * mode += ch - '0' ;
162
+ }
163
+
164
+ /* ' blob ' or ' tree ' */
165
+ if (response_end - response < strlen (" blob " ) ||
166
+ (response [1 ] != 'b' && response [1 ] != 't' ))
167
+ die ("unexpected ls response: not a tree or blob: %s" , response );
168
+ response += strlen (" blob " );
169
+
170
+ /* Dataref. */
171
+ tab = memchr (response , '\t' , response_end - response );
172
+ if (!tab )
173
+ die ("invalid ls response: missing tab: %s" , response );
174
+ strbuf_add (dataref , response , tab - response );
175
+ return 0 ;
176
+ }
177
+
178
+ int fast_export_ls_rev (uint32_t rev , uint32_t depth , const uint32_t * path ,
179
+ uint32_t * mode , struct strbuf * dataref )
180
+ {
181
+ ls_from_rev (rev , depth , path );
182
+ return parse_ls_response (get_response_line (), mode , dataref );
183
+ }
184
+
185
+ int fast_export_ls (uint32_t depth , const uint32_t * path ,
186
+ uint32_t * mode , struct strbuf * dataref )
187
+ {
188
+ ls_from_active_commit (depth , path );
189
+ return parse_ls_response (get_response_line (), mode , dataref );
190
+ }
0 commit comments