First steps to show moved-to and moved-from in 'svn status'. * subversion/include/svn_client.h * subversion/include/svn_wc.h * subversion/libsvn_client/status.c (svn_client_status_dup): (svn_client__create_status): * subversion/libsvn_wc/status.c (assemble_status): (svn_wc_dup_status3): * subversion/svn/status.c (print_status): --This line, and those below, will be ignored-- conf: # dub:/home/neels/pat/.pat-base/config-default conf: http://archive.apache.org/dist/apr/apr-1.4.2.tar.bz2 conf: http://archive.apache.org/dist/apr/apr-util-1.3.9.tar.bz2 conf: http://www.sqlite.org/sqlite-3.6.23.1.tar.gz conf: http://archive.apache.org/dist/httpd/httpd-2.2.15.tar.bz2 conf: http://www.webdav.org/neon/neon-0.29.3.tar.gz conf: http://ftp2.de.freebsd.org/pub/FreeBSD/distfiles/bdb/db-4.8.30.tar.gz conf: ftp://ftp.fu-berlin.de/unix/gnu/libiconv/libiconv-1.13.1.tar.gz conf: fsfs conf: local Index: subversion/include/svn_client.h =================================================================== --- subversion/include/svn_client.h (revision 1156828) +++ subversion/include/svn_client.h (working copy) @@ -2206,6 +2206,18 @@ typedef struct svn_client_status_t * to other data in future versions. */ const void *backwards_compatibility_baton; + /** Set to @c true if this file or directory is scheduled for + * addition-with-history that is part of an explicit move operation (or part + * of a subtree that is scheduled as such). + */ + /** Set to the path (relative to the working copy root) that this node was + * moved from, if this file or directory has been moved here locally. */ + const char *moved_from_relpath; + + /** Set to the path (relative to the working copy root) that this node was + * moved to, if this file or directory has been moved away locally. */ + const char *moved_to_relpath; + /* NOTE! Please update svn_client_status_dup() when adding new fields here. */ } svn_client_status_t; Index: subversion/include/svn_wc.h =================================================================== --- subversion/include/svn_wc.h (revision 1156828) +++ subversion/include/svn_wc.h (working copy) @@ -3619,6 +3619,14 @@ typedef struct svn_wc_status3_t /** @} */ + /* Set to the move source path if this item has been explicitly moved here + * (path relative to the working copy root) */ + const char *moved_from_relpath; + + /* Set to the move destination path if this item has been explicitly moved + * away (path relative to the working copy root) */ + const char *moved_to_relpath; + /* NOTE! Please update svn_wc_dup_status3() when adding new fields here. */ } svn_wc_status3_t; Index: subversion/libsvn_client/status.c =================================================================== --- subversion/libsvn_client/status.c (revision 1156828) +++ subversion/libsvn_client/status.c (working copy) @@ -563,6 +563,12 @@ svn_client_status_dup(const svn_client_s result_pool); } + if (status->moved_from_relpath) + st->moved_from_relpath = apr_pstrdup(result_pool, status->moved_from_relpath); + + if (status->moved_to_relpath) + st->moved_to_relpath = apr_pstrdup(result_pool, status->moved_to_relpath); + return st; } @@ -667,6 +673,9 @@ svn_client__create_status(svn_client_sta (*cst)->node_status = svn_wc_status_conflicted; } + (*cst)->moved_from_relpath = status->moved_from_relpath; + (*cst)->moved_to_relpath = status->moved_to_relpath; + return SVN_NO_ERROR; } Index: subversion/libsvn_wc/status.c =================================================================== --- subversion/libsvn_wc/status.c (revision 1156828) +++ subversion/libsvn_wc/status.c (working copy) @@ -403,6 +403,8 @@ assemble_status(svn_wc_status3_t **statu const char *repos_relpath; const char *repos_root_url; const char *repos_uuid; + const char *moved_from_relpath = NULL; + const char *moved_to_relpath = NULL; svn_filesize_t filesize = (dirent && (dirent->kind == svn_node_file)) ? dirent->filesize : SVN_INVALID_FILESIZE; @@ -608,6 +610,42 @@ assemble_status(svn_wc_status3_t **statu } } + /* Get moved_to info. */ + if (info->status == svn_wc__db_status_deleted) + { + const char *moved_to_abspath = NULL; + SVN_ERR(svn_wc__db_scan_deletion(NULL, + &moved_to_abspath, + NULL, NULL, + db, local_abspath, + result_pool, scratch_pool)); + if (moved_to_abspath) + /* ### This should probably be different, possibly returning a + * ### local_abspath and letting the client construct a pwd-relative + * ### path. */ + SVN_ERR(svn_wc__db_to_relpath(&moved_to_relpath, db, local_abspath, + moved_to_abspath, + result_pool, scratch_pool)); + + } + + /* Get moved_here info. */ + if (info->status == svn_wc__db_status_added) + { + const char *moved_from_abspath = NULL; + SVN_ERR(svn_wc__db_scan_addition(NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + &moved_from_abspath, + NULL, + db, local_abspath, + result_pool, scratch_pool)); + if (moved_from_abspath) + /* ### same as moved_to above */ + SVN_ERR(svn_wc__db_to_relpath(&moved_from_relpath, db, local_abspath, + moved_from_abspath, + result_pool, scratch_pool)); + } + if (node_status == svn_wc_status_normal) node_status = text_status; @@ -700,6 +738,9 @@ assemble_status(svn_wc_status3_t **statu stat->repos_relpath = repos_relpath; stat->repos_uuid = repos_uuid; + stat->moved_from_relpath = moved_from_relpath; + stat->moved_to_relpath = moved_to_relpath; + *status = stat; return SVN_NO_ERROR; @@ -2591,6 +2632,14 @@ svn_wc_dup_status3(const svn_wc_status3_ new_stat->repos_uuid = apr_pstrdup(pool, orig_stat->repos_uuid); + if (orig_stat->moved_from_relpath) + new_stat->moved_from_relpath + = apr_pstrdup(pool, orig_stat->moved_from_relpath); + + if (orig_stat->moved_to_relpath) + new_stat->moved_to_relpath + = apr_pstrdup(pool, orig_stat->moved_to_relpath); + /* Return the new hotness. */ return new_stat; } Index: subversion/svn/status.c =================================================================== --- subversion/svn/status.c (revision 1156828) +++ subversion/svn/status.c (working copy) @@ -143,6 +143,8 @@ print_status(const char *path, enum svn_wc_status_kind prop_status = status->prop_status; char tree_status_code = ' '; const char *tree_desc_line = ""; + const char *moved_from_line = ""; + const char *moved_to_line = ""; /* For historic reasons svn ignores the property status for added nodes, even if these nodes were copied and have local property changes. @@ -211,6 +213,14 @@ print_status(const char *path, (*prop_conflicts)++; } + if (status->moved_from_relpath) + moved_from_line = apr_psprintf(pool, "\n > moved from %s", + status->moved_from_relpath); + + if (status->moved_to_relpath) + moved_to_line = apr_psprintf(pool, "\n> moved to %s", + status->moved_to_relpath); + if (detailed) { char ood_status, lock_status; @@ -273,7 +283,7 @@ print_status(const char *path, SVN_ERR (svn_cmdline_printf(pool, - "%c%c%c%c%c%c%c %c %6s %6s %-12s %s%s\n", + "%c%c%c%c%c%c%c %c %6s %6s %-12s %s%s%s%s\n", generate_status_code(combined_status(status)), generate_status_code(prop_status), status->wc_is_locked ? 'L' : ' ', @@ -286,11 +296,13 @@ print_status(const char *path, commit_rev, commit_author, path, + moved_to_line, + moved_from_line, tree_desc_line)); } else SVN_ERR( - svn_cmdline_printf(pool, "%c%c%c%c%c%c%c %c %6s %s%s\n", + svn_cmdline_printf(pool, "%c%c%c%c%c%c%c %c %6s %s%s%s%s\n", generate_status_code(combined_status(status)), generate_status_code(prop_status), status->wc_is_locked ? 'L' : ' ', @@ -301,11 +313,13 @@ print_status(const char *path, ood_status, working_rev, path, + moved_to_line, + moved_from_line, tree_desc_line)); } else SVN_ERR( - svn_cmdline_printf(pool, "%c%c%c%c%c%c%c %s%s\n", + svn_cmdline_printf(pool, "%c%c%c%c%c%c%c %s%s%s%s\n", generate_status_code(combined_status(status)), generate_status_code(prop_status), status->wc_is_locked ? 'L' : ' ', @@ -315,6 +329,8 @@ print_status(const char *path, ? 'K' : ' '), tree_status_code, path, + moved_to_line, + moved_from_line, tree_desc_line)); return svn_cmdline_fflush(stdout);