strbuf_rtrim(sb);
        strbuf_ltrim(sb);
 }
+
 void strbuf_rtrim(struct strbuf *sb)
 {
        while (sb->len > 0 && isspace((unsigned char)sb->buf[sb->len - 1]))
        sb->buf[sb->len] = '\0';
 }
 
+void strbuf_trim_trailing_dir_sep(struct strbuf *sb)
+{
+       while (sb->len > 0 && is_dir_sep((unsigned char)sb->buf[sb->len - 1]))
+               sb->len--;
+       sb->buf[sb->len] = '\0';
+}
+
 void strbuf_ltrim(struct strbuf *sb)
 {
        char *b = sb->buf;
 {
        int fd;
        ssize_t len;
+       int saved_errno;
 
        fd = open(path, O_RDONLY);
        if (fd < 0)
                return -1;
        len = strbuf_read(sb, fd, hint);
+       saved_errno = errno;
        close(fd);
-       if (len < 0)
+       if (len < 0) {
+               errno = saved_errno;
                return -1;
+       }
 
        return len;
 }
        strbuf_setlen(sb, sb->len + len);
 }
 
-void strbuf_add_unique_abbrev(struct strbuf *sb, const unsigned char *sha1,
+void strbuf_add_unique_abbrev(struct strbuf *sb, const struct object_id *oid,
                              int abbrev_len)
 {
        int r;
        strbuf_grow(sb, GIT_SHA1_HEXSZ + 1);
-       r = find_unique_abbrev_r(sb->buf + sb->len, sha1, abbrev_len);
+       r = find_unique_abbrev_r(sb->buf + sb->len, oid, abbrev_len);
        strbuf_setlen(sb, sb->len + r);
 }