static void print_tag (FILE * out, const database_t * db, tag_t * tag, cvs_connection_t * s) { fprintf (stderr, "%s %s %s\n", format_date (&tag->changeset.time, false), tag->branch_versions ? "BRANCH" : "TAG", tag->tag); tag_t * branch; if (tag->parent == NULL) branch = NULL; else if (tag->parent->type == ct_commit) branch = tag->parent->versions[0]->branch; else branch = as_tag (tag->parent); assert (tag->parent == NULL || (branch && branch->last == tag->parent)); tag->last = &tag->changeset; create_fixups (db, branch ? branch->branch_versions : NULL, tag); // If the tag is a branch, then rewind the current versions to the parent // versions. The fix-up commits will restore things. FIXME - we should // just initialise the branch correctly! if (tag->branch_versions) { size_t bytes = sizeof branch->branch_versions[0] * (db->files_end - db->files); if (branch) memcpy (tag->branch_versions, branch->branch_versions, bytes); else memset (tag->branch_versions, 0, bytes); } if (tag->parent) tag->changeset.mark = tag->parent->mark; else tag->changeset.mark = 0; if (tag->deleted && (!tag->merge_source || tag->fixups == tag->fixups_end)) { assert (tag->branch_versions == NULL); return; } if (!tag->deleted) { fprintf (out, "reset %s/%s\n", tag->branch_versions ? branch_prefix : tag_prefix, *tag->tag ? tag->tag : master); if (tag->changeset.mark != 0) fprintf (out, "from :%zu\n", tag->changeset.mark); } if (tag->branch_versions == NULL) // For a tag, just force out all the fixups immediately. print_fixups (out, db, branch ? branch->branch_versions : NULL, tag, NULL, s); }
static int compare_changeset (const void * AA, const void * BB) { const changeset_t * A = AA; const changeset_t * B = BB; // We emit implicit merges and branches as soon as they become ready. if (A->type != B->type) return A->type < B->type ? -1 : 1; if (A->time != B->time) return A->time > B->time; // That's all the ordering we really *need* to do, but we try and make // things as deterministic as possible. if (A->type != B->type) return A->type > B->type ? 1 : -1; if (A->type == ct_tag) return strcmp (as_tag (A)->tag, as_tag (B)->tag); const version_t * vA = A->versions[0]; const version_t * vB = B->versions[0]; if (vA->author != vB->author) return strcmp (vA->author, vB->author); if (vA->commitid != vB->commitid) return strcmp (vA->commitid, vB->commitid); if (vA->log != vB->log) return strcmp (vA->log, vB->log); if (vA->branch->tag != vB->branch->tag) return vA->branch->tag < vB->branch->tag ? -1 : 1; assert (vA->implicit_merge == vB->implicit_merge); if (vA->file != vB->file) return vA->file > vB->file; return vA > vB; }
static void filter_output (void * data) { struct filter_context * context = data; size_t seq = 0; for (changeset_t ** p = context->serial; p != context->serial_end; ++p) { // FIXME - some changesets are going to get dropped... We should // pre-compute them and not send to the filter... if ((*p)->type == ct_commit) { printf ("COMMIT %zu %s\n", ++seq, (*p)->versions[0]->branch->tag); continue; } tag_t * tag = as_tag (*p); printf ("%s %zu %s\n", tag->branch_versions ? "BRANCH" : "TAG", ++seq, // FIXME - should refer to commit. tag->tag); } fflush (stdout); }
static void filter_input (database_t * db, FILE * in) { size_t n = 0; char * line = NULL; ssize_t len; while ((len = getline (&line, &n, in)) >= 0) { if (len > 0 && line[len - 1] == '\n') line[--len] = 0; if (len == 0) continue; if (strlen (line) != (size_t) len) fatal ("Line with NUL from filter\n"); if (starts_with (line, "DELETE TAG ")) { tag_t * tag = database_find_tag (db, line + 11); if (tag == NULL) fatal ("Unknown tag from filter: %s\n", line); if (tag->branch_versions != NULL) fatal ("Filter attempts to delete branch: %s\n", line); tag->deleted = true; } else if (starts_with (line, "MERGE ")) { char * ref1 = line + 6; char * ref2 = strchr (ref1, ' '); if (ref2 == NULL) fatal ("Illegal merge from filter: '%s'\n", line); *ref2++ = 0; changeset_t * cs1 = ref_lookup (db, ref1); changeset_t * cs2 = ref_lookup (db, ref2); if (cs2->type == ct_tag) as_tag (cs2)->merge_source = true; ARRAY_APPEND (cs1->merge, cs2); } else fatal ("Unknown line from filter: '%s'\n", line); } xfree (line); }