Junio C Hamano <gitster@xxxxxxxxx> writes: > Denton Liu <liu.denton@xxxxxxxxx> writes: > >> - new_branch_info->name = arg; >> + new_branch_info->name = strstr(arg, "...") ? >> + xstrdup(oid_to_hex(rev)) : >> + arg; > > Can we do better? > > I am not sure why we want to hardcode the knowledge of "..." syntax > like this here. "git checkout A...B" introduced in 2009 needed only > a single-liner change from get_sha1() to get_sha1_mb() without making > the ugly implementation detail seep into this layer. I _think_ what you are trying to work around is that a syntax that is not understood as a reference to a single revision by get_oid() but is understood as such by get_oid_mb() can be in the .name field, and that eventually gets passed to branch.c::create_branch() as "start_name" in the codepath. The function ought to know that start_name wants to name a single revision and never a revision range, but fails to use get_oid_mb() but just a plain get_oid(), and fails. If that is the case, wouldn't a better fix be more like the attached? This hasn't even been compile tested, but I suspect that without taking this approach, you would introduce a new "bug", namely, that $ git checkout -b newbranch master... ought to behave exactly like $ git branch newbranch master... $ git checkout newbranch But the first step would hit the same branch.c::create_branch() and would not work, no? The reason I care about hiding syntax details like "..." from users of get_*_mb() is because I anticipate that we'll want to extend it to things other than just "merge base between two" with syntax different from "..." (while probably renaming _mb suffix to something else). The codebase is not ready to replace get_oid() with get_oid_mb() blindly and wholesale, I think, as the former is used as an implementation detail of parsing range syntax like A..B but places that are end user facing *and* expect to take only a single revision (e.g. "rebase --onto <commit>", "checkout <commit>", etc.) and never a range that currently use get_oid() should be able to get replaced with get_oid_mb() to learn "A...B means their merge base, not a symmetric range" semantics for free. branch.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/branch.c b/branch.c index 28b81a7e02..a84c8aaca2 100644 --- a/branch.c +++ b/branch.c @@ -268,7 +268,7 @@ void create_branch(struct repository *r, } real_ref = NULL; - if (get_oid(start_name, &oid)) { + if (get_oid_mb(start_name, &oid)) { if (explicit_tracking) { if (advice_set_upstream_failure) { error(_(upstream_missing), start_name);