branch: improve error log on branch not found by checking remotes refs

New git users may want to locally delete remote-tracking branches but don't really understand how they are distinguished from branches by git. Then one may naively try: `git branch -d foo/bar` and get a correct error `branch foo/bar not found` but hard to understand for a newbie, this patch aims to guide one in such case. when failing to delete a branch with `git branch -d <branch>` because of branch not found, try to find a **remote refs** matching `<branch>` and if so, add an hint: `Did you forget --remote?` to the error message Signed-off-by: Clement Mabileau <mabileau.clement@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Clement Mabileau committed Apr 5, 2023 at 11:43 UTC 4c643fb321db00a9c79e2dcd1fd033681333584b
1 file changed +21 -4
builtin/branch.c
+21 -4
@@ -216,10 +216,11 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,
216 struct string_list refs_to_delete = STRING_LIST_INIT_DUP;
217 struct string_list_item *item;
218 int branch_name_pos;
219 + const char *fmt_remotes = "refs/remotes/%s";
220
221 switch (kinds) {
222 case FILTER_REFS_REMOTES:
222 - fmt = "refs/remotes/%s";
223 + fmt = fmt_remotes;
224 /* For subsequent UI messages */
225 remote_branch = 1;
226 allowed_interpret = INTERPRET_BRANCH_REMOTE;
@@ -263,9 +264,25 @@ static int delete_branches(int argc, const char **argv, int force, int kinds,
264 | RESOLVE_REF_ALLOW_BAD_NAME,
265 &oid, &flags);
266 if (!target) {
266 - error(remote_branch
267 - ? _("remote-tracking branch '%s' not found.")
268 - : _("branch '%s' not found."), bname.buf);
267 + if (remote_branch) {
268 + error(_("remote-tracking branch '%s' not found."), bname.buf);
269 + } else {
270 + char *virtual_name = mkpathdup(fmt_remotes, bname.buf);
271 + char *virtual_target = resolve_refdup(virtual_name,
272 + RESOLVE_REF_READING
273 + | RESOLVE_REF_NO_RECURSE
274 + | RESOLVE_REF_ALLOW_BAD_NAME,
275 + &oid, &flags);
276 + FREE_AND_NULL(virtual_name);
277 +
278 + if (virtual_target)
279 + error(_("branch '%s' not found.\n"
280 + "Did you forget --remote?"),
281 + bname.buf);
282 + else
283 + error(_("branch '%s' not found."), bname.buf);
284 + FREE_AND_NULL(virtual_target);
285 + }
286 ret = 1;
287 continue;
288 }