svn_error_t * svn_fs_fs__dag_get_revision(svn_revnum_t *rev, dag_node_t *node, apr_pool_t *pool) { /* In the special case that this is an unmodified transaction root, we need to actually get the revision of the noderev's predecessor (the revision root); see Issue #2608. */ const svn_fs_id_t *correct_id = node->fresh_root_predecessor_id ? node->fresh_root_predecessor_id : node->id; /* Look up the committed revision from the Node-ID. */ *rev = svn_fs_fs__id_rev(correct_id); return SVN_NO_ERROR; }
svn_error_t * svn_fs_fs__read_noderev(node_revision_t **noderev_p, svn_stream_t *stream, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { apr_hash_t *headers; node_revision_t *noderev; char *value; const char *noderev_id; SVN_ERR(read_header_block(&headers, stream, scratch_pool)); noderev = apr_pcalloc(result_pool, sizeof(*noderev)); /* Read the node-rev id. */ value = svn_hash_gets(headers, HEADER_ID); if (value == NULL) /* ### More information: filename/offset coordinates */ return svn_error_create(SVN_ERR_FS_CORRUPT, NULL, _("Missing id field in node-rev")); SVN_ERR(svn_stream_close(stream)); SVN_ERR(svn_fs_fs__id_parse(&noderev->id, value, result_pool)); noderev_id = value; /* for error messages later */ /* Read the type. */ value = svn_hash_gets(headers, HEADER_TYPE); if ((value == NULL) || ( strcmp(value, SVN_FS_FS__KIND_FILE) && strcmp(value, SVN_FS_FS__KIND_DIR))) /* ### s/kind/type/ */ return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL, _("Missing kind field in node-rev '%s'"), noderev_id); noderev->kind = (strcmp(value, SVN_FS_FS__KIND_FILE) == 0) ? svn_node_file : svn_node_dir; /* Read the 'count' field. */ value = svn_hash_gets(headers, HEADER_COUNT); if (value) SVN_ERR(svn_cstring_atoi(&noderev->predecessor_count, value)); else noderev->predecessor_count = 0; /* Get the properties location. */ value = svn_hash_gets(headers, HEADER_PROPS); if (value) { SVN_ERR(read_rep_offsets(&noderev->prop_rep, value, noderev->id, result_pool, scratch_pool)); } /* Get the data location. */ value = svn_hash_gets(headers, HEADER_TEXT); if (value) { SVN_ERR(read_rep_offsets(&noderev->data_rep, value, noderev->id, result_pool, scratch_pool)); } /* Get the created path. */ value = svn_hash_gets(headers, HEADER_CPATH); if (value == NULL) { return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL, _("Missing cpath field in node-rev '%s'"), noderev_id); } else { if (!svn_fspath__is_canonical(value)) return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL, _("Non-canonical cpath field in node-rev '%s'"), noderev_id); noderev->created_path = apr_pstrdup(result_pool, value); } /* Get the predecessor ID. */ value = svn_hash_gets(headers, HEADER_PRED); if (value) SVN_ERR(svn_fs_fs__id_parse(&noderev->predecessor_id, value, result_pool)); /* Get the copyroot. */ value = svn_hash_gets(headers, HEADER_COPYROOT); if (value == NULL) { noderev->copyroot_path = apr_pstrdup(result_pool, noderev->created_path); noderev->copyroot_rev = svn_fs_fs__id_rev(noderev->id); } else { SVN_ERR(parse_revnum(&noderev->copyroot_rev, (const char **)&value)); if (!svn_fspath__is_canonical(value)) return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL, _("Malformed copyroot line in node-rev '%s'"), noderev_id); noderev->copyroot_path = apr_pstrdup(result_pool, value); } /* Get the copyfrom. */ value = svn_hash_gets(headers, HEADER_COPYFROM); if (value == NULL) { noderev->copyfrom_path = NULL; noderev->copyfrom_rev = SVN_INVALID_REVNUM; } else { SVN_ERR(parse_revnum(&noderev->copyfrom_rev, (const char **)&value)); if (*value == 0) return svn_error_createf(SVN_ERR_FS_CORRUPT, NULL, _("Malformed copyfrom line in node-rev '%s'"), noderev_id); noderev->copyfrom_path = apr_pstrdup(result_pool, value); } /* Get whether this is a fresh txn root. */ value = svn_hash_gets(headers, HEADER_FRESHTXNRT); noderev->is_fresh_txn_root = (value != NULL); /* Get the mergeinfo count. */ value = svn_hash_gets(headers, HEADER_MINFO_CNT); if (value) SVN_ERR(svn_cstring_atoi64(&noderev->mergeinfo_count, value)); else noderev->mergeinfo_count = 0; /* Get whether *this* node has mergeinfo. */ value = svn_hash_gets(headers, HEADER_MINFO_HERE); noderev->has_mergeinfo = (value != NULL); *noderev_p = noderev; return SVN_NO_ERROR; }
svn_error_t * svn_fs_fs__write_noderev(svn_stream_t *outfile, node_revision_t *noderev, int format, svn_boolean_t include_mergeinfo, apr_pool_t *scratch_pool) { SVN_ERR(svn_stream_printf(outfile, scratch_pool, HEADER_ID ": %s\n", svn_fs_fs__id_unparse(noderev->id, scratch_pool)->data)); SVN_ERR(svn_stream_printf(outfile, scratch_pool, HEADER_TYPE ": %s\n", (noderev->kind == svn_node_file) ? SVN_FS_FS__KIND_FILE : SVN_FS_FS__KIND_DIR)); if (noderev->predecessor_id) SVN_ERR(svn_stream_printf(outfile, scratch_pool, HEADER_PRED ": %s\n", svn_fs_fs__id_unparse(noderev->predecessor_id, scratch_pool)->data)); SVN_ERR(svn_stream_printf(outfile, scratch_pool, HEADER_COUNT ": %d\n", noderev->predecessor_count)); if (noderev->data_rep) SVN_ERR(svn_stream_printf(outfile, scratch_pool, HEADER_TEXT ": %s\n", svn_fs_fs__unparse_representation (noderev->data_rep, format, noderev->kind == svn_node_dir, scratch_pool, scratch_pool)->data)); if (noderev->prop_rep) SVN_ERR(svn_stream_printf(outfile, scratch_pool, HEADER_PROPS ": %s\n", svn_fs_fs__unparse_representation (noderev->prop_rep, format, TRUE, scratch_pool, scratch_pool)->data)); SVN_ERR(svn_stream_printf(outfile, scratch_pool, HEADER_CPATH ": %s\n", noderev->created_path)); if (noderev->copyfrom_path) SVN_ERR(svn_stream_printf(outfile, scratch_pool, HEADER_COPYFROM ": %ld" " %s\n", noderev->copyfrom_rev, noderev->copyfrom_path)); if ((noderev->copyroot_rev != svn_fs_fs__id_rev(noderev->id)) || (strcmp(noderev->copyroot_path, noderev->created_path) != 0)) SVN_ERR(svn_stream_printf(outfile, scratch_pool, HEADER_COPYROOT ": %ld" " %s\n", noderev->copyroot_rev, noderev->copyroot_path)); if (noderev->is_fresh_txn_root) SVN_ERR(svn_stream_puts(outfile, HEADER_FRESHTXNRT ": y\n")); if (include_mergeinfo) { if (noderev->mergeinfo_count > 0) SVN_ERR(svn_stream_printf(outfile, scratch_pool, HEADER_MINFO_CNT ": %" APR_INT64_T_FMT "\n", noderev->mergeinfo_count)); if (noderev->has_mergeinfo) SVN_ERR(svn_stream_puts(outfile, HEADER_MINFO_HERE ": y\n")); } return svn_stream_puts(outfile, "\n"); }
/* Inspect the data and/or prop reps of revision REVNUM in FS. Store * reference count tallies in passed hashes (allocated in RESULT_POOL). * * If PROP_REPS or DATA_REPS is NULL, the respective kind of reps are not * tallied. * * Print progress report to STDERR unless QUIET is true. * * Use SCRATCH_POOL for temporary allocations. */ static svn_error_t * process_one_revision(svn_fs_t *fs, svn_revnum_t revnum, svn_boolean_t quiet, apr_hash_t *prop_reps, apr_hash_t *data_reps, apr_hash_t *both_reps, apr_pool_t *result_pool, apr_pool_t *scratch_pool) { svn_fs_root_t *rev_root; apr_hash_t *paths_changed; apr_hash_index_t *hi; if (! quiet) SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool, "processing r%ld\n", revnum)); /* Get the changed paths. */ SVN_ERR(svn_fs_revision_root(&rev_root, fs, revnum, scratch_pool)); SVN_ERR(svn_fs_paths_changed2(&paths_changed, rev_root, scratch_pool)); /* Iterate them. */ /* ### use iterpool? */ for (hi = apr_hash_first(scratch_pool, paths_changed); hi; hi = apr_hash_next(hi)) { const char *path; const svn_fs_path_change2_t *change; const svn_fs_id_t *node_rev_id1, *node_rev_id2; const svn_fs_id_t *the_id; node_revision_t *node_rev; path = svn__apr_hash_index_key(hi); change = svn__apr_hash_index_val(hi); if (! quiet) SVN_ERR(svn_cmdline_fprintf(stderr, scratch_pool, "processing r%ld:%s\n", revnum, path)); if (change->change_kind == svn_fs_path_change_delete) /* Can't ask for reps of PATH at REVNUM if the path no longer exists * at that revision! */ continue; /* Okay, we have two node_rev id's for this change: the txn one and * the revision one. We'll use the latter. */ node_rev_id1 = change->node_rev_id; SVN_ERR(svn_fs_node_id(&node_rev_id2, rev_root, path, scratch_pool)); SVN_ERR_ASSERT(svn_fs_fs__id_txn_id(node_rev_id1) != NULL); SVN_ERR_ASSERT(svn_fs_fs__id_rev(node_rev_id2) != SVN_INVALID_REVNUM); the_id = node_rev_id2; /* Get the node_rev using the chosen node_rev_id. */ SVN_ERR(svn_fs_fs__get_node_revision(&node_rev, fs, the_id, scratch_pool)); /* Maybe record the sha1's. */ SVN_ERR(record(prop_reps, node_rev->prop_rep, result_pool)); SVN_ERR(record(data_reps, node_rev->data_rep, result_pool)); SVN_ERR(record(both_reps, node_rev->prop_rep, result_pool)); SVN_ERR(record(both_reps, node_rev->data_rep, result_pool)); } return SVN_NO_ERROR; }