An svn:externals dir, first checked out onto an already versioned target dir (during update), blows away local modifications.
[[[ (pseudocode) $ svn ls XA/ $ svn diff --- XA/local_file +++ XA/local_file orig +very important local mod $ svn ps svn:externals "^/A XA" . $ svn update D XA/local_file A XA/remote_file svn: warning: W200000: Error handling externals definition for 'XA': svn: warning: W155035: The specified path has an unexpected status At revision 3. svn: E205011: Failure occurred processing one or more externals definitions $ svn diff XA $ svn cat XA/local_file cat: XA/local_file: No such file or directory ]]] The new externals definition switches the already existing dir XA to the external URL ^/A. Probably because of the failing consistency check and its abort, this wipes local modifications from XA/local_file. When producing a similar situation by changing the dir external's URL, local mods result in proper tree conflicts: "local edit, incoming delete/replace upon switch". So the idea is that, hopefully, once above consistency check doesn't abort the operation in this way, the update will just continue to flag such tree conflicts, problem solved. But that got me thinking. It's not so easy to recover local modifications after a conflicted switch -- ever more tree conflicts, manual labor. I would rather error early on this situation. Added weight: since svn:externals may come in from other people, it's not only you who's doing an 'svn switch' in own responsibility. This potentially messes up WCs with a simple 'svn update'. So I'd like to abort the entire dir external update - if there's a versioned dir already, and - if it has local mods anywhere, and - iff the BASE node's URL is different from the URL the dir external wants to bring in at that path. User can still commit / diff to the path's original URL without fuss. This (or as always a revert -R) and a subsequent update would solve any local update situations with dir externals. Do you like the idea & do you think that it's reasonably easy to achieve and backportable? FYI, comparing to file externals: File externals are treated a bit stricter, it seems any existing BASE node's IS_EXTERNAL status is verified before bringing in a file external: [[[ Fetching external item into 'xa': svn: warning: W195017: The file external from 'file:///tmp/switch_thru_external_file.vnT/repos/a' cannot overwrite the existing versioned item at '/tmp/switch_thru_external_file.vnT/wc/xa' ]]] If I change a successfully created file external's URL in the svn:externals prop and update, local mods produce a text conflict. This should probably abort the same way as above. ~Neels
#!/usr/bin/env bash ## TO MAKE THIS RUN YOUR CUSTOM COMPILED SVN, two simple options: ## 1. Adjust your PATH to point at your custom installed location: ## export PATH="$HOME/prefix/svn_trunk/bin:$PATH" ## OR ## 2. Uncomment the four lines below to use aliases into your ## built source tree. The next line is the only line you should ## need to adjust. # SVNDIR=/path/to/built_subversion_source_tree # function svn() { "$SVNDIR/subversion/svn/svn" "$@"; } # function svnserve() { "$SVNDIR/subversion/svnserve/svnserve" "$@"; } # function svnadmin() { "$SVNDIR/subversion/svnadmin/svnadmin" "$@"; } set -e svn --version BASE="$(mktemp -d "/tmp/$(basename "$0").XXX")" echo "BASE = $BASE" REPOS="$BASE/repos" WC="$BASE/wc" URL="file://$REPOS" svnadmin create "$REPOS" svn co -q "$URL" "$WC" set +e set -x cd "$WC" ## ACTUAL TEST mkdir A echo a > A/remote_file svn add A svn ci -mm svn up mkdir XA echo orig > XA/local_file svn add XA svn ci -mm svn info XA | grep '^URL\|^Path' echo very important local mod >> XA/local_file svn st XA svn diff XA svn up svn ls svn ps svn:externals "^/A XA" . svn ci -mm # bring in external XA svn up svn info XA | grep '^URL\|^Path' svn st XA svn diff XA ls XA/ cat XA/local_file # Where is the very important local mod!! ## END set +x echo "BASE = $BASE"
signature.asc
Description: OpenPGP digital signature