# # # add_dir "tests/clone_weird_branch_names" # # add_file "tests/clone_weird_branch_names/__driver__.lua" # content [205c20a2809513b93ee9ab6c1affb24070f284a2] # # patch "cmd_netsync.cc" # from [37c5b5bf5e8989df9e4119dd799f9ffd4b739855] # to [d16b1be50f93f31fbab1eb783eaa494d0e3ccfac] # # patch "globish.cc" # from [23f857decc878f3aa3b87fb9b45eacb69180d6f8] # to [05742d8536befa06b6edfb9a85308e45005375c4] # # patch "globish.hh" # from [93fca3ce5259a69e5ad8020c6d51560a696de54b] # to [d7ed90c535b99ef57cee9390745707ee568cdb1d] # ============================================================ --- globish.cc 23f857decc878f3aa3b87fb9b45eacb69180d6f8 +++ globish.cc 05742d8536befa06b6edfb9a85308e45005375c4 @@ -290,7 +290,7 @@ static string // Debugging. static string -decode(string::const_iterator p, string::const_iterator end) +decode(string::const_iterator p, string::const_iterator end, bool escaped = true) { string s; for (; p != end; p++) @@ -308,11 +308,12 @@ decode(string::const_iterator p, string: case META_ALT_OR: s.push_back(','); break; // Some of these are only special in certain contexts, - // but it does no harm to escape them always. + // so for these contexts we don't want to escape them case '[': case ']': case '-': case '!': case '^': case '{': case '}': case ',': case '*': case '?': case '\\': - s.push_back('\\'); + if (escaped) + s.push_back('\\'); // fall through default: s.push_back(*p); @@ -326,6 +327,12 @@ globish::operator()() const return decode(compiled_pattern.begin(), compiled_pattern.end()); } +string +globish::unescaped() const +{ + return decode(compiled_pattern.begin(), compiled_pattern.end(), false); +} + bool globish::contains_meta_chars() const { ============================================================ --- globish.hh 93fca3ce5259a69e5ad8020c6d51560a696de54b +++ globish.hh d7ed90c535b99ef57cee9390745707ee568cdb1d @@ -59,6 +59,7 @@ struct globish : origin_aware std::vector::const_iterator const & end); std::string operator()(void) const; + std::string unescaped() const; bool contains_meta_chars() const; bool matches(std::string const & target) const; ============================================================ --- cmd_netsync.cc 37c5b5bf5e8989df9e4119dd799f9ffd4b739855 +++ cmd_netsync.cc d16b1be50f93f31fbab1eb783eaa494d0e3ccfac @@ -490,7 +490,7 @@ CMD_NO_WORKSPACE(clone, "clone", "", CMD globish include_pattern = info->client.get_include_pattern(); E(!include_pattern().empty() && !include_pattern.contains_meta_chars(), origin::user, F("you must specify an unambiguous branch to clone")); - app.opts.branch = branch_name(include_pattern(), origin::user); + app.opts.branch = branch_name(include_pattern.unescaped(), origin::user); } I(!app.opts.branch().empty()); ============================================================ --- /dev/null +++ tests/clone_weird_branch_names/__driver__.lua 205c20a2809513b93ee9ab6c1affb24070f284a2 @@ -0,0 +1,15 @@ +skip_if(ostype == "Windows") -- file: not supported on native Win32 + +mtn_setup() + +addfile("foo", "blah blah") +commit("my-branch[1,2]-1^3") + +copy("test.db", "test-clone.db") +-- some of the special chars need to get double-escaped to get "through" +testURI="file://" .. test.root .. "/test-clone.db?my-branch\\\[1,2\\\]-1^3" + +check(nodb_mtn("clone", testURI), 0, false, false) +check(exists("my-branch[1,2]-1^3")) +check(readfile("foo") == readfile("my-branch[1,2]-1^3/foo")) +