* Remove empty parent directories associated with the specified * reference and/or its reflog, but spare [logs/]refs/ and immediate * subdirs. flags is a combination of REMOVE_EMPTY_PARENTS_REF and/or * REMOVE_EMPTY_PARENTS_REFLOG. */
| 1275 | * REMOVE_EMPTY_PARENTS_REFLOG. |
| 1276 | */ |
| 1277 | static void try_remove_empty_parents(struct files_ref_store *refs, |
| 1278 | const char *refname, |
| 1279 | unsigned int flags) |
| 1280 | { |
| 1281 | struct strbuf buf = STRBUF_INIT; |
| 1282 | struct strbuf sb = STRBUF_INIT; |
| 1283 | char *p, *q; |
| 1284 | int i; |
| 1285 | |
| 1286 | strbuf_addstr(&buf, refname); |
| 1287 | p = buf.buf; |
| 1288 | for (i = 0; i < 2; i++) { /* refs/{heads,tags,...}/ */ |
| 1289 | while (*p && *p != '/') |
| 1290 | p++; |
| 1291 | /* tolerate duplicate slashes; see check_refname_format() */ |
| 1292 | while (*p == '/') |
| 1293 | p++; |
| 1294 | } |
| 1295 | q = buf.buf + buf.len; |
| 1296 | while (flags & (REMOVE_EMPTY_PARENTS_REF | REMOVE_EMPTY_PARENTS_REFLOG)) { |
| 1297 | while (q > p && *q != '/') |
| 1298 | q--; |
| 1299 | while (q > p && *(q-1) == '/') |
| 1300 | q--; |
| 1301 | if (q == p) |
| 1302 | break; |
| 1303 | strbuf_setlen(&buf, q - buf.buf); |
| 1304 | |
| 1305 | strbuf_reset(&sb); |
| 1306 | files_ref_path(refs, &sb, buf.buf); |
| 1307 | if ((flags & REMOVE_EMPTY_PARENTS_REF) && rmdir(sb.buf)) |
| 1308 | flags &= ~REMOVE_EMPTY_PARENTS_REF; |
| 1309 | |
| 1310 | strbuf_reset(&sb); |
| 1311 | files_reflog_path(refs, &sb, buf.buf); |
| 1312 | if ((flags & REMOVE_EMPTY_PARENTS_REFLOG) && rmdir(sb.buf)) |
| 1313 | flags &= ~REMOVE_EMPTY_PARENTS_REFLOG; |
| 1314 | } |
| 1315 | strbuf_release(&buf); |
| 1316 | strbuf_release(&sb); |
| 1317 | } |
| 1318 | |
| 1319 | /* make sure nobody touched the ref, and unlink */ |
| 1320 | static void prune_ref(struct files_ref_store *refs, struct ref_to_prune *r) |
no test coverage detected