Tests: clean up and document submodule helpers
[gitweb.git] / builtin / worktree.c
index c98e2ce5f57c1f41ccaf90041a1a22233ae75551..ed043d5f1c0a107fb0650de826c0e5aea0fe165e 100644 (file)
@@ -38,7 +38,9 @@ static int prune_worktree(const char *id, struct strbuf *reason)
 {
        struct stat st;
        char *path;
-       int fd, len;
+       int fd;
+       size_t len;
+       ssize_t read_result;
 
        if (!is_directory(git_path("worktrees/%s", id))) {
                strbuf_addf(reason, _("Removing worktrees/%s: not a valid directory"), id);
@@ -56,10 +58,26 @@ static int prune_worktree(const char *id, struct strbuf *reason)
                            id, strerror(errno));
                return 1;
        }
-       len = st.st_size;
+       len = xsize_t(st.st_size);
        path = xmallocz(len);
-       read_in_full(fd, path, len);
+
+       read_result = read_in_full(fd, path, len);
+       if (read_result < 0) {
+               strbuf_addf(reason, _("Removing worktrees/%s: unable to read gitdir file (%s)"),
+                           id, strerror(errno));
+               close(fd);
+               free(path);
+               return 1;
+       }
        close(fd);
+
+       if (read_result != len) {
+               strbuf_addf(reason,
+                           _("Removing worktrees/%s: short read (expected %"PRIuMAX" bytes, read %"PRIuMAX")"),
+                           id, (uintmax_t)len, (uintmax_t)read_result);
+               free(path);
+               return 1;
+       }
        while (len && (path[len - 1] == '\n' || path[len - 1] == '\r'))
                len--;
        if (!len) {
@@ -381,6 +399,8 @@ static int add(int ac, const char **av, const char *prefix)
                branch = opts.new_branch;
        }
 
+       UNLEAK(path);
+       UNLEAK(opts);
        return add_worktree(path, branch, &opts);
 }
 
@@ -390,7 +410,7 @@ static void show_worktree_porcelain(struct worktree *wt)
        if (wt->is_bare)
                printf("bare\n");
        else {
-               printf("HEAD %s\n", sha1_to_hex(wt->head_sha1));
+               printf("HEAD %s\n", oid_to_hex(&wt->head_oid));
                if (wt->is_detached)
                        printf("detached\n");
                else if (wt->head_ref)
@@ -410,7 +430,7 @@ static void show_worktree(struct worktree *wt, int path_maxlen, int abbrev_len)
                strbuf_addstr(&sb, "(bare)");
        else {
                strbuf_addf(&sb, "%-*s ", abbrev_len,
-                               find_unique_abbrev(wt->head_sha1, DEFAULT_ABBREV));
+                               find_unique_abbrev(wt->head_oid.hash, DEFAULT_ABBREV));
                if (wt->is_detached)
                        strbuf_addstr(&sb, "(detached HEAD)");
                else if (wt->head_ref) {
@@ -435,7 +455,7 @@ static void measure_widths(struct worktree **wt, int *abbrev, int *maxlen)
 
                if (path_len > *maxlen)
                        *maxlen = path_len;
-               sha1_len = strlen(find_unique_abbrev(wt[i]->head_sha1, *abbrev));
+               sha1_len = strlen(find_unique_abbrev(wt[i]->head_oid.hash, *abbrev));
                if (sha1_len > *abbrev)
                        *abbrev = sha1_len;
        }