📄 diff.c
字号:
case svn_node_dir:
if (entry->schedule == svn_wc_schedule_replace)
{
/* ### TODO: Don't know how to do this bit. How do I get
information about what is being replaced? If it was a
directory then the directory elements are also going to be
deleted. We need to show deletion diffs for these
files. If it was a file we need to show a deletion diff
for that file. */
}
/* Check the subdir if in the anchor (the subdir is the target), or
if recursive */
if (in_anchor_not_target || dir_baton->edit_baton->recurse)
{
subdir_baton = make_dir_baton (path, dir_baton,
dir_baton->edit_baton,
FALSE,
subpool);
SVN_ERR (directory_elements_diff (subdir_baton, added));
}
break;
default:
break;
}
svn_pool_clear (subpool);
}
svn_pool_destroy (subpool);
return SVN_NO_ERROR;
}
/* An editor function. */
static svn_error_t *
set_target_revision (void *edit_baton,
svn_revnum_t target_revision,
apr_pool_t *pool)
{
struct edit_baton *eb = edit_baton;
eb->revnum = target_revision;
return SVN_NO_ERROR;
}
/* An editor function. The root of the comparison hierarchy */
static svn_error_t *
open_root (void *edit_baton,
svn_revnum_t base_revision,
apr_pool_t *dir_pool,
void **root_baton)
{
struct edit_baton *eb = edit_baton;
struct dir_baton *b;
eb->root_opened = TRUE;
b = make_dir_baton (eb->anchor_path, NULL, eb, FALSE, dir_pool);
*root_baton = b;
return SVN_NO_ERROR;
}
/* An editor function. */
static svn_error_t *
delete_entry (const char *path,
svn_revnum_t base_revision,
void *parent_baton,
apr_pool_t *pool)
{
struct dir_baton *pb = parent_baton;
struct edit_baton *eb = pb->edit_baton;
const svn_wc_entry_t *entry;
struct dir_baton *b;
const char *full_path = svn_path_join (pb->edit_baton->anchor_path, path,
pb->pool);
svn_wc_adm_access_t *adm_access;
const char *working_mimetype, *pristine_mimetype;
SVN_ERR (svn_wc_adm_probe_retrieve (&adm_access, pb->edit_baton->anchor,
full_path, pool));
SVN_ERR (svn_wc_entry (&entry, full_path, adm_access, FALSE, pool));
switch (entry->kind)
{
case svn_node_file:
/* A delete is required to change working-copy into requested
revision, so diff should show this as an add. Thus compare
the empty file against the current working copy. If
'reverse_order' is set, then show a deletion. */
SVN_ERR (get_local_mimetypes (&pristine_mimetype, &working_mimetype,
NULL, adm_access, full_path, pool));
if (eb->reverse_order)
{
/* Whenever showing a deletion, we show the text-base vanishing. */
const char *textbase = svn_wc__text_base_path (full_path,
FALSE, pool);
SVN_ERR (pb->edit_baton->callbacks->file_deleted
(NULL, NULL, full_path,
textbase,
svn_wc__empty_file_path (full_path, pool),
pristine_mimetype,
NULL,
pb->edit_baton->callback_baton));
}
else
{
/* Or normally, show the working file being added. */
SVN_ERR (pb->edit_baton->callbacks->file_added
(NULL, NULL, full_path,
svn_wc__empty_file_path (full_path, pool),
full_path,
0, entry->revision,
NULL,
working_mimetype,
pb->edit_baton->callback_baton));
}
apr_hash_set (pb->compared, full_path, APR_HASH_KEY_STRING, "");
break;
case svn_node_dir:
b = make_dir_baton (full_path, pb, pb->edit_baton, FALSE, pool);
/* A delete is required to change working-copy into requested
revision, so diff should show this as and add. Thus force the
directory diff to treat this as added. */
SVN_ERR (directory_elements_diff (b, TRUE));
break;
default:
break;
}
return SVN_NO_ERROR;
}
/* An editor function. */
static svn_error_t *
add_directory (const char *path,
void *parent_baton,
const char *copyfrom_path,
svn_revnum_t copyfrom_revision,
apr_pool_t *dir_pool,
void **child_baton)
{
struct dir_baton *pb = parent_baton;
struct dir_baton *b;
const char *full_path;
/* ### TODO: support copyfrom? */
full_path = svn_path_join (pb->edit_baton->anchor_path, path, dir_pool);
b = make_dir_baton (full_path, pb, pb->edit_baton, TRUE, dir_pool);
*child_baton = b;
return SVN_NO_ERROR;
}
/* An editor function. */
static svn_error_t *
open_directory (const char *path,
void *parent_baton,
svn_revnum_t base_revision,
apr_pool_t *dir_pool,
void **child_baton)
{
struct dir_baton *pb = parent_baton;
struct dir_baton *b;
const char *full_path;
/* Allocate path from the parent pool since the memory is used in the
parent's compared hash */
full_path = svn_path_join (pb->edit_baton->anchor_path, path, pb->pool);
b = make_dir_baton (full_path, pb, pb->edit_baton, FALSE, dir_pool);
*child_baton = b;
return SVN_NO_ERROR;
}
/* An editor function. When a directory is closed, all the directory
* elements that have been added or replaced will already have been
* diff'd. However there may be other elements in the working copy
* that have not yet been considered. */
static svn_error_t *
close_directory (void *dir_baton,
apr_pool_t *pool)
{
struct dir_baton *b = dir_baton;
/* Skip added directories, they can only contain added elements all of
which have already been diff'd. */
if (!b->added)
SVN_ERR (directory_elements_diff (dir_baton, FALSE));
/* Mark this directory as compared in the parent directory's baton. */
if (b->dir_baton)
{
apr_hash_set (b->dir_baton->compared, b->path, APR_HASH_KEY_STRING,
"");
}
if (b->propchanges->nelts > 0)
{
if (! b->edit_baton->reverse_order)
reverse_propchanges (b->baseprops, b->propchanges, b->pool);
SVN_ERR (b->edit_baton->callbacks->props_changed
(NULL, NULL,
b->path,
b->propchanges,
b->baseprops,
b->edit_baton->callback_baton));
}
return SVN_NO_ERROR;
}
/* An editor function. */
static svn_error_t *
add_file (const char *path,
void *parent_baton,
const char *copyfrom_path,
svn_revnum_t copyfrom_revision,
apr_pool_t *file_pool,
void **file_baton)
{
struct dir_baton *pb = parent_baton;
struct file_baton *b;
const char *full_path;
/* ### TODO: support copyfrom? */
full_path = svn_path_join (pb->edit_baton->anchor_path, path, file_pool);
b = make_file_baton (full_path, TRUE, pb, file_pool);
*file_baton = b;
/* Add this filename to the parent directory's list of elements that
have been compared. */
apr_hash_set (pb->compared, apr_pstrdup(pb->pool, full_path),
APR_HASH_KEY_STRING, "");
return SVN_NO_ERROR;
}
/* An editor function. */
static svn_error_t *
open_file (const char *path,
void *parent_baton,
svn_revnum_t base_revision,
apr_pool_t *file_pool,
void **file_baton)
{
struct dir_baton *pb = parent_baton;
struct file_baton *b;
const char *full_path;
full_path = svn_path_join (pb->edit_baton->anchor_path, path, file_pool);
b = make_file_baton (full_path, FALSE, pb, file_pool);
*file_baton = b;
/* Add this filename to the parent directory's list of elements that
have been compared. */
apr_hash_set (pb->compared, apr_pstrdup(pb->pool, full_path),
APR_HASH_KEY_STRING, "");
return SVN_NO_ERROR;
}
/* This is an apr cleanup handler. It is called whenever the associated
* pool is cleared or destroyed. It is installed when the temporary file is
* created, and removes the file when the file pool is deleted, whether in
* the normal course of events, or if an error occurs.
*
* ARG is the file baton for the working copy file associated with the
* temporary file.
*/
static apr_status_t
temp_file_cleanup_handler (void *arg)
{
struct file_baton *b = arg;
svn_error_t *err;
apr_status_t status;
/* The path to the temporary copy of the pristine repository version. */
const char *temp_file_path
= svn_wc__text_base_path (b->wc_path, TRUE, b->pool);
err = svn_io_remove_file (temp_file_path, b->pool);
if (err)
{
status = err->apr_err;
svn_error_clear (err);
}
else
status = APR_SUCCESS;
return status;
}
/* This removes the temp_file_cleanup_handler in the child process before
* exec'ing diff.
*/
static apr_status_t
temp_file_cleanup_handler_remover (void *arg)
{
struct file_baton *b = arg;
apr_pool_cleanup_kill (b->pool, b, temp_file_cleanup_handler);
return APR_SUCCESS;
}
/* An editor function. Do the work of applying the text delta. */
static svn_error_t *
window_handler (svn_txdelta_window_t *window,
void *window_baton)
{
struct file_baton *b = window_baton;
SVN_ERR (b->apply_handler (window, b->apply_baton));
if (!window)
{
SVN_ERR (svn_wc__close_text_base (b->temp_file, b->wc_path, 0, b->pool));
if (b->added)
{
SVN_ERR (svn_wc__close_empty_file (b->original_file, b->wc_path,
b->pool));
}
else
{
SVN_ERR (svn_wc__close_text_base (b->original_file, b->wc_path, 0,
b->pool));
}
}
return SVN_NO_ERROR;
}
/* An editor function. */
static svn_error_t *
apply_textdelta (void *file_baton,
const char *base_checksum,
apr_pool_t *pool,
svn_txdelta_window_handler_t *handler,
void **handler_baton)
{
struct file_baton *b = file_baton;
struct edit_baton *eb = b->edit_baton;
const svn_wc_entry_t *entry;
SVN_ERR (svn_wc_entry (&entry, b->wc_path, eb->anchor, FALSE, b->pool));
/* Check to see if there is a schedule-add with history entry in
the current working copy. If so, then this is not actually
an add, but instead a modification.*/
if (entry && entry->copyfrom_url)
b->added = FALSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -