You don't need 'immediate_parent_path' as it is scoped outside, it will
retain the last iteration path only.

>+ for (hi = apr_hash_first(NULL, skipped_parents); hi;

>+ hi = apr_hash_next(hi))

>+ {

>+ apr_hash_index_t *child_hi;

>+ apr_hash_t *child_entries;

>+ const void *parent_path;

>+

Spurious space(TAB) here.

>+ for (child_hi = apr_hash_first(NULL, child_entries); child_hi;

>+ child_hi = apr_hash_next(child_hi))

>+ {

>+ const void *child_path;

>+

>+ apr_hash_this(child_hi, &child_path, NULL, NULL);

>+ child_path = svn_path_join((const char *)parent_path,

>+ (const char *)child_path, pool);

>+

You need to ignore the "THIS_ENTRY".

>+ /* If child path is present in the merges hash table, then

>+ it has been assigned EMPTY or MERGE_RANGES as mergeinfo

>+ previously */

>+ if (!apr_hash_get(*merges, child_path, APR_HASH_KEY_STRING))

>+ {

>+ if (svn_path_compare_paths(immediate_parent_path,

>+ child_path))

This check is *bogus* as 'immediate_parent_path' is the last skipped
paths' dirname which is something we should not bother about, I hope
your intension about this block of code is to handle "THIS_ENTRY" which
you can handle outside.
You may need to take care of deleted child before setting mergeinfo. i.e
if B/E/alpha is getting skipped due to 'scheduled deletion of B/E', Your
code set's a mergeinfo on 'B/E' which is illogical.