868a869,940
> /*checks which order to use when updating source and target without 
>  *  * making changes to any attribute.*/
> static svn_error_t *
> check_order(report_baton_t *b, svn_revnum_t s_rev, const char *s_path,
>              const svn_fs_dirent_t *s_entry, const char *t_path,
>              const svn_fs_dirent_t *t_entry, 
>              const char *e_path, path_info_t *info, svn_depth_t wc_depth,
>              svn_depth_t requested_depth, apr_pool_t *pool, int *error_code)
> {
> 	svn_fs_root_t *s_root;
>   svn_boolean_t related;
>   int distance;
> 	
> 	/* For non-switch operations, follow link_path in the target. */
>   if (info && info->link_path && !b->is_switch)
>     {
>       t_path = info->link_path;
>       SVN_ERR(fake_dirent(&t_entry, b->t_root, t_path, pool));
>     }
> 
>   if (info && !SVN_IS_VALID_REVNUM(info->rev))
>     {
>       /* Delete this entry in the source. */
>       s_path = NULL;
>       s_entry = NULL;
>     }
>   else if (info && s_path)
>     {
>       /* Follow the rev and possibly path in this entry. */
>       s_path = (info->link_path) ? info->link_path : s_path;
>       s_rev = info->rev;
>       SVN_ERR(get_source_root(b, &s_root, s_rev));
>       SVN_ERR(fake_dirent(&s_entry, s_root, s_path, pool));
>     }
> 
>   /* Don't let the report carry us somewhere nonexistent. */
>   if (s_path && !s_entry) {
>     *error_code = 1;
>     return SVN_NO_ERROR;
>   }
>   /* If the source and target both exist and are of the same kind,
>  *      then find out whether they're related.  If they're exactly the
>  *           same, then we don't have to do anything (unless the report has
>  *                changes to the source).  If we're ignoring ancestry, then any two
>  *                     nodes of the same type are related enough for us. */
>   related = FALSE;
>   if (s_entry && t_entry && s_entry->kind == t_entry->kind)
>     {
>       distance = svn_fs_compare_ids(s_entry->id, t_entry->id);
>       if (distance == 0 && !any_path_info(b, e_path)
>           && (!info || (!info->start_empty && !info->lock_token))
>           && (requested_depth <= wc_depth || t_entry->kind == svn_node_file))
>       {
>       	*error_code = 1;
>         return SVN_NO_ERROR;
>       }
>       else if (distance != -1 || b->ignore_ancestry)
>         related = TRUE;
>     }
> 
>   /* If there's a source and it's not related to the target, then it's
>  *    * special! */
>   if (s_entry && !related)
>     {
>       *error_code = 0;
>       return SVN_NO_ERROR;
>     }
>     
>     *error_code = 1;
> 		return SVN_NO_ERROR;
> }
> 
930,932c1002,1004
<            const char *t_path, void *dir_baton, const char *e_path,
<            svn_boolean_t start_empty, svn_depth_t wc_depth,
<            svn_depth_t requested_depth, apr_pool_t *pool)
---
> 	           const char *t_path, void *dir_baton, const char *e_path,
> 	           svn_boolean_t start_empty, svn_depth_t wc_depth,
> 	           svn_depth_t requested_depth, apr_pool_t *pool)
937,1115c1009,1239
<   apr_pool_t *subpool;
<   const svn_fs_dirent_t *s_entry, *t_entry;
<   void *val;
<   const char *name, *s_fullpath, *t_fullpath, *e_fullpath;
<   path_info_t *info;
< 
<   /* Compare the property lists.  If we're starting empty, pass a NULL
<      source path so that we add all the properties.
< 
<      When we support directory locks, we must pass the lock token here. */
<   SVN_ERR(delta_proplists(b, s_rev, start_empty ? NULL : s_path, t_path,
<                           NULL, change_dir_prop, dir_baton, pool));
< 
<   if (requested_depth > svn_depth_empty
<       || requested_depth == svn_depth_unknown)
<     {
<       /* Get the list of entries in each of source and target. */
<       if (s_path && !start_empty)
<         {
<           SVN_ERR(get_source_root(b, &s_root, s_rev));
<           SVN_ERR(svn_fs_dir_entries(&s_entries, s_root, s_path, pool));
<         }
<       SVN_ERR(svn_fs_dir_entries(&t_entries, b->t_root, t_path, pool));
< 
<       /* Iterate over the report information for this directory. */
<       subpool = svn_pool_create(pool);
< 
<       while (1)
<         {
<           svn_pool_clear(subpool);
<           SVN_ERR(fetch_path_info(b, &name, &info, e_path, subpool));
<           if (!name)
<             break;
< 
<           /* Invalid revnum means we should delete, unless this is
<              just an excluded subpath. */
<           if (info 
<               && !SVN_IS_VALID_REVNUM(info->rev)
<               && info->depth != svn_depth_exclude)
<             {
<               /* We want to perform deletes before non-replacement adds,
<                  for graceful handling of case-only renames on
<                  case-insensitive client filesystems.  So, if the report
<                  item is a delete, remove the entry from the source hash,
<                  but don't update the entry yet. */
<               if (s_entries)
<                 apr_hash_set(s_entries, name, APR_HASH_KEY_STRING, NULL);
<               continue;
<             }
< 
<           e_fullpath = svn_path_join(e_path, name, subpool);
<           t_fullpath = svn_path_join(t_path, name, subpool);
<           t_entry = apr_hash_get(t_entries, name, APR_HASH_KEY_STRING);
<           s_fullpath = s_path ? svn_path_join(s_path, name, subpool) : NULL;
<           s_entry = s_entries ?
<             apr_hash_get(s_entries, name, APR_HASH_KEY_STRING) : NULL;
< 
<           /* The only special cases here are
< 
<              - When requested_depth is files but the reported path is
<              a directory.  This is technically a client error, but we
<              handle it anyway, by skipping the entry.
< 
<              - When the reported depth is svn_depth_exclude.
<           */
<           if ((! info || info->depth != svn_depth_exclude)
<               && (requested_depth != svn_depth_files
<                   || ((! t_entry || t_entry->kind != svn_node_dir)
<                       && (! s_entry || s_entry->kind != svn_node_dir))))
<             SVN_ERR(update_entry(b, s_rev, s_fullpath, s_entry, t_fullpath,
<                                  t_entry, dir_baton, e_fullpath, info,
<                                  info ? info->depth
<                                       : DEPTH_BELOW_HERE(wc_depth),
<                                  DEPTH_BELOW_HERE(requested_depth), subpool));
< 
<           /* Don't revisit this name in the target or source entries. */
<           apr_hash_set(t_entries, name, APR_HASH_KEY_STRING, NULL);
<           if (s_entries)
<             apr_hash_set(s_entries, name, APR_HASH_KEY_STRING, NULL);
< 
<           /* pathinfo entries live in their own subpools due to lookahead,
<              so we need to clear each one out as we finish with it. */
<           if (info)
<             svn_pool_destroy(info->pool);
<         }
< 
<       /* Remove any deleted entries.  Do this before processing the
<          target, for graceful handling of case-only renames. */
<       if (s_entries)
<         {
<           for (hi = apr_hash_first(pool, s_entries);
<                hi;
<                hi = apr_hash_next(hi))
<             {
<               svn_pool_clear(subpool);
<               apr_hash_this(hi, NULL, NULL, &val);
<               s_entry = val;
< 
<               if (apr_hash_get(t_entries, s_entry->name,
<                                APR_HASH_KEY_STRING) == NULL)
<                 {
<                   svn_revnum_t deleted_rev;
< 
<                   if (s_entry->kind == svn_node_file
<                       && wc_depth < svn_depth_files)
<                     continue;
< 
<                   if (s_entry->kind == svn_node_dir
<                       && (wc_depth < svn_depth_immediates
<                           || requested_depth == svn_depth_files))
<                     continue;
< 
<                   /* There is no corresponding target entry, so delete. */
<                   e_fullpath = svn_path_join(e_path, s_entry->name, subpool);
<                   SVN_ERR(svn_repos_deleted_rev(svn_fs_root_fs(b->t_root),
<                                                 svn_path_join(t_path,
<                                                               s_entry->name,
<                                                               subpool),
<                                                 s_rev, b->t_rev,
<                                                 &deleted_rev, subpool));
< 
<                   SVN_ERR(b->editor->delete_entry(e_fullpath,
<                                                   deleted_rev,
<                                                   dir_baton, subpool));
<                 }
<             }
<         }
< 
<       /* Loop over the dirents in the target. */
<       for (hi = apr_hash_first(pool, t_entries); hi; hi = apr_hash_next(hi))
<         {
<           svn_pool_clear(subpool);
<           apr_hash_this(hi, NULL, NULL, &val);
<           t_entry = val;
< 
<           if (is_depth_upgrade(wc_depth, requested_depth, t_entry->kind))
<             {
<               /* We're making the working copy deeper, pretend the source
<                  doesn't exist. */
<               s_entry = NULL;
<               s_fullpath = NULL;
<             }
<           else
<             {
<               if (t_entry->kind == svn_node_file
<                   && requested_depth == svn_depth_unknown
<                   && wc_depth < svn_depth_files)
<                 continue;
< 
<               if (t_entry->kind == svn_node_dir
<                   && (wc_depth < svn_depth_immediates
<                       || requested_depth == svn_depth_files))
<                 continue;
< 
<               /* Look for an entry with the same name
<                  in the source dirents. */
<               s_entry = s_entries ?
<                   apr_hash_get(s_entries, t_entry->name, APR_HASH_KEY_STRING)
<                   : NULL;
<               s_fullpath = s_entry ?
<                   svn_path_join(s_path, t_entry->name, subpool) : NULL;
<             }
< 
<           /* Compose the report, editor, and target paths for this entry. */
<           e_fullpath = svn_path_join(e_path, t_entry->name, subpool);
<           t_fullpath = svn_path_join(t_path, t_entry->name, subpool);
< 
<           SVN_ERR(update_entry(b, s_rev, s_fullpath, s_entry, t_fullpath,
<                                t_entry, dir_baton, e_fullpath, NULL,
<                                DEPTH_BELOW_HERE(wc_depth),
<                                DEPTH_BELOW_HERE(requested_depth),
<                                subpool));
<         }
< 
< 
<       /* Destroy iteration subpool. */
<       svn_pool_destroy(subpool);
<     }
<   return SVN_NO_ERROR;
---
> 	  apr_pool_t *subpool, *subpool_special;
> 	  const svn_fs_dirent_t *s_entry, *t_entry;
> 	  void *val;
> 	  const char *name, *s_fullpath, *t_fullpath, *e_fullpath;
> 	  path_info_t *info;
> 	  /*order variable, if it's 0 then the entry is special
> 	   * and should be deleted at the very end*/
> 	  int order = 1;
> 		/*Here we save the entries to be deleted later(renaming)*/
> 		apr_array_header_t *special_entries;
> 		int ARRAY_INIT_SZ = 32;
> 		int i;
> 		  
> 	  /*Initialize the special pool and special_entries*/
> 	  subpool_special = svn_pool_create(pool);
> 	  special_entries = apr_array_make(subpool_special, ARRAY_INIT_SZ, sizeof(const char*));
> 	  
> 	  /* Compare the property lists.  If we're starting empty, pass a NULL
> 	     source path so that we add all the properties.
> 	
> 	     When we support directory locks, we must pass the lock token here. */
> 	  SVN_ERR(delta_proplists(b, s_rev, start_empty ? NULL : s_path, t_path,
> 	                          NULL, change_dir_prop, dir_baton, pool));
> 	
> 	  if (requested_depth > svn_depth_empty
> 	      || requested_depth == svn_depth_unknown)
> 	    {
> 	      /* Get the list of entries in each of source and target. */
> 	      if (s_path && !start_empty)
> 	        {
> 	          SVN_ERR(get_source_root(b, &s_root, s_rev));
> 	          SVN_ERR(svn_fs_dir_entries(&s_entries, s_root, s_path, pool));
> 	        }
> 	      SVN_ERR(svn_fs_dir_entries(&t_entries, b->t_root, t_path, pool));
> 				
> 				/* Iterate over the report information for this directory. */
> 	      subpool = svn_pool_create(pool);
> 				
> 	      while (1)
> 	        {
> 	          svn_pool_clear(subpool);
> 	          
> 	          SVN_ERR(fetch_path_info(b, &name, &info, e_path, subpool));//changes name and info
> 	          
> 	          if (!name)
> 	            break;
> 	
> 	          /* Invalid revnum means we should delete, unless this is
> 	             just an excluded subpath. */
> 	          if (info 
> 	              && !SVN_IS_VALID_REVNUM(info->rev)
> 	              && info->depth != svn_depth_exclude)
> 	            {
> 	              /* We want to perform deletes before non-replacement adds,
> 	                 for graceful handling of case-only renames on
> 	                 case-insensitive client filesystems.  So, if the report
> 	                 item is a delete, remove the entry from the source hash,
> 	                 but don't update the entry yet. */
> 	              if (s_entries)
> 	                apr_hash_set(s_entries, name, APR_HASH_KEY_STRING, NULL);
> 	              continue;
> 	            }
> 	
> 	          e_fullpath = svn_path_join(e_path, name, subpool);
> 	          t_fullpath = svn_path_join(t_path, name, subpool);
> 	          t_entry = apr_hash_get(t_entries, name, APR_HASH_KEY_STRING);
> 	          s_fullpath = s_path ? svn_path_join(s_path, name, subpool) : NULL;
> 	          s_entry = s_entries ?
> 	            apr_hash_get(s_entries, name, APR_HASH_KEY_STRING) : NULL;
> 	
> 	          /* The only special cases here are
> 	
> 	             - When requested_depth is files but the reported path is
> 	             a directory.  This is technically a client error, but we
> 	             handle it anyway, by skipping the entry.
> 	
> 	             - When the reported depth is svn_depth_exclude.
> 	          
> 	          	here if we check if the entry is to be deleted
> 	           * because it's going to be replace, then we can put that 
> 	           * special entry in an array or something so we can later 
> 	           * update it(delte it) after updating the target!
> 	           */
> 	          if ((! info || info->depth != svn_depth_exclude)
> 	              && (requested_depth != svn_depth_files
> 	              || ((! t_entry || t_entry->kind != svn_node_dir)
> 	              && (! s_entry || s_entry->kind != svn_node_dir))))
> 	              {
> 	              	SVN_ERR(check_order(b, s_rev, s_fullpath, s_entry, t_fullpath,
> 	                    	             t_entry, e_fullpath, info,
> 	                      	           info ? info->depth
> 	                        	              : DEPTH_BELOW_HERE(wc_depth),
> 	                          	       DEPTH_BELOW_HERE(requested_depth), subpool, &order));
> 	            		/*Here if the order is 0 then the entry is to be replaced(copy on update)
> 	            		 * We should save the entry till the end where we will remove it!*/
> 	            		if(order == 0)
> 	            		{
> 	            			*(const char**)apr_array_push(special_entries) = apr_pstrdup(subpool_special, name);
> 	            			continue;
> 	            		}
> 	            		order = -1;
> 	            		SVN_ERR(update_entry(b, s_rev, s_fullpath, s_entry, t_fullpath,
> 	                                 t_entry, dir_baton, e_fullpath, info,
> 	                                 info ? info->depth
> 	                                      : DEPTH_BELOW_HERE(wc_depth),
> 	                                 DEPTH_BELOW_HERE(requested_depth), subpool));
> 	              }
> 	          /* Don't revisit this name in the target or source entries. */
> 	          apr_hash_set(t_entries, name, APR_HASH_KEY_STRING, NULL);
> 	          if (s_entries)
> 	            apr_hash_set(s_entries, name, APR_HASH_KEY_STRING, NULL);
> 	
> 	          /* pathinfo entries live in their own subpools due to lookahead,
> 	             so we need to clear each one out as we finish with it. */
> 	          if (info)
> 	            svn_pool_destroy(info->pool);
> 	        	}
> 	
> 	      /* Remove any deleted entries.  Do this before processing the
> 	         target, for graceful handling of case-only renames. */
> 	      if (s_entries)
> 	        {
> 	          for (hi = apr_hash_first(pool, s_entries);
> 	               hi;
> 	               hi = apr_hash_next(hi))
> 	            {
> 	              svn_pool_clear(subpool);
> 	              apr_hash_this(hi, NULL, NULL, &val);
> 	              s_entry = val;
> 								fprintf(stderr, "Names of dirents: %s\n", s_entry->name);
> 	              if (apr_hash_get(t_entries, s_entry->name,
> 	                               APR_HASH_KEY_STRING) == NULL)
> 	                {
> 	                  svn_revnum_t deleted_rev;
> 	
> 	                  if (s_entry->kind == svn_node_file
> 	                      && wc_depth < svn_depth_files)
> 	                    continue;
> 	
> 	                  if (s_entry->kind == svn_node_dir
> 	                      && (wc_depth < svn_depth_immediates
> 	                          || requested_depth == svn_depth_files))
> 	                    continue;
> 	
> 	                  /* There is no corresponding target entry, so delete. */
> 	                  e_fullpath = svn_path_join(e_path, s_entry->name, subpool);
> 	                  SVN_ERR(svn_repos_deleted_rev(svn_fs_root_fs(b->t_root),
> 	                                                svn_path_join(t_path,
> 	                                                              s_entry->name,
> 	                                                              subpool),
> 	                                                s_rev, b->t_rev,
> 	                                                &deleted_rev, subpool));
> 	
> 	                  SVN_ERR(b->editor->delete_entry(e_fullpath,
> 	                                                  deleted_rev,
> 	                                                  dir_baton, subpool));
> 	                }
> 	            }
> 	        }
> 	
> 	      /* Loop over the dirents in the target. */
> 	      for (hi = apr_hash_first(pool, t_entries); hi; hi = apr_hash_next(hi))
> 	        {
> 	          svn_pool_clear(subpool);
> 	          apr_hash_this(hi, NULL, NULL, &val);
> 	          t_entry = val;
> 	
> 	          if (is_depth_upgrade(wc_depth, requested_depth, t_entry->kind))
> 	            {
> 	              /* We're making the working copy deeper, pretend the source
> 	                 doesn't exist. */
> 	              s_entry = NULL;
> 	              s_fullpath = NULL;
> 	            }
> 	          else
> 	            {
> 	              if (t_entry->kind == svn_node_file
> 	                  && requested_depth == svn_depth_unknown
> 	                  && wc_depth < svn_depth_files)
> 	                continue;
> 	
> 	              if (t_entry->kind == svn_node_dir
> 	                  && (wc_depth < svn_depth_immediates
> 	                      || requested_depth == svn_depth_files))
> 	                continue;
> 	
> 	              /* Look for an entry with the same name
> 	                 in the source dirents. */
> 	              s_entry = s_entries ?
> 	                  apr_hash_get(s_entries, t_entry->name, APR_HASH_KEY_STRING)
> 	                  : NULL;
> 	              s_fullpath = s_entry ?
> 	                  svn_path_join(s_path, t_entry->name, subpool) : NULL;
> 	            }
> 	
> 	          /* Compose the report, editor, and target paths for this entry. */
> 	          e_fullpath = svn_path_join(e_path, t_entry->name, subpool);
> 	          t_fullpath = svn_path_join(t_path, t_entry->name, subpool);
> 	
> 	          SVN_ERR(update_entry(b, s_rev, s_fullpath, s_entry, t_fullpath,
> 	                               t_entry, dir_baton, e_fullpath, NULL,
> 	                               DEPTH_BELOW_HERE(wc_depth),
> 	                               DEPTH_BELOW_HERE(requested_depth),
> 	                               subpool));
> 	        }
> 	
> 				/*Here the special entries are updated(DELETED)*/
> 				for (i = 0; i < special_entries->nelts; i++) 
> 				{
> 	        const char *s = ((const char**)special_entries->elts)[i];
> 	        svn_revnum_t deleted_special_rev;
> 	        e_fullpath = svn_path_join(e_path, s, subpool);
> 	        
> 	        svn_pool_clear(subpool);
> 	        SVN_ERR(svn_repos_deleted_rev(svn_fs_root_fs(b->t_root),
> 	                                       svn_path_join(t_path,
> 	                                       s,
> 	                                       subpool),
> 	                                       s_rev, b->t_rev,
> 	                                       &deleted_special_rev, subpool));
> 	
> 	         SVN_ERR(b->editor->delete_entry(e_fullpath,
> 	                 deleted_special_rev,
> 	                 dir_baton, subpool));
> 	      }
> 	      /* Destroy iteration subpool. */
> 	      svn_pool_destroy(subpool);
> 	    }
> 	  
> 	  svn_pool_destroy(subpool_special);
> 	  return SVN_NO_ERROR;
