4 * Copyright (C) Linus Torvalds 2005
13 static int verbose = 0;
16 * This is a really stupid program that takes cvsps output, and
17 * generates a a long _shell_script_ that will create the GIT archive
20 * You've been warned. I told you it was stupid.
22 * NOTE NOTE NOTE! In order to do branches correctly, this needs
23 * the fixed cvsps that has the "Ancestor branch" tag output.
24 * Hopefully David Mansfield will update his distribution soon
25 * enough (he's the one who wrote the patch, so at least we don't
26 * have to figt maintainer issues ;)
36 static char date[100];
37 static char author[100];
38 static char branch[100];
39 static char ancestor[100];
41 static char log[32768];
42 static int loglen = 0;
43 static int initial_commit = 1;
45 static void lookup_author(char *n, char **name, char **email)
48 * FIXME!!! I'm lazy and stupid.
50 * This could be something like
52 * printf("lookup_author '%s'\n", n);
53 * *name = "$author_name";
54 * *email = "$author_email";
56 * and that would allow the script to do its own
57 * lookups at run-time.
63 static void prepare_commit(void)
65 char *author_name, *author_email;
68 lookup_author(author, &author_name, &author_email);
70 printf("export GIT_COMMITTER_NAME=%s\n", author_name);
71 printf("export GIT_COMMITTER_EMAIL=%s\n", author_email);
73 printf("export GIT_AUTHOR_NAME=%s\n", author_name);
74 printf("export GIT_AUTHOR_EMAIL=%s\n", author_email);
76 printf("export GIT_AUTHOR_DATE='%s'\n", date);
81 src_branch = *ancestor ? ancestor : branch;
82 if (!strcmp(src_branch, "HEAD"))
83 src_branch = "master";
84 printf("ln -sf refs/heads/'%s' .git/HEAD\n", src_branch);
87 * Even if cvsps claims an ancestor, we'll let the new
88 * branch name take precedence if it already exists
92 if (!strcmp(src_branch, "HEAD"))
93 src_branch = "master";
94 printf("[ -e .git/refs/heads/'%s' ] && ln -sf refs/heads/'%s' .git/HEAD\n",
95 src_branch, src_branch);
98 printf("git-read-tree -m HEAD || exit 1\n");
99 printf("git-checkout-cache -f -u -a\n");
102 static void commit(void)
104 const char *cmit_parent = initial_commit ? "" : "-p HEAD";
105 const char *dst_branch;
108 printf("tree=$(git-write-tree)\n");
109 printf("cat > .cmitmsg <<EOFMSG\n");
111 /* Escape $ characters, and remove control characters */
112 for (i = 0; i < loglen; i++) {
113 unsigned char c = log[i];
120 if (c == '\n' || c == '\t')
127 printf("\nEOFMSG\n");
128 printf("commit=$(cat .cmitmsg | git-commit-tree $tree %s)\n", cmit_parent);
131 if (!strcmp(dst_branch, "HEAD"))
132 dst_branch = "master";
134 printf("echo $commit > .git/refs/heads/'%s'\n", dst_branch);
146 static void get_rcs_name(char *rcspathname, char *name, char *dir)
148 sprintf(rcspathname, "%s/%s,v", rcsdir, name);
149 if (!access(rcspathname, R_OK))
152 sprintf(rcspathname, "%s/Attic/%s,v", rcsdir, name);
153 if (!access(rcspathname, R_OK))
157 sprintf(rcspathname, "%s/%.*s/Attic/%s,v", rcsdir, (int)(dir - name), name, dir+1);
158 if (!access(rcspathname, R_OK))
161 fprintf(stderr, "Unable to find RCS file for %s\n", name);
165 static void update_file(char *line)
167 static char rcspathname[4096];
168 char *name, *version;
171 while (isspace(*line))
174 line = strchr(line, ':');
178 line = strchr(line, '>');
183 line = strchr(line, '(');
184 if (line) { /* "(DEAD)" */
185 printf("git-update-cache --force-remove '%s'\n", name);
189 dir = strrchr(name, '/');
191 printf("mkdir -p %.*s\n", (int)(dir - name), name);
193 get_rcs_name(rcspathname, name, dir);
195 printf("co -q -p -r%s '%s' > '%s'\n", version, rcspathname, name);
196 printf("git-update-cache --add -- '%s'\n", name);
204 { "Author:", author },
205 { "Branch:", branch },
206 { "Ancestor branch:", ancestor },
212 int main(int argc, char **argv)
214 static char line[1000];
215 enum state state = Header;
217 rcsdir = getenv("RCSDIR");
219 fprintf(stderr, "I need an $RCSDIR\n");
223 printf("[ -d .git ] && exit 1\n");
224 printf("git-init-db\n");
225 printf("mkdir -p .git/refs/heads\n");
226 printf("mkdir -p .git/refs/tags\n");
227 printf("ln -sf refs/heads/master .git/HEAD\n");
229 while (fgets(line, sizeof(line), stdin) != NULL) {
230 int linelen = strlen(line);
232 while (linelen && isspace(line[linelen-1]))
236 struct hdrentry *entry;
240 printf("# H: %s\n", line);
241 for (entry = hdrs ; entry->name ; entry++) {
242 int len = strlen(entry->name);
245 if (memcmp(entry->name, line, len))
253 while (isspace(*val)) {
257 memcpy(entry->dest, val, linelen+1);
264 printf("# L: %s\n", line);
265 if (!strcmp(line, "Members:")) {
266 while (loglen && isspace(log[loglen-1]))
273 if (loglen + linelen + 5 > sizeof(log))
275 memcpy(log + loglen, line, linelen);
277 log[loglen++] = '\n';
282 printf("# M: %s\n", line);