📄 questions.c
字号:
const svn_wc_entry_t *entry;
SVN_ERR (svn_wc_entry (&entry, versioned_file, adm_access, TRUE, pool));
SVN_ERR (svn_wc_translated_file (&tmp_vfile, versioned_file, adm_access,
TRUE, pool));
/* Compare the files, while calculating the base file's checksum. */
{
/* "v_" means versioned_file, "b_" means base_file. */
svn_error_t *v_err = SVN_NO_ERROR;
svn_error_t *b_err = SVN_NO_ERROR;
apr_size_t v_file_bytes_read, b_file_bytes_read;
char v_buf[BUFSIZ], b_buf[BUFSIZ];
apr_file_t *v_file_h = NULL;
apr_file_t *b_file_h = NULL;
apr_pool_t *loop_pool;
int identical = TRUE;
unsigned char digest[APR_MD5_DIGESTSIZE];
apr_md5_ctx_t context;
const char *checksum;
SVN_ERR (svn_io_file_open (&v_file_h, tmp_vfile,
APR_READ, APR_OS_DEFAULT, pool));
SVN_ERR (svn_io_file_open (&b_file_h, base_file, APR_READ, APR_OS_DEFAULT,
pool));
apr_md5_init (&context);
loop_pool = svn_pool_create (pool);
do
{
svn_pool_clear (loop_pool);
/* The only way v_err can be true here is if we hit EOF. */
if (! v_err)
{
v_err = svn_io_file_read_full (v_file_h, v_buf, sizeof(v_buf),
&v_file_bytes_read, loop_pool);
if (v_err && !APR_STATUS_IS_EOF(v_err->apr_err))
return v_err;
}
b_err = svn_io_file_read_full (b_file_h, b_buf, sizeof(b_buf),
&b_file_bytes_read, loop_pool);
if (b_err && !APR_STATUS_IS_EOF(b_err->apr_err))
return b_err;
apr_md5_update (&context, b_buf, b_file_bytes_read);
if ((v_err && (! b_err))
|| (v_file_bytes_read != b_file_bytes_read)
|| (memcmp (v_buf, b_buf, v_file_bytes_read)))
{
identical = FALSE;
}
} while (! b_err);
svn_pool_destroy (loop_pool);
/* Clear any errors, but don't set the error variables to null, as
we still depend on them for conditionals. */
svn_error_clear (v_err);
svn_error_clear (b_err);
SVN_ERR (svn_io_file_close (v_file_h, pool));
SVN_ERR (svn_io_file_close (b_file_h, pool));
apr_md5_final (digest, &context);
checksum = svn_md5_digest_to_cstring (digest, pool);
if (entry->checksum && strcmp (checksum, entry->checksum) != 0)
{
return svn_error_createf
(SVN_ERR_WC_CORRUPT_TEXT_BASE, NULL,
_("Checksum mismatch indicates corrupt text base: '%s'\n"
" expected: %s\n"
" actual: %s\n"),
base_file, entry->checksum, checksum);
}
*modified_p = ! identical;
}
if (tmp_vfile != versioned_file)
err2 = svn_io_remove_file (tmp_vfile, pool);
if (err)
{
if (err2)
svn_error_compose (err, err2);
return err;
}
return err2;
}
svn_error_t *
svn_wc_text_modified_p (svn_boolean_t *modified_p,
const char *filename,
svn_boolean_t force_comparison,
svn_wc_adm_access_t *adm_access,
apr_pool_t *pool)
{
const char *textbase_filename;
svn_boolean_t equal_timestamps;
apr_pool_t *subpool = svn_pool_create (pool);
svn_node_kind_t kind;
/* Sanity check: if the path doesn't exist, return FALSE. */
SVN_ERR (svn_io_check_path (filename, &kind, subpool));
if (kind != svn_node_file)
{
*modified_p = FALSE;
goto cleanup;
}
if (! force_comparison)
{
/* See if the local file's timestamp is the same as the one
recorded in the administrative directory. This could,
theoretically, be wrong in certain rare cases, but with the
addition of a forced delay after commits (see revision 419
and issue #542) it's highly unlikely to be a problem. */
SVN_ERR (svn_wc__timestamps_equal_p (&equal_timestamps,
filename, adm_access,
svn_wc__text_time, subpool));
if (equal_timestamps)
{
*modified_p = FALSE;
goto cleanup;
}
}
/* If there's no text-base file, we have to assume the working file
is modified. For example, a file scheduled for addition but not
yet committed. */
textbase_filename = svn_wc__text_base_path (filename, 0, subpool);
SVN_ERR (svn_io_check_path (textbase_filename, &kind, subpool));
if (kind != svn_node_file)
{
*modified_p = TRUE;
goto cleanup;
}
if (force_comparison) /* Check all bytes, and verify checksum. */
{
SVN_ERR (compare_and_verify (modified_p,
filename,
adm_access,
textbase_filename,
subpool));
}
else /* Else, fall back on the standard mod detector. */
{
SVN_ERR (svn_wc__versioned_file_modcheck (modified_p,
filename,
adm_access,
textbase_filename,
subpool));
}
/* It is quite legitimate for modifications to the working copy to
produce a timestamp variation with no text variation. If it turns out
that there are no differences then we might be able to "repair" the
text-time in the entries file and so avoid the expensive file contents
comparison in the future. */
if (! *modified_p && svn_wc_adm_locked (adm_access))
{
svn_wc_entry_t tmp;
SVN_ERR (svn_io_file_affected_time (&tmp.text_time, filename, pool));
SVN_ERR (svn_wc__entry_modify (adm_access,
svn_path_basename (filename, pool),
&tmp, SVN_WC__ENTRY_MODIFY_TEXT_TIME, TRUE,
pool));
}
cleanup:
svn_pool_destroy (subpool);
return SVN_NO_ERROR;
}
svn_error_t *
svn_wc_conflicted_p (svn_boolean_t *text_conflicted_p,
svn_boolean_t *prop_conflicted_p,
const char *dir_path,
const svn_wc_entry_t *entry,
apr_pool_t *pool)
{
const char *path;
svn_node_kind_t kind;
apr_pool_t *subpool = svn_pool_create (pool); /* ### Why? */
*text_conflicted_p = FALSE;
*prop_conflicted_p = FALSE;
/* Look for any text conflict, exercising only as much effort as
necessary to obtain a definitive answer. This only applies to
files, but we don't have to explicitly check that entry is a
file, since these attributes would never be set on a directory
anyway. A conflict file entry notation only counts if the
conflict file still exists on disk. */
if (entry->conflict_old)
{
path = svn_path_join (dir_path, entry->conflict_old, subpool);
SVN_ERR (svn_io_check_path (path, &kind, subpool));
if (kind == svn_node_file)
*text_conflicted_p = TRUE;
}
if ((! *text_conflicted_p) && (entry->conflict_new))
{
path = svn_path_join (dir_path, entry->conflict_new, subpool);
SVN_ERR (svn_io_check_path (path, &kind, subpool));
if (kind == svn_node_file)
*text_conflicted_p = TRUE;
}
if ((! *text_conflicted_p) && (entry->conflict_wrk))
{
path = svn_path_join (dir_path, entry->conflict_wrk, subpool);
SVN_ERR (svn_io_check_path (path, &kind, subpool));
if (kind == svn_node_file)
*text_conflicted_p = TRUE;
}
/* What about prop conflicts? */
if (entry->prejfile)
{
path = svn_path_join (dir_path, entry->prejfile, subpool);
SVN_ERR (svn_io_check_path (path, &kind, subpool));
if (kind == svn_node_file)
*prop_conflicted_p = TRUE;
}
svn_pool_destroy (subpool);
return SVN_NO_ERROR;
}
svn_error_t *
svn_wc_has_binary_prop (svn_boolean_t *has_binary_prop,
const char *path,
svn_wc_adm_access_t *adm_access,
apr_pool_t *pool)
{
const svn_string_t *value;
apr_pool_t *subpool = svn_pool_create (pool);
SVN_ERR (svn_wc_prop_get (&value, SVN_PROP_MIME_TYPE, path, adm_access,
subpool));
if (value && (svn_mime_type_is_binary (value->data)))
*has_binary_prop = TRUE;
else
*has_binary_prop = FALSE;
svn_pool_destroy (subpool);
return SVN_NO_ERROR;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -