diff --git a/include/git2/refs.h b/include/git2/refs.h
index 5395ded..2073aab 100644
--- a/include/git2/refs.h
+++ b/include/git2/refs.h
@@ -33,6 +33,17 @@ GIT_BEGIN_DECL
 GIT_EXTERN(int) git_reference_lookup(git_reference **reference_out, git_repository *repo, const char *name);
 
 /**
+ * Lookup a reference by name and resolve immediately to OID.
+ *
+ * @param oid Pointer to oid to be filled in
+ * @param repo The repository in which to look up the reference
+ * @param name The long name for the reference
+ * @return 0 on success, -1 if name could not be resolved
+ */
+GIT_EXTERN(int) git_reference_name_to_oid(
+	git_oid *out, git_repository *repo, const char *name);
+
+/**
  * Create a new symbolic reference.
  *
  * The reference will be created in the repository and written
@@ -304,6 +315,15 @@ GIT_EXTERN(int) git_reference_reload(git_reference *ref);
  */
 GIT_EXTERN(void) git_reference_free(git_reference *ref);
 
+/**
+ * Compare two references.
+ *
+ * @param ref1 The first git_reference
+ * @param ref2 The second git_reference
+ * @return GIT_SUCCESS if the same, else a stable but meaningless ordering.
+ */
+GIT_EXTERN(int) git_reference_cmp(git_reference *ref1, git_reference *ref2);
+
 /** @} */
 GIT_END_DECL
 #endif
diff --git a/src/netops.c b/src/netops.c
index 2d759fd..e2fec0b 100644
--- a/src/netops.c
+++ b/src/netops.c
@@ -46,7 +46,7 @@ static void net_set_error(const char *str)
 }
 #endif
 
-void gitno_buffer_setup(gitno_buffer *buf, char *data, unsigned int len, int fd)
+void gitno_buffer_setup(gitno_buffer *buf, char *data, unsigned int len, GIT_SOCKET fd)
 {
 	memset(buf, 0x0, sizeof(gitno_buffer));
 	memset(data, 0x0, len);
@@ -60,17 +60,13 @@ int gitno_recv(gitno_buffer *buf)
 {
 	int ret;
 
-	ret = recv(buf->fd, buf->data + buf->offset, buf->len - buf->offset, 0);
-	if (ret == 0) /* Orderly shutdown, so exit */
-		return 0;
-
+	ret = p_recv(buf->fd, buf->data + buf->offset, buf->len - buf->offset, 0);
 	if (ret < 0) {
-		net_set_error("Error receiving data");
+		net_set_error("Error receiving socket data");
 		return -1;
 	}
 
 	buf->offset += ret;
-
 	return ret;
 }
 
@@ -97,12 +93,12 @@ void gitno_consume_n(gitno_buffer *buf, size_t cons)
 	buf->offset -= cons;
 }
 
-int gitno_connect(const char *host, const char *port)
+GIT_SOCKET gitno_connect(const char *host, const char *port)
 {
-	struct addrinfo *info, *p;
+	struct addrinfo *info = NULL, *p;
 	struct addrinfo hints;
 	int ret;
-	GIT_SOCKET s;
+	GIT_SOCKET s = INVALID_SOCKET;
 
 	memset(&hints, 0x0, sizeof(struct addrinfo));
 	hints.ai_family = AF_UNSPEC;
@@ -110,36 +106,30 @@ int gitno_connect(const char *host, const char *port)
 
 	if ((ret = getaddrinfo(host, port, &hints, &info)) < 0) {
 		giterr_set(GITERR_NET, "Failed to resolve address for %s: %s", host, gai_strerror(ret));
-		return -1;
+		return INVALID_SOCKET;
 	}
 
 	for (p = info; p != NULL; p = p->ai_next) {
 		s = socket(p->ai_family, p->ai_socktype, p->ai_protocol);
-#ifdef GIT_WIN32
 		if (s == INVALID_SOCKET) {
-#else
-		if (s < 0) {
-#endif
-			net_set_error("Error creating socket");
-			freeaddrinfo(info);
-			return -1;
+			net_set_error("error creating socket");
+			break;
 		}
 
-		ret = connect(s, p->ai_addr, p->ai_addrlen);
-		/* If we can't connect, try the next one */
-		if (ret < 0) {
-			close(s);
-			continue;
-		}
+		if (connect(s, p->ai_addr, (socklen_t)p->ai_addrlen) == 0)
+			break;
 
-		/* Return the socket */
-		freeaddrinfo(info);
-		return s;
+		/* If we can't connect, try the next one */
+		gitno_close(s);
+		s = INVALID_SOCKET;
 	}
 
 	/* Oops, we couldn't connect to any address */
-	giterr_set(GITERR_OS, "Failed to connect to %s", host);
-	return -1;
+	if (s == INVALID_SOCKET && p == NULL)
+		giterr_set(GITERR_OS, "Failed to connect to %s", host);
+
+	freeaddrinfo(info);
+	return s;
 }
 
 int gitno_send(GIT_SOCKET s, const char *msg, size_t len, int flags)
@@ -150,7 +140,7 @@ int gitno_send(GIT_SOCKET s, const char *msg, size_t len, int flags)
 	while (off < len) {
 		errno = 0;
 
-		ret = send(s, msg + off, len - off, flags);
+		ret = p_send(s, msg + off, len - off, flags);
 		if (ret < 0) {
 			net_set_error("Error sending data");
 			return -1;
@@ -159,7 +149,7 @@ int gitno_send(GIT_SOCKET s, const char *msg, size_t len, int flags)
 		off += ret;
 	}
 
-	return off;
+	return (int)off;
 }
 
 
@@ -187,7 +177,7 @@ int gitno_select_in(gitno_buffer *buf, long int sec, long int usec)
 	FD_SET(buf->fd, &fds);
 
 	/* The select(2) interface is silly */
-	return select(buf->fd + 1, &fds, NULL, NULL, &tv);
+	return select((int)buf->fd + 1, &fds, NULL, NULL, &tv);
 }
 
 int gitno_extract_host_and_port(char **host, char **port, const char *url, const char *default_port)
@@ -198,8 +188,8 @@ int gitno_extract_host_and_port(char **host, char **port, const char *url, const
 	slash = strchr(url, '/');
 
 	if (slash == NULL) {
-			giterr_set(GITERR_NET, "Malformed URL: missing /");
-			return -1;
+		giterr_set(GITERR_NET, "Malformed URL: missing /");
+		return -1;
 	}
 
 	if (colon == NULL) {
diff --git a/src/netops.h b/src/netops.h
index 01ad971..f370019 100644
--- a/src/netops.h
+++ b/src/netops.h
@@ -7,11 +7,7 @@
 #ifndef INCLUDE_netops_h__
 #define INCLUDE_netops_h__
 
-#ifndef GIT_WIN32
-typedef int GIT_SOCKET;
-#else
-typedef SOCKET GIT_SOCKET;
-#endif
+#include "posix.h"
 
 typedef struct gitno_buffer {
 	char *data;
@@ -20,12 +16,12 @@ typedef struct gitno_buffer {
 	GIT_SOCKET fd;
 } gitno_buffer;
 
-void gitno_buffer_setup(gitno_buffer *buf, char *data, unsigned int len, int fd);
+void gitno_buffer_setup(gitno_buffer *buf, char *data, unsigned int len, GIT_SOCKET fd);
 int gitno_recv(gitno_buffer *buf);
 void gitno_consume(gitno_buffer *buf, const char *ptr);
 void gitno_consume_n(gitno_buffer *buf, size_t cons);
 
-int gitno_connect(const char *host, const char *port);
+GIT_SOCKET gitno_connect(const char *host, const char *port);
 int gitno_send(GIT_SOCKET s, const char *msg, size_t len, int flags);
 int gitno_close(GIT_SOCKET s);
 int gitno_send_chunk_size(int s, size_t len);
diff --git a/src/odb_pack.c b/src/odb_pack.c
index 1a1fa55..b91e3ca 100644
--- a/src/odb_pack.c
+++ b/src/odb_pack.c
@@ -212,7 +212,7 @@ static int packfile_load__cb(void *_data, git_buf *path)
 	struct pack_backend *backend = (struct pack_backend *)_data;
 	struct git_pack_file *pack;
 	int error;
-	size_t i;
+	unsigned int i;
 
 	if (git__suffixcmp(path->ptr, ".idx") != 0)
 		return 0; /* not an index */
@@ -266,7 +266,7 @@ static int packfile_refresh_all(struct pack_backend *backend)
 static int pack_entry_find(struct git_pack_entry *e, struct pack_backend *backend, const git_oid *oid)
 {
 	int error;
-	size_t i;
+	unsigned int i;
 
 	if ((error = packfile_refresh_all(backend)) < 0)
 		return error;
@@ -298,7 +298,7 @@ static int pack_entry_find_prefix(
 	unsigned int len)
 {
 	int error;
-	size_t i;
+	unsigned int i;
 	unsigned found = 0;
 
 	if ((error = packfile_refresh_all(backend)) < 0)
@@ -423,7 +423,7 @@ static int pack_backend__exists(git_odb_backend *backend, const git_oid *oid)
 static void pack_backend__free(git_odb_backend *_backend)
 {
 	struct pack_backend *backend;
-	size_t i;
+	unsigned int i;
 
 	assert(_backend);
 
diff --git a/src/oid.c b/src/oid.c
index 7f0a520..d072f0f 100644
--- a/src/oid.c
+++ b/src/oid.c
@@ -260,6 +260,8 @@ git_oid_shorten *git_oid_shorten_new(size_t min_length)
 {
 	git_oid_shorten *os;
 
+	assert((size_t)((int)min_length) == min_length);
+
 	os = git__calloc(1, sizeof(git_oid_shorten));
 	if (os == NULL)
 		return NULL;
@@ -270,7 +272,7 @@ git_oid_shorten *git_oid_shorten_new(size_t min_length)
 	}
 
 	os->node_count = 1;
-	os->min_length = min_length;
+	os->min_length = (int)min_length;
 
 	return os;
 }
@@ -328,7 +330,8 @@ void git_oid_shorten_free(git_oid_shorten *os)
  */
 int git_oid_shorten_add(git_oid_shorten *os, const char *text_oid)
 {
-	int i, is_leaf;
+	int i;
+	bool is_leaf;
 	node_index idx;
 
 	if (os->full)
@@ -338,7 +341,7 @@ int git_oid_shorten_add(git_oid_shorten *os, const char *text_oid)
 		return os->min_length;
 
 	idx = 0;
-	is_leaf = 0;
+	is_leaf = false;
 
 	for (i = 0; i < GIT_OID_HEXSZ; ++i) {
 		int c = git__fromhex(text_oid[i]);
@@ -368,11 +371,11 @@ int git_oid_shorten_add(git_oid_shorten *os, const char *text_oid)
 		}
 
 		idx = node->children[c];
-		is_leaf = 0;
+		is_leaf = false;
 
 		if (idx < 0) {
 			node->children[c] = idx = -idx;
-			is_leaf = 1;
+			is_leaf = true;
 		}
 	}
 
diff --git a/src/pack.c b/src/pack.c
index b79ecf4..8d71138 100644
--- a/src/pack.c
+++ b/src/pack.c
@@ -165,6 +165,7 @@ static int pack_index_open(struct git_pack_file *p)
 {
 	char *idx_name;
 	int error;
+	size_t name_len, offset;
 
 	if (p->index_map.data)
 		return 0;
@@ -172,7 +173,11 @@ static int pack_index_open(struct git_pack_file *p)
 	idx_name = git__strdup(p->pack_name);
 	GITERR_CHECK_ALLOC(idx_name);
 
-	strcpy(idx_name + strlen(idx_name) - strlen(".pack"), ".idx");
+	name_len = strlen(idx_name);
+	offset = name_len - strlen(".pack");
+	assert(offset < name_len); /* make sure no underflow */
+
+	strncpy(idx_name + offset, ".idx", name_len - offset);
 
 	error = pack_index_check(idx_name, p);
 	git__free(idx_name);
@@ -501,7 +506,7 @@ git_off_t get_delta_base(
  *
  ***********************************************************/
 
-static struct git_pack_file *packfile_alloc(int extra)
+static struct git_pack_file *packfile_alloc(size_t extra)
 {
 	struct git_pack_file *p = git__calloc(1, sizeof(*p) + extra);
 	if (p != NULL)
diff --git a/src/path.c b/src/path.c
index 3c1a723..a7cf440 100644
--- a/src/path.c
+++ b/src/path.c
@@ -464,21 +464,22 @@ int git_path_find_dir(git_buf *dir, const char *path, const char *base)
 	return error;
 }
 
-int git_path_cmp(const char *name1, int len1, int isdir1,
-		const char *name2, int len2, int isdir2)
+int git_path_cmp(
+	const char *name1, size_t len1, int isdir1,
+	const char *name2, size_t len2, int isdir2)
 {
-	int len = len1 < len2 ? len1 : len2;
+	size_t len = len1 < len2 ? len1 : len2;
 	int cmp;
 
 	cmp = memcmp(name1, name2, len);
 	if (cmp)
 		return cmp;
 	if (len1 < len2)
-		return ((!isdir1 && !isdir2) ? -1 :
-						(isdir1 ? '/' - name2[len1] : name2[len1] - '/'));
+		return (!isdir1 && !isdir2) ? -1 :
+			(isdir1 ? '/' - name2[len1] : name2[len1] - '/');
 	if (len1 > len2)
-		return ((!isdir1 && !isdir2) ? 1 :
-						(isdir2 ? name1[len2] - '/' : '/' - name1[len2]));
+		return (!isdir1 && !isdir2) ? 1 :
+			(isdir2 ? name1[len2] - '/' : '/' - name1[len2]);
 	return 0;
 }
 
diff --git a/src/path.h b/src/path.h
index eb397d1..fd76805 100644
--- a/src/path.h
+++ b/src/path.h
@@ -204,8 +204,8 @@ extern int git_path_direach(
  * Sort function to order two paths.
  */
 extern int git_path_cmp(
-	const char *name1, int len1, int isdir1,
-	const char *name2, int len2, int isdir2);
+	const char *name1, size_t len1, int isdir1,
+	const char *name2, size_t len2, int isdir2);
 
 /**
  * Invoke callback up path directory by directory until the ceiling is
diff --git a/src/pkt.c b/src/pkt.c
index f8af7e2..ee113cd 100644
--- a/src/pkt.c
+++ b/src/pkt.c
@@ -102,6 +102,7 @@ static int comment_pkt(git_pkt **out, const char *line, size_t len)
  */
 static int ref_pkt(git_pkt **out, const char *line, size_t len)
 {
+	int error;
 	git_pkt_ref *pkt;
 
 	pkt = git__malloc(sizeof(git_pkt_ref));
@@ -109,14 +110,13 @@ static int ref_pkt(git_pkt **out, const char *line, size_t len)
 
 	memset(pkt, 0x0, sizeof(git_pkt_ref));
 	pkt->type = GIT_PKT_REF;
-	if (git_oid_fromstr(&pkt->head.oid, line) < 0) {
-		giterr_set(GITERR_NET, "Error parsing pkt-line");
+	if ((error = git_oid_fromstr(&pkt->head.oid, line)) < 0)
 		goto error_out;
-	}
 
 	/* Check for a bit of consistency */
 	if (line[GIT_OID_HEXSZ] != ' ') {
 		giterr_set(GITERR_NET, "Error parsing pkt-line");
+		error = -1;
 		goto error_out;
 	}
 
@@ -138,30 +138,32 @@ static int ref_pkt(git_pkt **out, const char *line, size_t len)
 	}
 
 	*out = (git_pkt *)pkt;
-
 	return 0;
 
 error_out:
 	git__free(pkt);
-	return -1;
+	return error;
 }
 
-static int parse_len(const char *line)
+static int32_t parse_len(const char *line)
 {
 	char num[PKT_LEN_SIZE + 1];
-	int i, len;
+	int i, error;
+	int32_t len;
 	const char *num_end;
 
 	memcpy(num, line, PKT_LEN_SIZE);
 	num[PKT_LEN_SIZE] = '\0';
 
 	for (i = 0; i < PKT_LEN_SIZE; ++i) {
-		if (!isxdigit(num[i]))
-			return GIT_ENOTNUM;
+		if (!isxdigit(num[i])) {
+			giterr_set(GITERR_NET, "Found invalid hex digit in length");
+			return -1;
+		}
 	}
 
-	if (git__strtol32(&len, num, &num_end, 16) < 0)
-		return -1;
+	if ((error = git__strtol32(&len, num, &num_end, 16)) < 0)
+		return error;
 
 	return len;
 }
@@ -179,16 +181,20 @@ static int parse_len(const char *line)
  * in ASCII hexadecimal (including itself)
  */
 
-int git_pkt_parse_line(git_pkt **head, const char *line, const char **out, size_t bufflen)
+int git_pkt_parse_line(
+	git_pkt **head, const char *line, const char **out, size_t bufflen)
 {
-	int ret = 0;
-	size_t len;
+	int ret;
+	int32_t len;
 
 	/* Not even enough for the length */
-	if (bufflen > 0 && bufflen < PKT_LEN_SIZE)
-		return GIT_ESHORTBUFFER;
+	if (bufflen > 0 && bufflen < PKT_LEN_SIZE) {
+		giterr_set(GITERR_NET, "Insufficient buffer data");
+		return -1;
+	}
 
-	if ((ret = parse_len(line)) < 0) {
+	len = parse_len(line);
+	if (len < 0) {
 		/*
 		 * If we fail to parse the length, it might be because the
 		 * server is trying to send us the packfile already.
@@ -198,18 +204,17 @@ int git_pkt_parse_line(git_pkt **head, const char *line, const char **out, size_
 			return pack_pkt(head);
 		}
 
-		giterr_set(GITERR_NET, "Error parsing pkt-line");
-		return -1;
+		return (int)len;
 	}
 
-	len = ret;
-
 	/*
 	 * If we were given a buffer length, then make sure there is
 	 * enough in the buffer to satisfy this line
 	 */
-	if (bufflen > 0 && bufflen < len)
-		return GIT_ESHORTBUFFER;
+	if (bufflen > 0 && bufflen < (size_t)len) {
+		giterr_set(GITERR_NET, "Insufficient buffer data for packet length");
+		return -1;
+	}
 
 	line += PKT_LEN_SIZE;
 	/*
@@ -245,7 +250,7 @@ int git_pkt_parse_line(git_pkt **head, const char *line, const char **out, size_
 
 void git_pkt_free(git_pkt *pkt)
 {
-	if(pkt->type == GIT_PKT_REF) {
+	if (pkt->type == GIT_PKT_REF) {
 		git_pkt_ref *p = (git_pkt_ref *) pkt;
 		git__free(p->head.name);
 	}
@@ -258,7 +263,7 @@ int git_pkt_buffer_flush(git_buf *buf)
 	return git_buf_put(buf, pkt_flush_str, strlen(pkt_flush_str));
 }
 
-int git_pkt_send_flush(int s)
+int git_pkt_send_flush(GIT_SOCKET s)
 {
 
 	return gitno_send(s, pkt_flush_str, strlen(pkt_flush_str), 0);
@@ -268,12 +273,14 @@ static int buffer_want_with_caps(git_remote_head *head, git_transport_caps *caps
 {
 	char capstr[20];
 	char oid[GIT_OID_HEXSZ +1] = {0};
-	int len;
+	unsigned int len;
 
 	if (caps->ofs_delta)
-		strcpy(capstr, GIT_CAP_OFS_DELTA);
+		strncpy(capstr, GIT_CAP_OFS_DELTA, sizeof(capstr));
 
-	len = strlen("XXXXwant ") + GIT_OID_HEXSZ + 1 /* NUL */ + strlen(capstr) + 1 /* LF */;
+	len = (unsigned int)
+		(strlen("XXXXwant ") + GIT_OID_HEXSZ + 1 /* NUL */ +
+		 strlen(capstr) + 1 /* LF */);
 	git_buf_grow(buf, buf->size + len);
 
 	git_oid_fmt(oid, &head->oid);
@@ -283,15 +290,14 @@ static int buffer_want_with_caps(git_remote_head *head, git_transport_caps *caps
 static int send_want_with_caps(git_remote_head *head, git_transport_caps *caps, GIT_SOCKET fd)
 {
 	git_buf buf = GIT_BUF_INIT;
-	int error;
+	int ret;
 
 	if (buffer_want_with_caps(head, caps, &buf) < 0)
 		return -1;
 
-	error = gitno_send(fd, buf.ptr, buf.size, 0);
+	ret = gitno_send(fd, buf.ptr, buf.size, 0);
 	git_buf_free(&buf);
-
-	return error;
+	return ret;
 }
 
 /*
@@ -335,7 +341,7 @@ int git_pkt_buffer_wants(const git_vector *refs, git_transport_caps *caps, git_b
 	return git_pkt_buffer_flush(buf);
 }
 
-int git_pkt_send_wants(const git_vector *refs, git_transport_caps *caps, int fd)
+int git_pkt_send_wants(const git_vector *refs, git_transport_caps *caps, GIT_SOCKET fd)
 {
 	unsigned int i = 0;
 	char buf[sizeof(pkt_want_prefix) + GIT_OID_HEXSZ + 1];
@@ -357,6 +363,7 @@ int git_pkt_send_wants(const git_vector *refs, git_transport_caps *caps, int fd)
 
 		if (send_want_with_caps(refs->contents[i], caps, fd) < 0)
 			return -1;
+
 		/* Increase it here so it's correct whether we run this or not */
 		i++;
 	}
@@ -384,7 +391,7 @@ int git_pkt_buffer_have(git_oid *oid, git_buf *buf)
 	return git_buf_printf(buf, "%s%s\n", pkt_have_prefix, oidhex);
 }
 
-int git_pkt_send_have(git_oid *oid, int fd)
+int git_pkt_send_have(git_oid *oid, GIT_SOCKET fd)
 {
 	char buf[] = "0032have 0000000000000000000000000000000000000000\n";
 
@@ -398,7 +405,7 @@ int git_pkt_buffer_done(git_buf *buf)
 	return git_buf_puts(buf, pkt_done_str);
 }
 
-int git_pkt_send_done(int fd)
+int git_pkt_send_done(GIT_SOCKET fd)
 {
 	return gitno_send(fd, pkt_done_str, strlen(pkt_done_str), 0);
 }
diff --git a/src/pkt.h b/src/pkt.h
index b0bc089..1f8d62e 100644
--- a/src/pkt.h
+++ b/src/pkt.h
@@ -11,6 +11,7 @@
 #include "common.h"
 #include "transport.h"
 #include "buffer.h"
+#include "posix.h"
 #include "git2/net.h"
 
 enum git_pkt_type {
@@ -65,13 +66,13 @@ typedef struct {
 
 int git_pkt_parse_line(git_pkt **head, const char *line, const char **out, size_t len);
 int git_pkt_buffer_flush(git_buf *buf);
-int git_pkt_send_flush(int s);
+int git_pkt_send_flush(GIT_SOCKET s);
 int git_pkt_buffer_done(git_buf *buf);
-int git_pkt_send_done(int s);
+int git_pkt_send_done(GIT_SOCKET s);
 int git_pkt_buffer_wants(const git_vector *refs, git_transport_caps *caps, git_buf *buf);
-int git_pkt_send_wants(const git_vector *refs, git_transport_caps *caps, int fd);
+int git_pkt_send_wants(const git_vector *refs, git_transport_caps *caps, GIT_SOCKET fd);
 int git_pkt_buffer_have(git_oid *oid, git_buf *buf);
-int git_pkt_send_have(git_oid *oid, int fd);
+int git_pkt_send_have(git_oid *oid, GIT_SOCKET fd);
 void git_pkt_free(git_pkt *pkt);
 
 #endif
diff --git a/src/posix.c b/src/posix.c
index 9778809..a3f81d7 100644
--- a/src/posix.c
+++ b/src/posix.c
@@ -58,7 +58,13 @@ int p_read(git_file fd, void *buf, size_t cnt)
 {
 	char *b = buf;
 	while (cnt) {
-		ssize_t r = read(fd, b, cnt);
+		ssize_t r;
+#ifdef GIT_WIN32
+		assert((size_t)((unsigned int)cnt) == cnt);
+		r = read(fd, b, (unsigned int)cnt);
+#else
+		r = read(fd, b, cnt);
+#endif
 		if (r < 0) {
 			if (errno == EINTR || errno == EAGAIN)
 				continue;
@@ -76,7 +82,13 @@ int p_write(git_file fd, const void *buf, size_t cnt)
 {
 	const char *b = buf;
 	while (cnt) {
-		ssize_t r = write(fd, b, cnt);
+		ssize_t r;
+#ifdef GIT_WIN32
+		assert((size_t)((unsigned int)cnt) == cnt);
+		r = write(fd, b, (unsigned int)cnt);
+#else
+		r = write(fd, b, cnt);
+#endif
 		if (r < 0) {
 			if (errno == EINTR || errno == EAGAIN)
 				continue;
diff --git a/src/posix.h b/src/posix.h
index fb17cba..752d515 100644
--- a/src/posix.h
+++ b/src/posix.h
@@ -54,6 +54,14 @@ extern int p_rename(const char *from, const char *to);
 #define p_rmdir(p) rmdir(p)
 #define p_chmod(p,m) chmod(p, m)
 #define p_access(p,m) access(p,m)
+#define p_recv(s,b,l,f) recv(s,b,l,f)
+#define p_send(s,b,l,f) send(s,b,l,f)
+typedef int GIT_SOCKET;
+#define INVALID_SOCKET -1
+
+#else
+
+typedef SOCKET GIT_SOCKET;
 
 #endif
 
diff --git a/src/pqueue.c b/src/pqueue.c
index 3fbf933..cb59c13 100644
--- a/src/pqueue.c
+++ b/src/pqueue.c
@@ -17,14 +17,14 @@ int git_pqueue_init(git_pqueue *q, size_t n, git_pqueue_cmp cmppri)
 	assert(q);
 
 	/* Need to allocate n+1 elements since element 0 isn't used. */
-	if ((q->d = git__malloc((n + 1) * sizeof(void *))) == NULL)
-		return GIT_ENOMEM;
+	q->d = git__malloc((n + 1) * sizeof(void *));
+	GITERR_CHECK_ALLOC(q->d);
 
 	q->size = 1;
 	q->avail = q->step = (n + 1); /* see comment above about n+1 */
 	q->cmppri = cmppri;
 
-	return GIT_SUCCESS;
+	return 0;
 }
 
 
@@ -102,8 +102,8 @@ int git_pqueue_insert(git_pqueue *q, void *d)
 	/* allocate more memory if necessary */
 	if (q->size >= q->avail) {
 		newsize = q->size + q->step;
-		if ((tmp = git__realloc(q->d, sizeof(void *) * newsize)) == NULL)
-			return GIT_ENOMEM;
+		tmp = git__realloc(q->d, sizeof(void *) * newsize);
+		GITERR_CHECK_ALLOC(tmp);
 
 		q->d = tmp;
 		q->avail = newsize;
@@ -114,7 +114,7 @@ int git_pqueue_insert(git_pqueue *q, void *d)
 	q->d[i] = d;
 	bubble_up(q, i);
 
-	return GIT_SUCCESS;
+	return 0;
 }
 
 
diff --git a/src/refs.c b/src/refs.c
index fb23a0e..bea1f17 100644
--- a/src/refs.c
+++ b/src/refs.c
@@ -15,7 +15,8 @@
 #include <git2/tag.h>
 #include <git2/object.h>
 
-#define MAX_NESTING_LEVEL 5
+#define DEFAULT_NESTING_LEVEL	5
+#define MAX_NESTING_LEVEL		10
 
 enum {
 	GIT_PACKREF_HAS_PEEL = 1,
@@ -132,13 +133,13 @@ static int reference_read(
 
 static int loose_parse_symbolic(git_reference *ref, git_buf *file_content)
 {
-	const unsigned int header_len = strlen(GIT_SYMREF);
+	const unsigned int header_len = (unsigned int)strlen(GIT_SYMREF);
 	const char *refname_start;
 	char *eol;
 
 	refname_start = (const char *)file_content->ptr;
 
-	if (file_content->size < (header_len + 1))
+	if (file_content->size < header_len + 1)
 		goto corrupt;
 
 	/*
@@ -729,11 +730,11 @@ static int packed_write(git_repository *repo)
 	unsigned int i;
 	git_buf pack_file_path = GIT_BUF_INIT;
 	git_vector packing_list;
-	size_t total_refs;
+	unsigned int total_refs;
 
 	assert(repo && repo->references.packfile);
 
-	total_refs = repo->references.packfile->key_count;
+	total_refs = (unsigned int)repo->references.packfile->key_count;
 
 	if (git_vector_init(&packing_list, total_refs, packed_sort) < 0)
 		return -1;
@@ -820,9 +821,9 @@ static int _reference_available_cb(const char *ref, void *data)
 	d = (struct reference_available_t *)data;
 
 	if (!d->old_ref || strcmp(d->old_ref, ref)) {
-		int reflen = strlen(ref);
-		int newlen = strlen(d->new_ref);
-		int cmplen = reflen < newlen ? reflen : newlen;
+		size_t reflen = strlen(ref);
+		size_t newlen = strlen(d->new_ref);
+		size_t cmplen = reflen < newlen ? reflen : newlen;
 		const char *lead = reflen < newlen ? d->new_ref : ref;
 
 		if (!strncmp(d->new_ref, ref, cmplen) && lead[cmplen] == '/') {
@@ -1057,24 +1058,80 @@ int git_reference_delete(git_reference *ref)
 int git_reference_lookup(git_reference **ref_out,
 	git_repository *repo, const char *name)
 {
-	char normalized_name[GIT_REFNAME_MAX];
-	git_reference *ref = NULL;
-	int result;
+	return git_reference_lookup_resolved(ref_out, repo, name, 0);
+}
+
+int git_reference_name_to_oid(
+	git_oid *out, git_repository *repo, const char *name)
+{
+	int error;
+	git_reference *ref;
+
+	if ((error = git_reference_lookup_resolved(&ref, repo, name, -1)) < 0)
+		return error;
+
+	git_oid_cpy(out, git_reference_oid(ref));
+	git_reference_free(ref);
+	return 0;
+}
+
+int git_reference_lookup_resolved(
+	git_reference **ref_out,
+	git_repository *repo,
+	const char *name,
+	int max_nesting)
+{
+	git_reference *scan;
+	int result, nesting;
 
 	assert(ref_out && repo && name);
+
 	*ref_out = NULL;
 
-	if (normalize_name(normalized_name, sizeof(normalized_name), name, 0) < 0)
-		return -1;
+	if (max_nesting > MAX_NESTING_LEVEL)
+		max_nesting = MAX_NESTING_LEVEL;
+	else if (max_nesting < 0)
+		max_nesting = DEFAULT_NESTING_LEVEL;
 
-	if (reference_alloc(&ref, repo, normalized_name) < 0)
-		return -1;
+	scan = git__calloc(1, sizeof(git_reference));
+	GITERR_CHECK_ALLOC(scan);
 
-	result = reference_lookup(ref);
-	if (result == 0)
-		*ref_out = ref;
+	scan->name = git__calloc(GIT_REFNAME_MAX + 1, sizeof(char));
+	GITERR_CHECK_ALLOC(scan->name);
 
-	return result;
+	if ((result = normalize_name(scan->name, GIT_REFNAME_MAX, name, 0)) < 0) {
+		git_reference_free(scan);
+		return result;
+	}
+
+	scan->target.symbolic = git__strdup(scan->name);
+	GITERR_CHECK_ALLOC(scan->target.symbolic);
+
+	scan->owner = repo;
+	scan->flags = GIT_REF_SYMBOLIC;
+
+	for (nesting = max_nesting;
+		 nesting >= 0 && (scan->flags & GIT_REF_SYMBOLIC) != 0;
+		 nesting--)
+	{
+		if (nesting != max_nesting)
+			strncpy(scan->name, scan->target.symbolic, GIT_REFNAME_MAX);
+
+		scan->mtime = 0;
+
+		if ((result = reference_lookup(scan)) < 0)
+			return result; /* lookup git_reference_free on scan already */
+	}
+
+	if ((scan->flags & GIT_REF_OID) == 0 && max_nesting != 0) {
+		giterr_set(GITERR_REFERENCE,
+			"Cannot resolve reference (>%u levels deep)", max_nesting);
+		git_reference_free(scan);
+		return -1;
+	}
+
+	*ref_out = scan;
+	return 0;
 }
 
 /**
@@ -1381,47 +1438,10 @@ rollback:
 
 int git_reference_resolve(git_reference **ref_out, git_reference *ref)
 {
-	int result, i = 0;
-	git_repository *repo;
-
-	assert(ref);
-
-	*ref_out = NULL;
-	repo = ref->owner;
-
-	/* If the reference is already resolved, we need to return a
-	 * copy. Instead of duplicating `ref`, we look it up again to
-	 * ensure the copy is out to date */
 	if (ref->flags & GIT_REF_OID)
 		return git_reference_lookup(ref_out, ref->owner, ref->name);
-
-	/* Otherwise, keep iterating until the reference is resolved */
-	for (i = 0; i < MAX_NESTING_LEVEL; ++i) {
-		git_reference *new_ref;
-
-		result = git_reference_lookup(&new_ref, repo, ref->target.symbolic);
-		if (result < 0)
-			return result;
-
-		/* Free intermediate references, except for the original one
-		 * we've received */
-		if (i > 0)
-			git_reference_free(ref);
-
-		ref = new_ref;
-
-		/* When the reference we've just looked up is an OID, we've
-		 * successfully resolved the symbolic ref */
-		if (ref->flags & GIT_REF_OID) {
-			*ref_out = ref;
-			return 0;
-		}
-	}
-
-	giterr_set(GITERR_REFERENCE,
-		"Symbolic reference too nested (%d levels deep)", MAX_NESTING_LEVEL);
-
-	return -1;
+	else
+		return git_reference_lookup_resolved(ref_out, ref->owner, ref->target.symbolic, -1);
 }
 
 int git_reference_packall(git_repository *repo)
@@ -1649,3 +1669,20 @@ int git_reference__normalize_name_oid(
 {
 	return normalize_name(buffer_out, out_size, name, 1);
 }
+
+#define GIT_REF_TYPEMASK (GIT_REF_OID | GIT_REF_SYMBOLIC)
+
+int git_reference_cmp(git_reference *ref1, git_reference *ref2)
+{
+	assert(ref1 && ref2);
+
+	/* let's put symbolic refs before OIDs */
+	if ((ref1->flags & GIT_REF_TYPEMASK) != (ref2->flags & GIT_REF_TYPEMASK))
+		return (ref1->flags & GIT_REF_SYMBOLIC) ? -1 : 1;
+
+	if (ref1->flags & GIT_REF_SYMBOLIC)
+		return strcmp(ref1->target.symbolic, ref2->target.symbolic);
+
+	return git_oid_cmp(&ref1->target.oid, &ref2->target.oid);
+}
+
diff --git a/src/refs.h b/src/refs.h
index 13b9abf..e4a225c 100644
--- a/src/refs.h
+++ b/src/refs.h
@@ -55,4 +55,27 @@ void git_repository__refcache_free(git_refcache *refs);
 int git_reference__normalize_name(char *buffer_out, size_t out_size, const char *name);
 int git_reference__normalize_name_oid(char *buffer_out, size_t out_size, const char *name);
 
+/**
+ * Lookup a reference by name and try to resolve to an OID.
+ *
+ * You can control how many dereferences this will attempt to resolve the
+ * reference with the `max_deref` parameter, or pass -1 to use a sane
+ * default.  If you pass 0 for `max_deref`, this will not attempt to resolve
+ * the reference.  For any value of `max_deref` other than 0, not
+ * successfully resolving the reference will be reported as an error.
+
+ * The generated reference must be freed by the user.
+ *
+ * @param reference_out Pointer to the looked-up reference
+ * @param repo The repository to look up the reference
+ * @param name The long name for the reference (e.g. HEAD, ref/heads/master, refs/tags/v0.1.0, ...)
+ * @param max_deref Maximum number of dereferences to make of symbolic refs, 0 means simple lookup, < 0 means use default reasonable value
+ * @return 0 on success or < 0 on error; not being able to resolve the reference is an error unless 0 was passed for max_deref
+ */
+int git_reference_lookup_resolved(
+	git_reference **reference_out,
+	git_repository *repo,
+	const char *name,
+	int max_deref);
+
 #endif
diff --git a/src/repository.c b/src/repository.c
index b8b2033..88e3a18 100644
--- a/src/repository.c
+++ b/src/repository.c
@@ -183,21 +183,20 @@ static int find_ceiling_dir_offset(
 	char buf[GIT_PATH_MAX + 1];
 	char buf2[GIT_PATH_MAX + 1];
 	const char *ceil, *sep;
-	int len, max_len = -1;
-	int min_len;
+	size_t len, max_len = 0, min_len;
 
 	assert(path);
 
-	min_len = git_path_root(path) + 1;
+	min_len = (size_t)(git_path_root(path) + 1);
 
 	if (ceiling_directories == NULL || min_len == 0)
-		return min_len;
+		return (int)min_len;
 
 	for (sep = ceil = ceiling_directories; *sep; ceil = sep + 1) {
 		for (sep = ceil; *sep && *sep != GIT_PATH_LIST_SEPARATOR; sep++);
 		len = sep - ceil;
 
-		if (len == 0 || len >= (int)sizeof(buf) || git_path_root(ceil) == -1)
+		if (len == 0 || len >= sizeof(buf) || git_path_root(ceil) == -1)
 			continue;
 
 		strncpy(buf, ceil, len);
@@ -218,7 +217,7 @@ static int find_ceiling_dir_offset(
 		}
 	}
 
-	return max_len <= min_len ? min_len : max_len;
+	return (int)(max_len <= min_len ? min_len : max_len);
 }
 
 /*
@@ -774,24 +773,7 @@ int git_repository_head_detached(git_repository *repo)
 
 int git_repository_head(git_reference **head_out, git_repository *repo)
 {
-	git_reference *ref, *resolved_ref;
-	int error;
-
-	*head_out = NULL;
-
-	error = git_reference_lookup(&ref, repo, GIT_HEAD_FILE);
-	if (error < 0)
-		return error;
-
-	error = git_reference_resolve(&resolved_ref, ref);
-	if (error < 0) {
-		git_reference_free(ref);
-		return error;
-	}
-
-	git_reference_free(ref);
-	*head_out = resolved_ref;
-	return 0;
+	return git_reference_lookup_resolved(head_out, repo, GIT_HEAD_FILE, -1);
 }
 
 int git_repository_head_orphan(git_repository *repo)
diff --git a/src/revwalk.c b/src/revwalk.c
index c2c098c..a625760 100644
--- a/src/revwalk.c
+++ b/src/revwalk.c
@@ -77,11 +77,10 @@ static int commit_time_cmp(void *a, void *b)
 static commit_list *commit_list_insert(commit_object *item, commit_list **list_p)
 {
 	commit_list *new_list = git__malloc(sizeof(commit_list));
-	if (new_list == NULL)
-		return NULL;
-
-	new_list->item = item;
-	new_list->next = *list_p;
+	if (new_list != NULL) {
+		new_list->item = item;
+		new_list->next = *list_p;
+	}
 	*list_p = new_list;
 	return new_list;
 }
@@ -143,8 +142,7 @@ static int alloc_chunk(git_revwalk *walk)
 	void *chunk;
 
 	chunk = git__calloc(COMMITS_PER_CHUNK, CHUNK_STEP);
-	if (chunk == NULL)
-		return GIT_ENOMEM;
+	GITERR_CHECK_ALLOC(chunk);
 
 	walk->chunk_size = 0;
 	return git_vector_insert(&walk->memory_alloc, chunk);
@@ -155,7 +153,8 @@ static commit_object *alloc_commit(git_revwalk *walk)
 	unsigned char *chunk;
 
 	if (walk->chunk_size == COMMITS_PER_CHUNK)
-		alloc_chunk(walk);
+		if (alloc_chunk(walk) < 0)
+			return NULL;
 
 	chunk = git_vector_get(&walk->memory_alloc, walk->memory_alloc.length - 1);
 	chunk += (walk->chunk_size * CHUNK_STEP);
@@ -186,7 +185,7 @@ static commit_object *commit_lookup(git_revwalk *walk, const git_oid *oid)
 
 	git_oid_cpy(&commit->oid, oid);
 
-	if (git_hashtable_insert(walk->commits, &commit->oid, commit) < GIT_SUCCESS) {
+	if (git_hashtable_insert(walk->commits, &commit->oid, commit) < 0) {
 		git__free(commit);
 		return NULL;
 	}
@@ -196,7 +195,7 @@ static commit_object *commit_lookup(git_revwalk *walk, const git_oid *oid)
 
 static int commit_quick_parse(git_revwalk *walk, commit_object *commit, git_rawobj *raw)
 {
-	const int parent_len = strlen("parent ") + GIT_OID_HEXSZ + 1;
+	const size_t parent_len = strlen("parent ") + GIT_OID_HEXSZ + 1;
 
 	unsigned char *buffer = raw->data;
 	unsigned char *buffer_end = buffer + raw->len;
@@ -262,7 +261,7 @@ static int commit_parse(git_revwalk *walk, commit_object *commit)
 		return 0;
 
 	if ((error = git_odb_read(&obj, walk->odb, &commit->oid)) < 0)
-		return -1;
+		return error;
 
 	if (obj->raw.type != GIT_OBJ_COMMIT) {
 		git_odb_object_free(obj);
@@ -432,6 +431,8 @@ static void mark_uninteresting(commit_object *commit)
 
 static int process_commit(git_revwalk *walk, commit_object *commit, int hide)
 {
+	int error;
+
 	if (hide)
 		mark_uninteresting(commit);
 
@@ -440,8 +441,8 @@ static int process_commit(git_revwalk *walk, commit_object *commit, int hide)
 
 	commit->seen = 1;
 
-	if (commit_parse(walk, commit) < 0)
-		return -1;
+	if ((error = commit_parse(walk, commit)) < 0)
+		return error;
 
 	return walk->enqueue(walk, commit);
 }
@@ -449,13 +450,12 @@ static int process_commit(git_revwalk *walk, commit_object *commit, int hide)
 static int process_commit_parents(git_revwalk *walk, commit_object *commit)
 {
 	unsigned short i;
+	int error = 0;
 
-	for (i = 0; i < commit->out_degree; ++i) {
-		if (process_commit(walk, commit->parents[i], commit->uninteresting) < 0)
-			return -1;
-	}
+	for (i = 0; i < commit->out_degree && !error; ++i)
+		error = process_commit(walk, commit->parents[i], commit->uninteresting);
 
-	return 0;
+	return error;
 }
 
 static int push_commit(git_revwalk *walk, const git_oid *oid, int uninteresting)
@@ -464,7 +464,7 @@ static int push_commit(git_revwalk *walk, const git_oid *oid, int uninteresting)
 
 	commit = commit_lookup(walk, oid);
 	if (commit == NULL)
-		return -1;
+		return -1; /* error already reported by failed lookup */
 
 	commit->uninteresting = uninteresting;
 	if (walk->one == NULL && !uninteresting) {
@@ -492,21 +492,12 @@ int git_revwalk_hide(git_revwalk *walk, const git_oid *oid)
 
 static int push_ref(git_revwalk *walk, const char *refname, int hide)
 {
-	git_reference *ref, *resolved;
-	int error;
-
-	if (git_reference_lookup(&ref, walk->repo, refname) < 0)
-		return -1;
+	git_oid oid;
 
-	error = git_reference_resolve(&resolved, ref);
-	git_reference_free(ref);
-	if (error < 0)
+	if (git_reference_name_to_oid(&oid, walk->repo, refname) < 0)
 		return -1;
 
-	error = push_commit(walk, git_reference_oid(resolved), hide);
-	git_reference_free(resolved);
-
-	return error;
+	return push_commit(walk, &oid, hide);
 }
 
 struct push_cb_data {
@@ -558,7 +549,8 @@ static int push_glob(git_revwalk *walk, const char *glob, int hide)
 	data.glob = git_buf_cstr(&buf);
 	data.hide = hide;
 
-	if (git_reference_foreach(walk->repo, GIT_REF_LISTALL, push_glob_cb, &data) < 0)
+	if (git_reference_foreach(
+			walk->repo, GIT_REF_LISTALL, push_glob_cb, &data) < 0)
 		goto on_error;
 
 	regfree(&preg);
@@ -614,7 +606,7 @@ static int revwalk_enqueue_timesort(git_revwalk *walk, commit_object *commit)
 
 static int revwalk_enqueue_unsorted(git_revwalk *walk, commit_object *commit)
 {
-	return commit_list_insert(commit, &walk->iterator_rand) ? GIT_SUCCESS : GIT_ENOMEM;
+	return commit_list_insert(commit, &walk->iterator_rand) ? 0 : -1;
 }
 
 static int revwalk_next_timesort(commit_object **object_out, git_revwalk *walk)
@@ -624,7 +616,7 @@ static int revwalk_next_timesort(commit_object **object_out, git_revwalk *walk)
 
 	while ((next = git_pqueue_pop(&walk->iterator_time)) != NULL) {
 		if ((error = process_commit_parents(walk, next)) < 0)
-			return -1;
+			return error;
 
 		if (!next->uninteresting) {
 			*object_out = next;
@@ -642,7 +634,7 @@ static int revwalk_next_unsorted(commit_object **object_out, git_revwalk *walk)
 
 	while ((next = commit_list_pop(&walk->iterator_rand)) != NULL) {
 		if ((error = process_commit_parents(walk, next)) < 0)
-			return -1;
+			return error;
 
 		if (!next->uninteresting) {
 			*object_out = next;
@@ -724,19 +716,19 @@ static int prepare_walk(git_revwalk *walk)
 		}
 
 		if (error != GIT_EREVWALKOVER)
-			return -1;
+			return error;
 
 		walk->get_next = &revwalk_next_toposort;
 	}
 
 	if (walk->sorting & GIT_SORT_REVERSE) {
 
-		while ((error = walk->get_next(&next, walk)) == GIT_SUCCESS)
+		while ((error = walk->get_next(&next, walk)) == 0)
 			if (commit_list_insert(next, &walk->iterator_reverse) == NULL)
 				return -1;
 
 		if (error != GIT_EREVWALKOVER)
-			return -1;
+			return error;
 
 		walk->get_next = &revwalk_next_reverse;
 	}
@@ -761,16 +753,13 @@ int git_revwalk_new(git_revwalk **revwalk_out, git_repository *repo)
 	walk->commits = git_hashtable_alloc(64,
 			object_table_hash,
 			(git_hash_keyeq_ptr)git_oid_cmp);
+	GITERR_CHECK_ALLOC(walk->commits);
 
-	if (walk->commits == NULL) {
-		git__free(walk);
+	if (git_pqueue_init(&walk->iterator_time, 8, commit_time_cmp) < 0 ||
+		git_vector_init(&walk->memory_alloc, 8, NULL) < 0 ||
+		git_vector_init(&walk->twos, 4, NULL) < 0 ||
+		alloc_chunk(walk) < 0)
 		return -1;
-	}
-
-	git_pqueue_init(&walk->iterator_time, 8, commit_time_cmp);
-	git_vector_init(&walk->memory_alloc, 8, NULL);
-	git_vector_init(&walk->twos, 4, NULL);
-	alloc_chunk(walk);
 
 	walk->get_next = &revwalk_next_unsorted;
 	walk->enqueue = &revwalk_enqueue_unsorted;
@@ -849,7 +838,7 @@ int git_revwalk_next(git_oid *oid, git_revwalk *walk)
 
 	if (!walk->walking) {
 		if ((error = prepare_walk(walk)) < 0)
-			return -1;
+			return error;
 	}
 
 	error = walk->get_next(&next, walk);
@@ -859,11 +848,10 @@ int git_revwalk_next(git_oid *oid, git_revwalk *walk)
 		return GIT_EREVWALKOVER;
 	}
 
-	if (error < 0)
-		return -1;
+	if (!error)
+		git_oid_cpy(oid, &next->oid);
 
-	git_oid_cpy(oid, &next->oid);
-	return 0;
+	return error;
 }
 
 void git_revwalk_reset(git_revwalk *walk)
diff --git a/src/sha1.c b/src/sha1.c
index af3c2d2..8aaedeb 100644
--- a/src/sha1.c
+++ b/src/sha1.c
@@ -232,7 +232,7 @@ void git__blk_SHA1_Init(blk_SHA_CTX *ctx)
 	ctx->H[4] = 0xc3d2e1f0;
 }
 
-void git__blk_SHA1_Update(blk_SHA_CTX *ctx, const void *data, unsigned long len)
+void git__blk_SHA1_Update(blk_SHA_CTX *ctx, const void *data, size_t len)
 {
 	unsigned int lenW = ctx->size & 63;
 
@@ -242,7 +242,7 @@ void git__blk_SHA1_Update(blk_SHA_CTX *ctx, const void *data, unsigned long len)
 	if (lenW) {
 		unsigned int left = 64 - lenW;
 		if (len < left)
-			left = len;
+			left = (unsigned int)len;
 		memcpy(lenW + (char *)ctx->W, data, left);
 		lenW = (lenW + left) & 63;
 		len -= left;
diff --git a/src/sha1.h b/src/sha1.h
index 117e931..93a244d 100644
--- a/src/sha1.h
+++ b/src/sha1.h
@@ -12,7 +12,7 @@ typedef struct {
 } blk_SHA_CTX;
 
 void git__blk_SHA1_Init(blk_SHA_CTX *ctx);
-void git__blk_SHA1_Update(blk_SHA_CTX *ctx, const void *dataIn, unsigned long len);
+void git__blk_SHA1_Update(blk_SHA_CTX *ctx, const void *dataIn, size_t len);
 void git__blk_SHA1_Final(unsigned char hashout[20], blk_SHA_CTX *ctx);
 
 #define SHA_CTX		blk_SHA_CTX
diff --git a/src/signature.c b/src/signature.c
index 87386bc..4d6d11c 100644
--- a/src/signature.c
+++ b/src/signature.c
@@ -47,7 +47,7 @@ static int signature_error(const char *msg)
 static int process_trimming(const char *input, char **storage, const char *input_end, int fail_when_empty)
 {
 	const char *left, *right;
-	int trimmed_input_length;
+	size_t trimmed_input_length;
 
 	assert(storage);
 
diff --git a/src/status.c b/src/status.c
index 0732d4a..62cc37e 100644
--- a/src/status.c
+++ b/src/status.c
@@ -20,31 +20,19 @@
 
 static int resolve_head_to_tree(git_tree **tree, git_repository *repo)
 {
-	git_reference *head = NULL;
+	git_oid head_oid;
 	git_object *obj = NULL;
 
-	if (git_reference_lookup(&head, repo, GIT_HEAD_FILE) < 0)
-		return -1;
-
-	if (git_reference_oid(head) == NULL) {
-		git_reference *resolved;
-
-		if (git_reference_resolve(&resolved, head) < 0) {
-			/* cannot resolve HEAD - probably brand new repo */
-			giterr_clear();
-			git_reference_free(head);
-			return GIT_ENOTFOUND;
-		}
-
-		git_reference_free(head);
-		head = resolved;
+	if (git_reference_name_to_oid(&head_oid, repo, GIT_HEAD_FILE) < 0) {
+		/* cannot resolve HEAD - probably brand new repo */
+		giterr_clear();
+		*tree = NULL;
+		return 0;
 	}
 
-	if (git_object_lookup(&obj, repo, git_reference_oid(head), GIT_OBJ_ANY) < 0)
+	if (git_object_lookup(&obj, repo, &head_oid, GIT_OBJ_ANY) < 0)
 		goto fail;
 
-	git_reference_free(head);
-
 	switch (git_object_type(obj)) {
 	case GIT_OBJ_TREE:
 		*tree = (git_tree *)obj;
@@ -62,7 +50,6 @@ static int resolve_head_to_tree(git_tree **tree, git_repository *repo)
 
 fail:
 	git_object_free(obj);
-	git_reference_free(head);
 	return -1;
 }
 
@@ -152,7 +139,7 @@ int git_status_foreach_ext(
 		diffopt.flags = diffopt.flags | GIT_DIFF_RECURSE_UNTRACKED_DIRS;
 	/* TODO: support EXCLUDE_SUBMODULES flag */
 
-	if (show != GIT_STATUS_SHOW_WORKDIR_ONLY &&
+	if (show != GIT_STATUS_SHOW_WORKDIR_ONLY && head != NULL &&
 		(err = git_diff_index_to_tree(repo, &diffopt, head, &idx2head)) < 0)
 		goto cleanup;
 
@@ -345,316 +332,6 @@ static int status_entry_update_ignore(struct status_entry *e, git_ignores *ignor
 	return 0;
 }
 
-struct status_st {
-	git_repository *repo;
-	git_vector *vector;
-	git_index *index;
-	git_tree *tree;
-	git_ignores *ignores;
-
-	int workdir_path_len;
-	git_buf head_tree_relative_path;
-	int head_tree_relative_path_len;
-	unsigned int tree_position;
-	unsigned int index_position;
-	int is_dir:1;
-};
-
-static int retrieve_head_tree(git_tree **tree_out, git_repository *repo)
-{
-	git_reference *resolved_head_ref;
-	git_commit *head_commit = NULL;
-	git_tree *tree;
-	int error = 0;
-
-	*tree_out = NULL;
-
-	if ((error = git_repository_head(&resolved_head_ref, repo)) < 0) {
-		/* Assume that a situation where HEAD exists but can not be resolved
-		 * is valid.  A new repository fits this description for instance.
-		 */
-		if (error == GIT_ENOTFOUND)
-			return 0;
-		return error;
-	}
-
-	if ((error = git_commit_lookup(
-		&head_commit, repo, git_reference_oid(resolved_head_ref))) < 0)
-		return error;
-
-	git_reference_free(resolved_head_ref);
-
-	if ((error = git_commit_tree(&tree, head_commit)) == 0)
-		*tree_out = tree;
-
-	git_commit_free(head_commit);
-	return error;
-}
-
-enum path_type {
-	GIT_STATUS_PATH_NULL,
-	GIT_STATUS_PATH_IGNORE,
-	GIT_STATUS_PATH_FILE,
-	GIT_STATUS_PATH_FOLDER,
-};
-
-static int dirent_cb(void *state, git_buf *full_path);
-static int alphasorted_futils_direach(
-	git_buf *path, int (*fn)(void *, git_buf *), void *arg);
-
-static int process_folder(
-	struct status_st *st,
-	const git_tree_entry *tree_entry,
-	git_buf *full_path,
-	enum path_type path_type)
-{
-	git_object *subtree = NULL;
-	git_tree *pushed_tree = NULL;
-	int error, pushed_tree_position = 0;
-	git_otype tree_entry_type = GIT_OBJ_BAD;
-
-	if (tree_entry != NULL) {
-		tree_entry_type = git_tree_entry_type(tree_entry);
-
-		switch (tree_entry_type) {
-		case GIT_OBJ_TREE:
-			error = git_tree_entry_2object(&subtree, ((git_object *)(st->tree))->repo, tree_entry);
-			pushed_tree = st->tree;
-			pushed_tree_position = st->tree_position;
-			st->tree = (git_tree *)subtree;
-			st->tree_position = 0;
-			st->head_tree_relative_path_len += 1 + tree_entry->filename_len; /* path + '/' + name */
-			break;
-
-		case GIT_OBJ_BLOB:
-			/* No op */
-			break;
-
-		case GIT_OBJ_COMMIT:
-			/* TODO: proper submodule support */
-			break;
-
-		default:
-			giterr_set(GITERR_REPOSITORY, "Unexpected tree entry type");
-			return -1;
-		}
-	}
-
-
-	if (full_path != NULL && path_type == GIT_STATUS_PATH_FOLDER) {
-		git_ignores ignores, *old_ignores;
-
-		if ((error = git_ignore__for_path(st->repo,
-			full_path->ptr + st->workdir_path_len, &ignores)) == 0)
-		{
-			old_ignores = st->ignores;
-			st->ignores = &ignores;
-
-			error = alphasorted_futils_direach(full_path, dirent_cb, st);
-
-			git_ignore__free(st->ignores);
-			st->ignores = old_ignores;
-		}
-	} else {
-		error = dirent_cb(st, NULL);
-	}
-
-	if (tree_entry_type == GIT_OBJ_TREE) {
-		git_object_free(subtree);
-		st->head_tree_relative_path_len -= 1 + tree_entry->filename_len;
-		st->tree = pushed_tree;
-		st->tree_position = pushed_tree_position;
-		st->tree_position++;
-	}
-
-	return error;
-}
-
-static int store_if_changed(struct status_st *st, struct status_entry *e)
-{
-	int error = status_entry_update_flags(e);
-	if (error < 0)
-		return error;
-
-	if (status_entry_is_ignorable(e) &&
-		(error = status_entry_update_ignore(e, st->ignores, e->path)) < 0)
-		return error;
-
-	if (e->status_flags == GIT_STATUS_CURRENT) {
-		git__free(e);
-		return 0;
-	}
-
-	return git_vector_insert(st->vector, e);
-}
-
-static int determine_status(
-	struct status_st *st,
-	int in_head, int in_index, int in_workdir,
-	const git_tree_entry *tree_entry,
-	const git_index_entry *index_entry,
-	git_buf *full_path,
-	const char *status_path,
-	enum path_type path_type)
-{
-	struct status_entry *e;
-	int error = 0;
-	git_otype tree_entry_type = GIT_OBJ_BAD;
-
-	if (tree_entry != NULL)
-		tree_entry_type = git_tree_entry_type(tree_entry);
-
-	/* If we're dealing with a directory in the workdir, let's recursively tackle it first */
-	if (path_type == GIT_STATUS_PATH_FOLDER)
-		return process_folder(st, tree_entry, full_path, path_type);
-
-	/* Are we dealing with a file somewhere? */
-	if (in_workdir || in_index || (in_head && tree_entry_type == GIT_OBJ_BLOB)) {
-		e = status_entry_new(NULL, status_path);
-
-		if (in_head && tree_entry_type == GIT_OBJ_BLOB) {
-			status_entry_update_from_tree_entry(e, tree_entry);
-			st->tree_position++;
-		}
-
-		if (in_index) {
-			status_entry_update_from_index_entry(e, index_entry);
-			st->index_position++;
-		}
-
-		if (in_workdir &&
-			(error = status_entry_update_from_workdir(e, full_path->ptr)) < 0)
-			return error;	/* The callee has already set the error message */
-
-		return store_if_changed(st, e);
-	}
-
-	/* Are we dealing with a subtree? */
-	if (tree_entry_type == GIT_OBJ_TREE) {
-		assert(in_head && !in_index && !in_workdir);
-		return process_folder(st, tree_entry, full_path, path_type);
-	}
-
-	/* We're dealing with something else -- most likely a submodule;
-	 * skip it for now */
-	if (in_head)
-		st->tree_position++;
-	if (in_index)
-		st->index_position++;
-	return 0;
-}
-
-static int path_type_from(git_buf *full_path, int is_dir)
-{
-	if (full_path == NULL)
-		return GIT_STATUS_PATH_NULL;
-
-	if (!is_dir)
-		return GIT_STATUS_PATH_FILE;
-
-	if (!git__suffixcmp(full_path->ptr, "/" DOT_GIT "/"))
-		return GIT_STATUS_PATH_IGNORE;
-
-	return GIT_STATUS_PATH_FOLDER;
-}
-
-static const char *status_path(
-	const char *first, const char *second, const char *third)
-{
-	/* At least one of them can not be NULL */
-	assert(first != NULL || second != NULL || third != NULL);
-
-	/* TODO: Fixme. Ensure that when non null, they're all equal */
-	if (first != NULL)
-		return first;
-
-	if (second != NULL)
-		return second;
-
-	return third;
-}
-
-static int compare(const char *left, const char *right)
-{
-	if (left == NULL && right == NULL)
-		return 0;
-
-	if (left == NULL)
-		return 1;
-
-	if (right == NULL)
-		return -1;
-
-	return strcmp(left, right);
-}
-
-/* Greatly inspired from JGit IndexTreeWalker */
-/* https://github.com/spearce/jgit/blob/ed47e29c777accfa78c6f50685a5df2b8f5b8ff5/org.spearce.jgit/src/org/spearce/jgit/lib/IndexTreeWalker.java#L88 */
-
-static int dirent_cb(void *state, git_buf *a)
-{
-	const git_tree_entry *m;
-	const git_index_entry *entry;
-	enum path_type path_type;
-	int cmpma, cmpmi, cmpai, error;
-	const char *pm, *pa, *pi;
-	const char *m_name, *i_name, *a_name;
-	struct status_st *st = (struct status_st *)state;
-
-	path_type = path_type_from(a, st->is_dir);
-
-	if (path_type == GIT_STATUS_PATH_IGNORE)
-		return 0;	/* Let's skip the ".git" directory */
-
-	a_name = (path_type != GIT_STATUS_PATH_NULL) ? a->ptr + st->workdir_path_len : NULL;
-
-	/* Loop over head tree and index up to and including this workdir file */
-	while (1) {
-		if (st->tree == NULL)
-			m = NULL;
-		else
-			m = git_tree_entry_byindex(st->tree, st->tree_position);
-
-		entry = git_index_get(st->index, st->index_position);
-
-		if ((m == NULL) && (a == NULL) && (entry == NULL))
-			return 0;
-
-		if (m != NULL) {
-			git_buf_truncate(&st->head_tree_relative_path,
-							 st->head_tree_relative_path_len);
-			git_buf_joinpath(&st->head_tree_relative_path,
-							 st->head_tree_relative_path.ptr, m->filename);
-			/* When the tree entry is a folder, append a forward slash to its name */
-			if (git_tree_entry_type(m) == GIT_OBJ_TREE)
-				git_path_to_dir(&st->head_tree_relative_path);
-
-			if (git_buf_oom(&st->head_tree_relative_path))
-				return -1;
-
-			m_name = st->head_tree_relative_path.ptr;
-		} else
-			m_name = NULL;
-
-		i_name = (entry != NULL) ? entry->path : NULL;
-
-		cmpma = compare(m_name, a_name);
-		cmpmi = compare(m_name, i_name);
-		cmpai = compare(a_name, i_name);
-
-		pm = ((cmpma <= 0) && (cmpmi <= 0)) ? m_name : NULL;
-		pa = ((cmpma >= 0) && (cmpai <= 0)) ? a_name : NULL;
-		pi = ((cmpmi >= 0) && (cmpai >= 0)) ? i_name : NULL;
-
-		if ((error = determine_status(st, pm != NULL, pi != NULL, pa != NULL,
-				m, entry, a, status_path(pm, pi, pa), path_type)) < 0)
-			return error;
-
-		if ((pa != NULL) || (path_type == GIT_STATUS_PATH_FOLDER))
-			return 0;
-	}
-}
-
 static int recurse_tree_entry(git_tree *tree, struct status_entry *e, const char *path)
 {
 	char *dir_sep;
@@ -728,7 +405,7 @@ int git_status_file(
 	status_entry_update_from_index(e, index);
 
 	/* Try to find file in HEAD */
-	if ((error = retrieve_head_tree(&tree, repo)) < 0)
+	if ((error = resolve_head_to_tree(&tree, repo)) < 0)
 		goto cleanup;
 
 	if (tree != NULL) {
@@ -761,62 +438,6 @@ cleanup:
 	return error;
 }
 
-/*
- * git_path_direach is not supposed to return entries in an ordered manner.
- * alphasorted_futils_direach wraps git_path_dirload and invokes the
- * callback function by passing it alphabetically sorted path parameters.
- *
- */
-static int alphasorted_futils_direach(
-	git_buf *path,
-	int (*fn)(void *, git_buf *),
-	void *arg)
-{
-	int error;
-	char *entry;
-	git_vector entry_names;
-	unsigned int idx;
-
-	if (git_vector_init(&entry_names, 16, git__strcmp_cb) < 0)
-		return -1;
-
-	if ((error = git_path_dirload(path->ptr, 0, 1, &entry_names)) < 0)
-		return error;
-
-	git_vector_foreach(&entry_names, idx, entry) {
-		size_t entry_len = strlen(entry);
-		if (git_path_isdir(entry)) {
-			/* dirload allocated 1 extra byte so there is space for slash */
-			entry[entry_len++] = '/';
-			entry[entry_len]   = '\0';
-		}
-	}
-
-	git_vector_sort(&entry_names);
-
-	git_vector_foreach(&entry_names, idx, entry) {
-		/* Walk the entire vector even if there is an error, in order to
-		 * free up memory, but stop making callbacks after an error.
-		 */
-		if (!error) {
-			git_buf entry_path = GIT_BUF_INIT;
-			git_buf_attach(&entry_path, entry, 0);
-
-			((struct status_st *)arg)->is_dir =
-				(entry_path.ptr[entry_path.size - 1] == '/');
-
-			error = fn(arg, &entry_path);
-		}
-
-		git__free(entry);
-	}
-
-	git_vector_free(&entry_names);
-
-	return error;
-}
-
-
 int git_status_should_ignore(git_repository *repo, const char *path, int *ignored)
 {
 	int error;
diff --git a/src/tag.c b/src/tag.c
index cfd2c70..5524879 100644
--- a/src/tag.c
+++ b/src/tag.c
@@ -67,7 +67,8 @@ int git_tag__parse_buffer(git_tag *tag, const char *buffer, size_t length)
 		NULL, "commit\n", "tree\n", "blob\n", "tag\n"
 	};
 
-	unsigned int i, text_len;
+	unsigned int i;
+	size_t text_len;
 	char *search;
 	int error;
 
diff --git a/src/transports/git.c b/src/transports/git.c
index fd3ff5b..825f072 100644
--- a/src/transports/git.c
+++ b/src/transports/git.c
@@ -46,7 +46,7 @@ static int gen_proto(git_buf *request, const char *cmd, const char *url)
 	char *delim, *repo;
 	char default_command[] = "git-upload-pack";
 	char host[] = "host=";
-	int len;
+	size_t len;
 
 	delim = strchr(url, '/');
 	if (delim == NULL) {
@@ -66,7 +66,8 @@ static int gen_proto(git_buf *request, const char *cmd, const char *url)
 	len = 4 + strlen(cmd) + 1 + strlen(repo) + 1 + strlen(host) + (delim - url) + 1;
 
 	git_buf_grow(request, len);
-	git_buf_printf(request, "%04x%s %s%c%s", len, cmd, repo, 0, host);
+	git_buf_printf(request, "%04x%s %s%c%s",
+		(unsigned int)(len & 0x0FFFF), cmd, repo, 0, host);
 	git_buf_put(request, url, delim - url);
 	git_buf_putc(request, '\0');
 
@@ -119,7 +120,7 @@ static int do_connect(transport_git *t, const char *url)
 	git__free(port);
 
 	if (error < GIT_SUCCESS && s > 0)
-		close(s);
+		gitno_close(s);
 	if (!connected) {
 		giterr_set(GITERR_NET, "Failed to connect to the host");
 		return -1;
diff --git a/src/transports/http.c b/src/transports/http.c
index d8af99d..0938fef 100644
--- a/src/transports/http.c
+++ b/src/transports/http.c
@@ -32,7 +32,7 @@ typedef struct {
 	git_protocol proto;
 	git_vector refs;
 	git_vector common;
-	int socket;
+	GIT_SOCKET socket;
 	git_buf buf;
 	git_remote_head **heads;
 	int error;
@@ -96,7 +96,7 @@ static int do_connect(transport_http *t, const char *host, const char *port)
 	t->socket = s;
 	t->parent.connected = 1;
 
-	return GIT_SUCCESS;
+	return 0;
 }
 
 /*
diff --git a/src/transports/local.c b/src/transports/local.c
index 01c72cb..5dc3501 100644
--- a/src/transports/local.c
+++ b/src/transports/local.c
@@ -26,31 +26,22 @@ static int add_ref(transport_local *t, const char *name)
 {
 	const char peeled[] = "^{}";
 	git_remote_head *head;
-	git_reference *ref = NULL, *resolved_ref = NULL;
 	git_object *obj = NULL, *target = NULL;
 	git_buf buf = GIT_BUF_INIT;
 
-	if (git_reference_lookup(&ref, t->repo, name) < 0)
-		return -1;
-
-	if (git_reference_resolve(&resolved_ref, ref) < 0) {
-		git_reference_free(ref);
-		return -1;
-	}
-
 	head = git__malloc(sizeof(git_remote_head));
 	GITERR_CHECK_ALLOC(head);
 
 	head->name = git__strdup(name);
 	GITERR_CHECK_ALLOC(head->name);
 
-	git_oid_cpy(&head->oid, git_reference_oid(resolved_ref));
-
-	if (git_vector_insert(&t->refs, head) < 0)
+	if (git_reference_name_to_oid(&head->oid, t->repo, name) < 0 ||
+		git_vector_insert(&t->refs, head) < 0)
+	{
+		git__free(head->name);
+		git__free(head);
 		return -1;
-
-	git_reference_free(ref);
-	git_reference_free(resolved_ref);
+	}
 
 	/* If it's not a tag, we don't need to try to peel it */
 	if (git__prefixcmp(name, GIT_REFS_TAGS_DIR))
@@ -100,10 +91,8 @@ static int store_refs(transport_local *t)
 
 	assert(t);
 
-	if (git_vector_init(&t->refs, ref_names.count, NULL) < 0)
-		return -1;
-
-	if (git_reference_listall(&ref_names, t->repo, GIT_REF_LISTALL) < 0)
+	if (git_reference_listall(&ref_names, t->repo, GIT_REF_LISTALL) < 0 ||
+		git_vector_init(&t->refs, (unsigned int)ref_names.count, NULL) < 0)
 		goto on_error;
 
 	/* Sort the references first */
diff --git a/src/tree.c b/src/tree.c
index 5957f7a..56a7229 100644
--- a/src/tree.c
+++ b/src/tree.c
@@ -624,7 +624,7 @@ static int tree_frompath(
 	git_tree **parent_out,
 	git_tree *root,
 	git_buf *treeentry_path,
-	int offset)
+	size_t offset)
 {
 	char *slash_pos = NULL;
 	const git_tree_entry* entry;
diff --git a/src/tsort.c b/src/tsort.c
index 6fbec5b..f54c21e 100644
--- a/src/tsort.c
+++ b/src/tsort.c
@@ -30,8 +30,10 @@ static int binsearch(void **dst, const void *x, size_t size, cmp_ptr_t cmp)
 	int l, c, r;
 	void *lx, *cx;
 
+	assert(size > 0);
+
 	l = 0;
-	r = size - 1;
+	r = (int)size - 1;
 	c = r >> 1;
 	lx = dst[l];
 
@@ -84,7 +86,7 @@ static void bisort(void **dst, size_t start, size_t size, cmp_ptr_t cmp)
 		/* Else we need to find the right place, shift everything over, and squeeze in */
 		x = dst[i];
 		location = binsearch(dst, x, i, cmp);
-		for (j = i - 1; j >= location; j--) {
+		for (j = (int)i - 1; j >= location; j--) {
 			dst[j + 1] = dst[j];
 		}
 		dst[location] = x;
@@ -104,7 +106,7 @@ struct tsort_store {
 	void **storage;
 };
 
-static void reverse_elements(void **dst, int start, int end)
+static void reverse_elements(void **dst, ssize_t start, ssize_t end)
 {
 	while (start < end) {
 		void *tmp = dst[start];
@@ -116,7 +118,7 @@ static void reverse_elements(void **dst, int start, int end)
 	}
 }
 
-static int count_run(void **dst, ssize_t start, ssize_t size, struct tsort_store *store)
+static ssize_t count_run(void **dst, ssize_t start, ssize_t size, struct tsort_store *store)
 {
 	ssize_t curr = start + 2;
 
@@ -148,7 +150,7 @@ static int count_run(void **dst, ssize_t start, ssize_t size, struct tsort_store
 	}
 }
 
-static int compute_minrun(size_t n)
+static size_t compute_minrun(size_t n)
 {
 	int r = 0;
 	while (n >= 64) {
@@ -158,19 +160,19 @@ static int compute_minrun(size_t n)
 	return n + r;
 }
 
-static int check_invariant(struct tsort_run *stack, int stack_curr)
+static int check_invariant(struct tsort_run *stack, ssize_t stack_curr)
 {
 	if (stack_curr < 2)
 		return 1;
 
 	else if (stack_curr == 2) {
-		const int A = stack[stack_curr - 2].length;
-		const int B = stack[stack_curr - 1].length;
+		const ssize_t A = stack[stack_curr - 2].length;
+		const ssize_t B = stack[stack_curr - 1].length;
 		return (A > B);
 	} else {
-		const int A = stack[stack_curr - 3].length;
-		const int B = stack[stack_curr - 2].length;
-		const int C = stack[stack_curr - 1].length;
+		const ssize_t A = stack[stack_curr - 3].length;
+		const ssize_t B = stack[stack_curr - 2].length;
+		const ssize_t C = stack[stack_curr - 1].length;
 		return !((A <= B + C) || (B <= C));
 	}
 }
@@ -195,7 +197,7 @@ static int resize(struct tsort_store *store, size_t new_size)
 	return 0;
 }
 
-static void merge(void **dst, const struct tsort_run *stack, int stack_curr, struct tsort_store *store)
+static void merge(void **dst, const struct tsort_run *stack, ssize_t stack_curr, struct tsort_store *store)
 {
 	const ssize_t A = stack[stack_curr - 2].length;
 	const ssize_t B = stack[stack_curr - 1].length;
@@ -343,7 +345,7 @@ void git__tsort(void **dst, size_t size, cmp_ptr_t cmp)
 	}
 
 	/* compute the minimum run length */
-	minrun = compute_minrun(size);
+	minrun = (ssize_t)compute_minrun(size);
 
 	/* temporary storage for merges */
 	store->alloc = 0;
diff --git a/src/util.c b/src/util.c
index 81ad106..2cf7b15 100644
--- a/src/util.c
+++ b/src/util.c
@@ -391,10 +391,11 @@ int git__bsearch(
 	int (*compare)(const void *, const void *),
 	size_t *position)
 {
-	int lim, cmp = -1;
+	unsigned int lim;
+	int cmp = -1;
 	void **part, **base = array;
 
-	for (lim = array_len; lim != 0; lim >>= 1) {
+	for (lim = (unsigned int)array_len; lim != 0; lim >>= 1) {
 		part = base + (lim >> 1);
 		cmp = (*compare)(key, *part);
 		if (cmp == 0) {
diff --git a/src/vector.c b/src/vector.c
index d73c2b4..304f324 100644
--- a/src/vector.c
+++ b/src/vector.c
@@ -10,7 +10,7 @@
 #include "vector.h"
 
 static const double resize_factor = 1.75;
-static const size_t minimum_size = 8;
+static const unsigned int minimum_size = 8;
 
 static int resize_vector(git_vector *v)
 {
diff --git a/src/win32/posix.h b/src/win32/posix.h
index 60adc96..d13d3e3 100644
--- a/src/win32/posix.h
+++ b/src/win32/posix.h
@@ -49,5 +49,7 @@ extern int p_open(const char *path, int flags);
 extern int p_creat(const char *path, mode_t mode);
 extern int p_getcwd(char *buffer_out, size_t size);
 extern int p_rename(const char *from, const char *to);
+extern int p_recv(GIT_SOCKET socket, void *buffer, size_t length, int flags);
+extern int p_send(GIT_SOCKET socket, const void *buffer, size_t length, int flags);
 
 #endif
diff --git a/src/win32/posix_w32.c b/src/win32/posix_w32.c
index c6b36a8..8af6641 100644
--- a/src/win32/posix_w32.c
+++ b/src/win32/posix_w32.c
@@ -4,7 +4,7 @@
  * This file is part of libgit2, distributed under the GNU GPL v2 with
  * a Linking Exception. For full terms see the included COPYING file.
  */
-#include "posix.h"
+#include "../posix.h"
 #include "path.h"
 #include "utf-conv.h"
 #include <errno.h>
@@ -179,11 +179,11 @@ int p_readlink(const char *link, char *target, size_t target_len)
 	target_w = (wchar_t*)git__malloc(target_len * sizeof(wchar_t));
 	GITERR_CHECK_ALLOC(target_w);
 
-	dwRet = pGetFinalPath(hFile, target_w, target_len, 0x0);
+	dwRet = pGetFinalPath(hFile, target_w, (DWORD)target_len, 0x0);
 	if (dwRet == 0 ||
 		dwRet >= target_len ||
 		!WideCharToMultiByte(CP_UTF8, 0, target_w, -1, target,
-			target_len * sizeof(char), NULL, NULL))
+			(int)(target_len * sizeof(char)), NULL, NULL))
 		error = -1;
 
 	git__free(target_w);
@@ -241,13 +241,19 @@ int p_creat(const char *path, mode_t mode)
 
 int p_getcwd(char *buffer_out, size_t size)
 {
-	wchar_t* buf = (wchar_t*)git__malloc(sizeof(wchar_t) * (int)size);
 	int ret;
+	wchar_t* buf;
+
+	if ((size_t)((int)size) != size)
+		return -1;
+
+	buf = (wchar_t*)git__malloc(sizeof(wchar_t) * (int)size);
+	GITERR_CHECK_ALLOC(buf);
 
 	_wgetcwd(buf, (int)size);
 
 	ret = WideCharToMultiByte(
-		CP_UTF8, 0, buf, -1, buffer_out, size, NULL, NULL);
+		CP_UTF8, 0, buf, -1, buffer_out, (int)size, NULL, NULL);
 
 	git__free(buf);
 	return !ret ? -1 : 0;
@@ -421,3 +427,19 @@ int p_rename(const char *from, const char *to)
 
 	return ret;
 }
+
+int p_recv(GIT_SOCKET socket, void *buffer, size_t length, int flags)
+{
+	if ((size_t)((int)length) != length)
+		return -1; /* giterr_set will be done by caller */
+
+	return recv(socket, buffer, (int)length, flags);
+}
+
+int p_send(GIT_SOCKET socket, const void *buffer, size_t length, int flags)
+{
+	if ((size_t)((int)length) != length)
+		return -1; /* giterr_set will be done by caller */
+
+	return send(socket, buffer, (int)length, flags);
+}
diff --git a/src/win32/utf-conv.c b/src/win32/utf-conv.c
index f00f5be..fbcb69d 100644
--- a/src/win32/utf-conv.c
+++ b/src/win32/utf-conv.c
@@ -31,27 +31,23 @@ void gitwin_set_utf8(void)
 wchar_t* gitwin_to_utf16(const char* str)
 {
 	wchar_t* ret;
-	int cb;
+	size_t cb;
 
 	if (!str)
 		return NULL;
 
 	cb = strlen(str) * sizeof(wchar_t);
-	if (cb == 0) {
-		ret = (wchar_t*)git__malloc(sizeof(wchar_t));
-		if (ret)
-			ret[0] = 0;
-		return ret;
-	}
+	if (cb == 0)
+		return (wchar_t *)git__calloc(1, sizeof(wchar_t));
 
 	/* Add space for null terminator */
 	cb += sizeof(wchar_t);
 
-	ret = (wchar_t*)git__malloc(cb);
+	ret = (wchar_t *)git__malloc(cb);
 	if (!ret)
 		return NULL;
 
-	if (MultiByteToWideChar(_active_codepage, 0, str, -1, ret, cb) == 0) {
+	if (MultiByteToWideChar(_active_codepage, 0, str, -1, ret, (int)cb) == 0) {
 		giterr_set(GITERR_OS, "Could not convert string to UTF-16");
 		git__free(ret);
 		ret = NULL;
@@ -62,7 +58,7 @@ wchar_t* gitwin_to_utf16(const char* str)
 
 int gitwin_append_utf16(wchar_t *buffer, const char *str, size_t len)
 {
-	int result = MultiByteToWideChar(_active_codepage, 0, str, -1, buffer, len);
+	int result = MultiByteToWideChar(_active_codepage, 0, str, -1, buffer, (int)len);
 	if (result == 0)
 		giterr_set(GITERR_OS, "Could not convert string to UTF-16");
 	return result;
@@ -71,19 +67,14 @@ int gitwin_append_utf16(wchar_t *buffer, const char *str, size_t len)
 char* gitwin_from_utf16(const wchar_t* str)
 {
 	char* ret;
-	int cb;
+	size_t cb;
 
-	if (!str) {
+	if (!str)
 		return NULL;
-	}
 
 	cb = wcslen(str) * sizeof(char);
-	if (cb == 0) {
-		ret = (char*)git__malloc(sizeof(char));
-		if (ret)
-			ret[0] = 0;
-		return ret;
-	}
+	if (cb == 0)
+		return (char *)git__calloc(1, sizeof(char));
 
 	/* Add space for null terminator */
 	cb += sizeof(char);
@@ -92,7 +83,7 @@ char* gitwin_from_utf16(const wchar_t* str)
 	if (!ret)
 		return NULL;
 
-	if (WideCharToMultiByte(_active_codepage, 0, str, -1, ret, cb, NULL, NULL) == 0) {
+	if (WideCharToMultiByte(_active_codepage, 0, str, -1, ret, (int)cb, NULL, NULL) == 0) {
 		giterr_set(GITERR_OS, "Could not convert string to UTF-8");
 		git__free(ret);
 		ret = NULL;
diff --git a/src/xdiff/xemit.c b/src/xdiff/xemit.c
index 8b7d417..e3e63d9 100644
--- a/src/xdiff/xemit.c
+++ b/src/xdiff/xemit.c
@@ -40,7 +40,7 @@ static long xdl_get_rec(xdfile_t *xdf, long ri, char const **rec) {
 
 
 static int xdl_emit_record(xdfile_t *xdf, long ri, char const *pre, xdemitcb_t *ecb) {
-	long size, psize = strlen(pre);
+	long size, psize = (long)strlen(pre);
 	char const *rec;
 
 	size = xdl_get_rec(xdf, ri, &rec);
diff --git a/src/xdiff/xmerge.c b/src/xdiff/xmerge.c
index 9e13b25..84e4246 100644
--- a/src/xdiff/xmerge.c
+++ b/src/xdiff/xmerge.c
@@ -149,9 +149,9 @@ static int fill_conflict_hunk(xdfenv_t *xe1, const char *name1,
 			      int size, int i, int style,
 			      xdmerge_t *m, char *dest, int marker_size)
 {
-	int marker1_size = (name1 ? strlen(name1) + 1 : 0);
-	int marker2_size = (name2 ? strlen(name2) + 1 : 0);
-	int marker3_size = (name3 ? strlen(name3) + 1 : 0);
+	int marker1_size = (name1 ? (int)strlen(name1) + 1 : 0);
+	int marker2_size = (name2 ? (int)strlen(name2) + 1 : 0);
+	int marker3_size = (name3 ? (int)strlen(name3) + 1 : 0);
 
 	if (marker_size <= 0)
 		marker_size = DEFAULT_CONFLICT_MARKER_SIZE;
diff --git a/src/xdiff/xutils.c b/src/xdiff/xutils.c
index 9dea04b..bb7bdee 100644
--- a/src/xdiff/xutils.c
+++ b/src/xdiff/xutils.c
@@ -62,14 +62,14 @@ int xdl_emit_diffrec(char const *rec, long size, char const *pre, long psize,
 
 void *xdl_mmfile_first(mmfile_t *mmf, long *size)
 {
-	*size = mmf->size;
+	*size = (long)mmf->size;
 	return mmf->ptr;
 }
 
 
 long xdl_mmfile_size(mmfile_t *mmf)
 {
-	return mmf->size;
+	return (long)mmf->size;
 }
 
 
@@ -321,7 +321,7 @@ int xdl_num_out(char *out, long val) {
 		*str++ = '0';
 	*str = '\0';
 
-	return str - out;
+	return (int)(str - out);
 }
 
 
diff --git a/tests-clar/attr/attr_expect.h b/tests-clar/attr/attr_expect.h
index b064eac..df1e104 100644
--- a/tests-clar/attr/attr_expect.h
+++ b/tests-clar/attr/attr_expect.h
@@ -34,7 +34,7 @@ GIT_INLINE(void) attr_check_expected(
 		break;
 
 	case EXPECT_STRING:
-		cl_assert_strequal(expected_str, value);
+		cl_assert_equal_s(expected_str, value);
 		break;
 	}
 }
diff --git a/tests-clar/attr/file.c b/tests-clar/attr/file.c
index 6aeaa51..7fede50 100644
--- a/tests-clar/attr/file.c
+++ b/tests-clar/attr/file.c
@@ -13,19 +13,19 @@ void test_attr_file__simple_read(void)
 
 	cl_git_pass(git_attr_file__new(&file));
 	cl_git_pass(git_attr_file__from_file(NULL, cl_fixture("attr/attr0"), file));
-	cl_assert_strequal(cl_fixture("attr/attr0"), file->path);
+	cl_assert_equal_s(cl_fixture("attr/attr0"), file->path);
 	cl_assert(file->rules.length == 1);
 
 	rule = get_rule(0);
 	cl_assert(rule != NULL);
-	cl_assert_strequal("*", rule->match.pattern);
+	cl_assert_equal_s("*", rule->match.pattern);
 	cl_assert(rule->match.length == 1);
 	cl_assert((rule->match.flags & GIT_ATTR_FNMATCH_HASWILD) != 0);
 
 	cl_assert(rule->assigns.length == 1);
 	assign = get_assign(rule, 0);
 	cl_assert(assign != NULL);
-	cl_assert_strequal("binary", assign->name);
+	cl_assert_equal_s("binary", assign->name);
 	cl_assert(GIT_ATTR_TRUE(assign->value));
 	cl_assert(!assign->is_allocated);
 
@@ -40,7 +40,7 @@ void test_attr_file__match_variants(void)
 
 	cl_git_pass(git_attr_file__new(&file));
 	cl_git_pass(git_attr_file__from_file(NULL, cl_fixture("attr/attr1"), file));
-	cl_assert_strequal(cl_fixture("attr/attr1"), file->path);
+	cl_assert_equal_s(cl_fixture("attr/attr1"), file->path);
 	cl_assert(file->rules.length == 10);
 
 	/* let's do a thorough check of this rule, then just verify
@@ -48,53 +48,53 @@ void test_attr_file__match_variants(void)
 	 */
 	rule = get_rule(0);
 	cl_assert(rule);
-	cl_assert_strequal("pat0", rule->match.pattern);
+	cl_assert_equal_s("pat0", rule->match.pattern);
 	cl_assert(rule->match.length == strlen("pat0"));
 	cl_assert(rule->match.flags == 0);
 	cl_assert(rule->assigns.length == 1);
 	assign = get_assign(rule,0);
-	cl_assert_strequal("attr0", assign->name);
+	cl_assert_equal_s("attr0", assign->name);
 	cl_assert(assign->name_hash == git_attr_file__name_hash(assign->name));
 	cl_assert(GIT_ATTR_TRUE(assign->value));
 	cl_assert(!assign->is_allocated);
 
 	rule = get_rule(1);
-	cl_assert_strequal("pat1", rule->match.pattern);
+	cl_assert_equal_s("pat1", rule->match.pattern);
 	cl_assert(rule->match.length == strlen("pat1"));
 	cl_assert(rule->match.flags == GIT_ATTR_FNMATCH_NEGATIVE);
 
 	rule = get_rule(2);
-	cl_assert_strequal("pat2", rule->match.pattern);
+	cl_assert_equal_s("pat2", rule->match.pattern);
 	cl_assert(rule->match.length == strlen("pat2"));
 	cl_assert(rule->match.flags == GIT_ATTR_FNMATCH_DIRECTORY);
 
 	rule = get_rule(3);
-	cl_assert_strequal("pat3dir/pat3file", rule->match.pattern);
+	cl_assert_equal_s("pat3dir/pat3file", rule->match.pattern);
 	cl_assert(rule->match.flags == GIT_ATTR_FNMATCH_FULLPATH);
 
 	rule = get_rule(4);
-	cl_assert_strequal("pat4.*", rule->match.pattern);
+	cl_assert_equal_s("pat4.*", rule->match.pattern);
 	cl_assert((rule->match.flags & GIT_ATTR_FNMATCH_HASWILD) != 0);
 
 	rule = get_rule(5);
-	cl_assert_strequal("*.pat5", rule->match.pattern);
+	cl_assert_equal_s("*.pat5", rule->match.pattern);
 	cl_assert((rule->match.flags & GIT_ATTR_FNMATCH_HASWILD) != 0);
 
 	rule = get_rule(7);
-	cl_assert_strequal("pat7[a-e]??[xyz]", rule->match.pattern);
+	cl_assert_equal_s("pat7[a-e]??[xyz]", rule->match.pattern);
 	cl_assert(rule->assigns.length == 1);
 	cl_assert((rule->match.flags & GIT_ATTR_FNMATCH_HASWILD) != 0);
 	assign = get_assign(rule,0);
-	cl_assert_strequal("attr7", assign->name);
+	cl_assert_equal_s("attr7", assign->name);
 	cl_assert(GIT_ATTR_TRUE(assign->value));
 
 	rule = get_rule(8);
-	cl_assert_strequal("pat8 with spaces", rule->match.pattern);
+	cl_assert_equal_s("pat8 with spaces", rule->match.pattern);
 	cl_assert(rule->match.length == strlen("pat8 with spaces"));
 	cl_assert(rule->match.flags == 0);
 
 	rule = get_rule(9);
-	cl_assert_strequal("pat9", rule->match.pattern);
+	cl_assert_equal_s("pat9", rule->match.pattern);
 
 	git_attr_file__free(file);
 }
@@ -111,9 +111,9 @@ static void check_one_assign(
 	git_attr_rule *rule = get_rule(rule_idx);
 	git_attr_assignment *assign = get_assign(rule, assign_idx);
 
-	cl_assert_strequal(pattern, rule->match.pattern);
+	cl_assert_equal_s(pattern, rule->match.pattern);
 	cl_assert(rule->assigns.length == 1);
-	cl_assert_strequal(name, assign->name);
+	cl_assert_equal_s(name, assign->name);
 	cl_assert(assign->name_hash == git_attr_file__name_hash(assign->name));
 
 	attr_check_expected(expected, expected_str, assign->value);
@@ -127,7 +127,7 @@ void test_attr_file__assign_variants(void)
 
 	cl_git_pass(git_attr_file__new(&file));
 	cl_git_pass(git_attr_file__from_file(NULL, cl_fixture("attr/attr2"), file));
-	cl_assert_strequal(cl_fixture("attr/attr2"), file->path);
+	cl_assert_equal_s(cl_fixture("attr/attr2"), file->path);
 	cl_assert(file->rules.length == 11);
 
 	check_one_assign(file, 0, 0, "pat0", "simple", EXPECT_TRUE, NULL);
@@ -140,45 +140,45 @@ void test_attr_file__assign_variants(void)
 	check_one_assign(file, 7, 0, "pat6", "negempty", EXPECT_FALSE, NULL);
 
 	rule = get_rule(8);
-	cl_assert_strequal("pat7", rule->match.pattern);
+	cl_assert_equal_s("pat7", rule->match.pattern);
 	cl_assert(rule->assigns.length == 5);
 	/* assignments will be sorted by hash value, so we have to do
 	 * lookups by search instead of by position
 	 */
 	assign = git_attr_rule__lookup_assignment(rule, "multiple");
 	cl_assert(assign);
-	cl_assert_strequal("multiple", assign->name);
+	cl_assert_equal_s("multiple", assign->name);
 	cl_assert(GIT_ATTR_TRUE(assign->value));
 	assign = git_attr_rule__lookup_assignment(rule, "single");
 	cl_assert(assign);
-	cl_assert_strequal("single", assign->name);
+	cl_assert_equal_s("single", assign->name);
 	cl_assert(GIT_ATTR_FALSE(assign->value));
 	assign = git_attr_rule__lookup_assignment(rule, "values");
 	cl_assert(assign);
-	cl_assert_strequal("values", assign->name);
-	cl_assert_strequal("1", assign->value);
+	cl_assert_equal_s("values", assign->name);
+	cl_assert_equal_s("1", assign->value);
 	assign = git_attr_rule__lookup_assignment(rule, "also");
 	cl_assert(assign);
-	cl_assert_strequal("also", assign->name);
-	cl_assert_strequal("a-really-long-value/*", assign->value);
+	cl_assert_equal_s("also", assign->name);
+	cl_assert_equal_s("a-really-long-value/*", assign->value);
 	assign = git_attr_rule__lookup_assignment(rule, "happy");
 	cl_assert(assign);
-	cl_assert_strequal("happy", assign->name);
-	cl_assert_strequal("yes!", assign->value);
+	cl_assert_equal_s("happy", assign->name);
+	cl_assert_equal_s("yes!", assign->value);
 	assign = git_attr_rule__lookup_assignment(rule, "other");
 	cl_assert(!assign);
 
 	rule = get_rule(9);
-	cl_assert_strequal("pat8", rule->match.pattern);
+	cl_assert_equal_s("pat8", rule->match.pattern);
 	cl_assert(rule->assigns.length == 2);
 	assign = git_attr_rule__lookup_assignment(rule, "again");
 	cl_assert(assign);
-	cl_assert_strequal("again", assign->name);
+	cl_assert_equal_s("again", assign->name);
 	cl_assert(GIT_ATTR_TRUE(assign->value));
 	assign = git_attr_rule__lookup_assignment(rule, "another");
 	cl_assert(assign);
-	cl_assert_strequal("another", assign->name);
-	cl_assert_strequal("12321", assign->value);
+	cl_assert_equal_s("another", assign->name);
+	cl_assert_equal_s("12321", assign->value);
 
 	check_one_assign(file, 10, 0, "pat9", "at-eof", EXPECT_FALSE, NULL);
 
@@ -193,37 +193,37 @@ void test_attr_file__check_attr_examples(void)
 
 	cl_git_pass(git_attr_file__new(&file));
 	cl_git_pass(git_attr_file__from_file(NULL, cl_fixture("attr/attr3"), file));
-	cl_assert_strequal(cl_fixture("attr/attr3"), file->path);
+	cl_assert_equal_s(cl_fixture("attr/attr3"), file->path);
 	cl_assert(file->rules.length == 3);
 
 	rule = get_rule(0);
-	cl_assert_strequal("*.java", rule->match.pattern);
+	cl_assert_equal_s("*.java", rule->match.pattern);
 	cl_assert(rule->assigns.length == 3);
 	assign = git_attr_rule__lookup_assignment(rule, "diff");
-	cl_assert_strequal("diff", assign->name);
-	cl_assert_strequal("java", assign->value);
+	cl_assert_equal_s("diff", assign->name);
+	cl_assert_equal_s("java", assign->value);
 	assign = git_attr_rule__lookup_assignment(rule, "crlf");
-	cl_assert_strequal("crlf", assign->name);
+	cl_assert_equal_s("crlf", assign->name);
 	cl_assert(GIT_ATTR_FALSE(assign->value));
 	assign = git_attr_rule__lookup_assignment(rule, "myAttr");
-	cl_assert_strequal("myAttr", assign->name);
+	cl_assert_equal_s("myAttr", assign->name);
 	cl_assert(GIT_ATTR_TRUE(assign->value));
 	assign = git_attr_rule__lookup_assignment(rule, "missing");
 	cl_assert(assign == NULL);
 
 	rule = get_rule(1);
-	cl_assert_strequal("NoMyAttr.java", rule->match.pattern);
+	cl_assert_equal_s("NoMyAttr.java", rule->match.pattern);
 	cl_assert(rule->assigns.length == 1);
 	assign = get_assign(rule, 0);
-	cl_assert_strequal("myAttr", assign->name);
+	cl_assert_equal_s("myAttr", assign->name);
 	cl_assert(assign->value == NULL);
 
 	rule = get_rule(2);
-	cl_assert_strequal("README", rule->match.pattern);
+	cl_assert_equal_s("README", rule->match.pattern);
 	cl_assert(rule->assigns.length == 1);
 	assign = get_assign(rule, 0);
-	cl_assert_strequal("caveat", assign->name);
-	cl_assert_strequal("unspecified", assign->value);
+	cl_assert_equal_s("caveat", assign->name);
+	cl_assert_equal_s("unspecified", assign->value);
 
 	git_attr_file__free(file);
 }
diff --git a/tests-clar/attr/lookup.c b/tests-clar/attr/lookup.c
index 1939618..4ce80e9 100644
--- a/tests-clar/attr/lookup.c
+++ b/tests-clar/attr/lookup.c
@@ -11,12 +11,12 @@ void test_attr_lookup__simple(void)
 
 	cl_git_pass(git_attr_file__new(&file));
 	cl_git_pass(git_attr_file__from_file(NULL, cl_fixture("attr/attr0"), file));
-	cl_assert_strequal(cl_fixture("attr/attr0"), file->path);
+	cl_assert_equal_s(cl_fixture("attr/attr0"), file->path);
 	cl_assert(file->rules.length == 1);
 
 	cl_git_pass(git_attr_path__init(&path, "test", NULL));
-	cl_assert_strequal("test", path.path);
-	cl_assert_strequal("test", path.basename);
+	cl_assert_equal_s("test", path.path);
+	cl_assert_equal_s("test", path.basename);
 	cl_assert(!path.is_dir);
 
 	cl_git_pass(git_attr_file__lookup_one(file,&path,"binary",&value));
@@ -129,11 +129,11 @@ void test_attr_lookup__match_variants(void)
 
 	cl_git_pass(git_attr_file__new(&file));
 	cl_git_pass(git_attr_file__from_file(NULL, cl_fixture("attr/attr1"), file));
-	cl_assert_strequal(cl_fixture("attr/attr1"), file->path);
+	cl_assert_equal_s(cl_fixture("attr/attr1"), file->path);
 	cl_assert(file->rules.length == 10);
 
 	cl_git_pass(git_attr_path__init(&path, "/testing/for/pat0", NULL));
-	cl_assert_strequal("pat0", path.basename);
+	cl_assert_equal_s("pat0", path.basename);
 
 	run_test_cases(file, cases, 0);
 	run_test_cases(file, dir_cases, 1);
diff --git a/tests-clar/attr/repo.c b/tests-clar/attr/repo.c
index 5ff33d1..6dc13aa 100644
--- a/tests-clar/attr/repo.c
+++ b/tests-clar/attr/repo.c
@@ -101,7 +101,7 @@ void test_attr_repo__get_many(void)
 	cl_assert(GIT_ATTR_TRUE(values[0]));
 	cl_assert(GIT_ATTR_TRUE(values[1]));
 	cl_assert(GIT_ATTR_UNSPECIFIED(values[2]));
-	cl_assert_strequal("yes", values[3]);
+	cl_assert_equal_s("yes", values[3]);
 }
 
 static int count_attrs(
@@ -150,7 +150,7 @@ void test_attr_repo__manpage_example(void)
 	cl_assert(GIT_ATTR_FALSE(value));
 
 	cl_git_pass(git_attr_get(g_repo, "sub/abc", "merge", &value));
-	cl_assert_strequal("filfre", value);
+	cl_assert_equal_s("filfre", value);
 
 	cl_git_pass(git_attr_get(g_repo, "sub/abc", "frotz", &value));
 	cl_assert(GIT_ATTR_UNSPECIFIED(value));
@@ -177,13 +177,13 @@ void test_attr_repo__macros(void)
 	cl_assert(GIT_ATTR_TRUE(values[1]));
 	cl_assert(GIT_ATTR_FALSE(values[2]));
 	cl_assert(GIT_ATTR_UNSPECIFIED(values[3]));
-	cl_assert_strequal("77", values[4]);
+	cl_assert_equal_s("77", values[4]);
 
 	cl_git_pass(git_attr_get_many(g_repo, "macro_test", 3, names3, values));
 
 	cl_assert(GIT_ATTR_TRUE(values[0]));
 	cl_assert(GIT_ATTR_FALSE(values[1]));
-	cl_assert_strequal("answer", values[2]);
+	cl_assert_equal_s("answer", values[2]);
 }
 
 void test_attr_repo__bad_macros(void)
@@ -222,7 +222,7 @@ void test_attr_repo__bad_macros(void)
 	 *     -firstmacro secondmacro="hahaha" thirdmacro
 	 */
 	cl_assert(GIT_ATTR_FALSE(values[3]));
-	cl_assert_strequal("hahaha", values[4]);
+	cl_assert_equal_s("hahaha", values[4]);
 	cl_assert(GIT_ATTR_TRUE(values[5]));
 }
 
diff --git a/tests-clar/clar_libgit2.h b/tests-clar/clar_libgit2.h
index bb2feee..4d338ef 100644
--- a/tests-clar/clar_libgit2.h
+++ b/tests-clar/clar_libgit2.h
@@ -25,26 +25,6 @@
  */
 #define cl_git_fail(expr) cl_must_fail(expr)
 
-/**
- * Wrapper for string comparison that knows about nulls.
- */
-#define cl_assert_strequal(a,b) \
-	cl_assert_strequal_internal(a,b,__FILE__,__LINE__,"string mismatch: " #a " != " #b)
-
-GIT_INLINE(void) cl_assert_strequal_internal(
-	const char *a, const char *b, const char *file, int line, const char *err)
-{
-	int match = (a == NULL || b == NULL) ? (a == b) : (strcmp(a, b) == 0);
-	if (!match) {
-		char buf[4096];
-		snprintf(buf, 4096, "'%s' != '%s'", a, b);
-		clar__assert(0, file, line, err, buf, 1);
-	}
-}
-
-#define cl_assert_intequal(a,b) \
-	do { if ((a) != (b)) { char buf[128]; snprintf(buf,128,"%d != %d",(a),(b)); clar__assert(0,__FILE__,__LINE__,#a " != " #b,buf,1); } } while (0)
-
 /*
  * Some utility macros for building long strings
  */
diff --git a/tests-clar/core/buffer.c b/tests-clar/core/buffer.c
index 4ba7b66..9294ccd 100644
--- a/tests-clar/core/buffer.c
+++ b/tests-clar/core/buffer.c
@@ -19,11 +19,11 @@ void test_core_buffer__0(void)
 
 	git_buf_puts(&buf, test_string);
 	cl_assert(git_buf_oom(&buf) == 0);
-	cl_assert_strequal(test_string, git_buf_cstr(&buf));
+	cl_assert_equal_s(test_string, git_buf_cstr(&buf));
 
 	git_buf_puts(&buf, test_string);
 	cl_assert(git_buf_oom(&buf) == 0);
-	cl_assert_strequal(test_string_x2, git_buf_cstr(&buf));
+	cl_assert_equal_s(test_string_x2, git_buf_cstr(&buf));
 
 	git_buf_free(&buf);
 }
@@ -35,11 +35,11 @@ void test_core_buffer__1(void)
 
 	git_buf_printf(&buf, "%s %s %d ", "shoop", "da", 23);
 	cl_assert(git_buf_oom(&buf) == 0);
-	cl_assert_strequal("shoop da 23 ", git_buf_cstr(&buf));
+	cl_assert_equal_s("shoop da 23 ", git_buf_cstr(&buf));
 
 	git_buf_printf(&buf, "%s %d", "woop", 42);
 	cl_assert(git_buf_oom(&buf) == 0);
-	cl_assert_strequal("shoop da 23 woop 42", git_buf_cstr(&buf));
+	cl_assert_equal_s("shoop da 23 woop 42", git_buf_cstr(&buf));
 
 	git_buf_free(&buf);
 }
@@ -59,7 +59,7 @@ void test_core_buffer__2(void)
 	cl_assert(buf.asize == 0);
 
 	/* empty buffer should be empty string */
-	cl_assert_strequal("", git_buf_cstr(&buf));
+	cl_assert_equal_s("", git_buf_cstr(&buf));
 	cl_assert(buf.size == 0);
 	/* cl_assert(buf.asize == 0); -- should not assume what git_buf does */
 
@@ -71,38 +71,38 @@ void test_core_buffer__2(void)
 	/* add letter */
 	git_buf_putc(&buf, '+');
 	cl_assert(git_buf_oom(&buf) == 0);
-	cl_assert_strequal("+", git_buf_cstr(&buf));
+	cl_assert_equal_s("+", git_buf_cstr(&buf));
 
 	/* add letter again */
 	git_buf_putc(&buf, '+');
 	cl_assert(git_buf_oom(&buf) == 0);
-	cl_assert_strequal("++", git_buf_cstr(&buf));
+	cl_assert_equal_s("++", git_buf_cstr(&buf));
 
 	/* let's try that a few times */
 	for (i = 0; i < 16; ++i) {
 		git_buf_putc(&buf, '+');
 		cl_assert(git_buf_oom(&buf) == 0);
 	}
-	cl_assert_strequal("++++++++++++++++++", git_buf_cstr(&buf));
+	cl_assert_equal_s("++++++++++++++++++", git_buf_cstr(&buf));
 
 	git_buf_free(&buf);
 
 	/* add data */
 	git_buf_put(&buf, "xo", 2);
 	cl_assert(git_buf_oom(&buf) == 0);
-	cl_assert_strequal("xo", git_buf_cstr(&buf));
+	cl_assert_equal_s("xo", git_buf_cstr(&buf));
 
 	/* add letter again */
 	git_buf_put(&buf, "xo", 2);
 	cl_assert(git_buf_oom(&buf) == 0);
-	cl_assert_strequal("xoxo", git_buf_cstr(&buf));
+	cl_assert_equal_s("xoxo", git_buf_cstr(&buf));
 
 	/* let's try that a few times */
 	for (i = 0; i < 16; ++i) {
 		git_buf_put(&buf, "xo", 2);
 		cl_assert(git_buf_oom(&buf) == 0);
 	}
-	cl_assert_strequal("xoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxo",
+	cl_assert_equal_s("xoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxoxo",
 					   git_buf_cstr(&buf));
 
 	git_buf_free(&buf);
@@ -110,21 +110,21 @@ void test_core_buffer__2(void)
 	/* set to string */
 	git_buf_sets(&buf, test_string);
 	cl_assert(git_buf_oom(&buf) == 0);
-	cl_assert_strequal(test_string, git_buf_cstr(&buf));
+	cl_assert_equal_s(test_string, git_buf_cstr(&buf));
 
 	/* append string */
 	git_buf_puts(&buf, test_string);
 	cl_assert(git_buf_oom(&buf) == 0);
-	cl_assert_strequal(test_string_x2, git_buf_cstr(&buf));
+	cl_assert_equal_s(test_string_x2, git_buf_cstr(&buf));
 
 	/* set to string again (should overwrite - not append) */
 	git_buf_sets(&buf, test_string);
 	cl_assert(git_buf_oom(&buf) == 0);
-	cl_assert_strequal(test_string, git_buf_cstr(&buf));
+	cl_assert_equal_s(test_string, git_buf_cstr(&buf));
 
 	/* test clear */
 	git_buf_clear(&buf);
-	cl_assert_strequal("", git_buf_cstr(&buf));
+	cl_assert_equal_s("", git_buf_cstr(&buf));
 
 	git_buf_free(&buf);
 
@@ -133,27 +133,27 @@ void test_core_buffer__2(void)
 	cl_assert(git_buf_oom(&buf) == 0);
 
 	git_buf_copy_cstr(data, sizeof(data), &buf);
-	cl_assert_strequal(REP4("0123456789"), data);
+	cl_assert_equal_s(REP4("0123456789"), data);
 	git_buf_copy_cstr(data, 11, &buf);
-	cl_assert_strequal("0123456789", data);
+	cl_assert_equal_s("0123456789", data);
 	git_buf_copy_cstr(data, 3, &buf);
-	cl_assert_strequal("01", data);
+	cl_assert_equal_s("01", data);
 	git_buf_copy_cstr(data, 1, &buf);
-	cl_assert_strequal("", data);
+	cl_assert_equal_s("", data);
 
 	git_buf_copy_cstr(data, sizeof(data), &buf);
-	cl_assert_strequal(REP4("0123456789"), data);
+	cl_assert_equal_s(REP4("0123456789"), data);
 
 	git_buf_sets(&buf, REP256("x"));
 	git_buf_copy_cstr(data, sizeof(data), &buf);
 	/* since sizeof(data) == 128, only 127 bytes should be copied */
-	cl_assert_strequal(REP4(REP16("x")) REP16("x") REP16("x")
+	cl_assert_equal_s(REP4(REP16("x")) REP16("x") REP16("x")
 					   REP16("x") "xxxxxxxxxxxxxxx", data);
 
 	git_buf_free(&buf);
 
 	git_buf_copy_cstr(data, sizeof(data), &buf);
-	cl_assert_strequal("", data);
+	cl_assert_equal_s("", data);
 }
 
 /* let's do some tests with larger buffers to push our limits */
@@ -164,17 +164,17 @@ void test_core_buffer__3(void)
 	/* set to string */
 	git_buf_set(&buf, test_4096, 4096);
 	cl_assert(git_buf_oom(&buf) == 0);
-	cl_assert_strequal(test_4096, git_buf_cstr(&buf));
+	cl_assert_equal_s(test_4096, git_buf_cstr(&buf));
 
 	/* append string */
 	git_buf_puts(&buf, test_4096);
 	cl_assert(git_buf_oom(&buf) == 0);
-	cl_assert_strequal(test_8192, git_buf_cstr(&buf));
+	cl_assert_equal_s(test_8192, git_buf_cstr(&buf));
 
 	/* set to string again (should overwrite - not append) */
 	git_buf_set(&buf, test_4096, 4096);
 	cl_assert(git_buf_oom(&buf) == 0);
-	cl_assert_strequal(test_4096, git_buf_cstr(&buf));
+	cl_assert_equal_s(test_4096, git_buf_cstr(&buf));
 
 	git_buf_free(&buf);
 }
@@ -192,22 +192,22 @@ void test_core_buffer__4(void)
 		cl_assert(strlen(git_buf_cstr(&buf)) == (size_t)((i + 1) * 2));
 	}
 	/* we have appended 1234 10x and removed the first 20 letters */
-	cl_assert_strequal("12341234123412341234", git_buf_cstr(&buf));
+	cl_assert_equal_s("12341234123412341234", git_buf_cstr(&buf));
 
 	git_buf_consume(&buf, NULL);
-	cl_assert_strequal("12341234123412341234", git_buf_cstr(&buf));
+	cl_assert_equal_s("12341234123412341234", git_buf_cstr(&buf));
 
 	git_buf_consume(&buf, "invalid pointer");
-	cl_assert_strequal("12341234123412341234", git_buf_cstr(&buf));
+	cl_assert_equal_s("12341234123412341234", git_buf_cstr(&buf));
 
 	git_buf_consume(&buf, buf.ptr);
-	cl_assert_strequal("12341234123412341234", git_buf_cstr(&buf));
+	cl_assert_equal_s("12341234123412341234", git_buf_cstr(&buf));
 
 	git_buf_consume(&buf, buf.ptr + 1);
-	cl_assert_strequal("2341234123412341234", git_buf_cstr(&buf));
+	cl_assert_equal_s("2341234123412341234", git_buf_cstr(&buf));
 
 	git_buf_consume(&buf, buf.ptr + buf.size);
-	cl_assert_strequal("", git_buf_cstr(&buf));
+	cl_assert_equal_s("", git_buf_cstr(&buf));
 
 	git_buf_free(&buf);
 }
@@ -227,7 +227,7 @@ check_buf_append(
 	cl_assert(git_buf_oom(&tgt) == 0);
 	git_buf_puts(&tgt, data_b);
 	cl_assert(git_buf_oom(&tgt) == 0);
-	cl_assert_strequal(expected_data, git_buf_cstr(&tgt));
+	cl_assert_equal_s(expected_data, git_buf_cstr(&tgt));
 	cl_assert(tgt.size == expected_size);
 	if (expected_asize > 0)
 		cl_assert(tgt.asize == expected_asize);
@@ -250,27 +250,27 @@ check_buf_append_abc(
 
 	git_buf_sets(&buf, buf_a);
 	cl_assert(git_buf_oom(&buf) == 0);
-	cl_assert_strequal(buf_a, git_buf_cstr(&buf));
+	cl_assert_equal_s(buf_a, git_buf_cstr(&buf));
 
 	git_buf_puts(&buf, buf_b);
 	cl_assert(git_buf_oom(&buf) == 0);
-	cl_assert_strequal(expected_ab, git_buf_cstr(&buf));
+	cl_assert_equal_s(expected_ab, git_buf_cstr(&buf));
 
 	git_buf_puts(&buf, buf_c);
 	cl_assert(git_buf_oom(&buf) == 0);
-	cl_assert_strequal(expected_abc, git_buf_cstr(&buf));
+	cl_assert_equal_s(expected_abc, git_buf_cstr(&buf));
 
 	git_buf_puts(&buf, buf_a);
 	cl_assert(git_buf_oom(&buf) == 0);
-	cl_assert_strequal(expected_abca, git_buf_cstr(&buf));
+	cl_assert_equal_s(expected_abca, git_buf_cstr(&buf));
 
 	git_buf_puts(&buf, buf_b);
 	cl_assert(git_buf_oom(&buf) == 0);
-	cl_assert_strequal(expected_abcab, git_buf_cstr(&buf));
+	cl_assert_equal_s(expected_abcab, git_buf_cstr(&buf));
 
 	git_buf_puts(&buf, buf_c);
 	cl_assert(git_buf_oom(&buf) == 0);
-	cl_assert_strequal(expected_abcabc, git_buf_cstr(&buf));
+	cl_assert_equal_s(expected_abcabc, git_buf_cstr(&buf));
 
 	git_buf_free(&buf);
 }
@@ -330,13 +330,13 @@ void test_core_buffer__6(void)
 	git_buf_sets(&b, "bar");
 	cl_assert(git_buf_oom(&b) == 0);
 
-	cl_assert_strequal("foo", git_buf_cstr(&a));
-	cl_assert_strequal("bar", git_buf_cstr(&b));
+	cl_assert_equal_s("foo", git_buf_cstr(&a));
+	cl_assert_equal_s("bar", git_buf_cstr(&b));
 
 	git_buf_swap(&a, &b);
 
-	cl_assert_strequal("bar", git_buf_cstr(&a));
-	cl_assert_strequal("foo", git_buf_cstr(&b));
+	cl_assert_equal_s("bar", git_buf_cstr(&a));
+	cl_assert_equal_s("foo", git_buf_cstr(&b));
 
 	git_buf_free(&a);
 	git_buf_free(&b);
@@ -352,25 +352,25 @@ void test_core_buffer__7(void)
 
 	git_buf_sets(&a, "foo");
 	cl_assert(git_buf_oom(&a) == 0);
-	cl_assert_strequal("foo", git_buf_cstr(&a));
+	cl_assert_equal_s("foo", git_buf_cstr(&a));
 
 	b = git_buf_detach(&a);
 
-	cl_assert_strequal("foo", b);
-	cl_assert_strequal("", a.ptr);
+	cl_assert_equal_s("foo", b);
+	cl_assert_equal_s("", a.ptr);
 	git__free(b);
 
 	b = git_buf_detach(&a);
 
-	cl_assert_strequal(NULL, b);
-	cl_assert_strequal("", a.ptr);
+	cl_assert_equal_s(NULL, b);
+	cl_assert_equal_s("", a.ptr);
 
 	git_buf_free(&a);
 
 	b = git__strdup(fun);
 	git_buf_attach(&a, b, 0);
 
-	cl_assert_strequal(fun, a.ptr);
+	cl_assert_equal_s(fun, a.ptr);
 	cl_assert(a.size == strlen(fun));
 	cl_assert(a.asize == strlen(fun) + 1);
 
@@ -379,7 +379,7 @@ void test_core_buffer__7(void)
 	b = git__strdup(fun);
 	git_buf_attach(&a, b, strlen(fun) + 1);
 
-	cl_assert_strequal(fun, a.ptr);
+	cl_assert_equal_s(fun, a.ptr);
 	cl_assert(a.size == strlen(fun));
 	cl_assert(a.asize == strlen(fun) + 1);
 
@@ -398,7 +398,7 @@ check_joinbuf_2(
 
 	git_buf_join(&buf, sep, a, b);
 	cl_assert(git_buf_oom(&buf) == 0);
-	cl_assert_strequal(expected, git_buf_cstr(&buf));
+	cl_assert_equal_s(expected, git_buf_cstr(&buf));
 	git_buf_free(&buf);
 }
 
@@ -416,7 +416,7 @@ check_joinbuf_n_2(
 
 	git_buf_join_n(&buf, sep, 1, b);
 	cl_assert(git_buf_oom(&buf) == 0);
-	cl_assert_strequal(expected, git_buf_cstr(&buf));
+	cl_assert_equal_s(expected, git_buf_cstr(&buf));
 
 	git_buf_free(&buf);
 }
@@ -433,7 +433,7 @@ check_joinbuf_n_4(
 	git_buf buf = GIT_BUF_INIT;
 	git_buf_join_n(&buf, sep, 4, a, b, c, d);
 	cl_assert(git_buf_oom(&buf) == 0);
-	cl_assert_strequal(expected, git_buf_cstr(&buf));
+	cl_assert_equal_s(expected, git_buf_cstr(&buf));
 	git_buf_free(&buf);
 }
 
@@ -444,15 +444,15 @@ void test_core_buffer__8(void)
 
 	git_buf_join_n(&a, '/', 1, "foo");
 	cl_assert(git_buf_oom(&a) == 0);
-	cl_assert_strequal("foo", git_buf_cstr(&a));
+	cl_assert_equal_s("foo", git_buf_cstr(&a));
 
 	git_buf_join_n(&a, '/', 1, "bar");
 	cl_assert(git_buf_oom(&a) == 0);
-	cl_assert_strequal("foo/bar", git_buf_cstr(&a));
+	cl_assert_equal_s("foo/bar", git_buf_cstr(&a));
 
 	git_buf_join_n(&a, '/', 1, "baz");
 	cl_assert(git_buf_oom(&a) == 0);
-	cl_assert_strequal("foo/bar/baz", git_buf_cstr(&a));
+	cl_assert_equal_s("foo/bar/baz", git_buf_cstr(&a));
 
 	git_buf_free(&a);
 
@@ -536,7 +536,7 @@ void test_core_buffer__9(void)
 		for (j = 0; j < sizeof(b) / sizeof(char*); ++j) {
 			for (i = 0; i < sizeof(a) / sizeof(char*); ++i) {
 				git_buf_join(&buf, separator, a[i], b[j]);
-				cl_assert_strequal(*expect, buf.ptr);
+				cl_assert_equal_s(*expect, buf.ptr);
 				expect++;
 			}
 		}
@@ -550,14 +550,14 @@ void test_core_buffer__10(void)
 	git_buf a = GIT_BUF_INIT;
 
 	cl_git_pass(git_buf_join_n(&a, '/', 1, "test"));
-	cl_assert_strequal(a.ptr, "test");
+	cl_assert_equal_s(a.ptr, "test");
 	cl_git_pass(git_buf_join_n(&a, '/', 1, "string"));
-	cl_assert_strequal(a.ptr, "test/string");
+	cl_assert_equal_s(a.ptr, "test/string");
 	git_buf_clear(&a);
 	cl_git_pass(git_buf_join_n(&a, '/', 3, "test", "string", "join"));
-	cl_assert_strequal(a.ptr, "test/string/join");
+	cl_assert_equal_s(a.ptr, "test/string/join");
 	cl_git_pass(git_buf_join_n(&a, '/', 2, a.ptr, "more"));
-	cl_assert_strequal(a.ptr, "test/string/join/test/string/join/more");
+	cl_assert_equal_s(a.ptr, "test/string/join/test/string/join/more");
 
 	git_buf_free(&a);
 }
diff --git a/tests-clar/core/errors.c b/tests-clar/core/errors.c
index c781000..78f811c 100644
--- a/tests-clar/core/errors.c
+++ b/tests-clar/core/errors.c
@@ -42,12 +42,14 @@ void test_core_errors__new_school(void)
 	cl_assert(str_in_error != NULL);
 
 	git_error_clear();
+	cl_assert(git_error_last() == NULL);
 
-	{
+	do {
 		struct stat st;
+		memset(&st, 0, sizeof(st));
 		assert(p_lstat("this_file_does_not_exist", &st) < 0);
 		GIT_UNUSED(st);
-	}
+	} while (false);
 	giterr_set(GITERR_OS, "stat failed"); /* internal fn */
 
 	cl_assert(git_error_last() != NULL);
diff --git a/tests-clar/core/path.c b/tests-clar/core/path.c
index 2654ef7..f02e0f7 100644
--- a/tests-clar/core/path.c
+++ b/tests-clar/core/path.c
@@ -8,11 +8,11 @@ check_dirname(const char *A, const char *B)
 	char *dir2;
 
 	cl_assert(git_path_dirname_r(&dir, A) >= 0);
-	cl_assert_strequal(B, dir.ptr);
+	cl_assert_equal_s(B, dir.ptr);
 	git_buf_free(&dir);
 
 	cl_assert((dir2 = git_path_dirname(A)) != NULL);
-	cl_assert_strequal(B, dir2);
+	cl_assert_equal_s(B, dir2);
 	git__free(dir2);
 }
 
@@ -23,11 +23,11 @@ check_basename(const char *A, const char *B)
 	char *base2;
 
 	cl_assert(git_path_basename_r(&base, A) >= 0);
-	cl_assert_strequal(B, base.ptr);
+	cl_assert_equal_s(B, base.ptr);
 	git_buf_free(&base);
 
 	cl_assert((base2 = git_path_basename(A)) != NULL);
-	cl_assert_strequal(B, base2);
+	cl_assert_equal_s(B, base2);
 	git__free(base2);
 }
 
@@ -37,7 +37,7 @@ check_topdir(const char *A, const char *B)
 	const char *dir;
 
 	cl_assert((dir = git_path_topdir(A)) != NULL);
-	cl_assert_strequal(B, dir);
+	cl_assert_equal_s(B, dir);
 }
 
 static void
@@ -46,7 +46,7 @@ check_joinpath(const char *path_a, const char *path_b, const char *expected_path
 	git_buf joined_path = GIT_BUF_INIT;
 
 	cl_git_pass(git_buf_joinpath(&joined_path, path_a, path_b));
-	cl_assert_strequal(expected_path, joined_path.ptr);
+	cl_assert_equal_s(expected_path, joined_path.ptr);
 
 	git_buf_free(&joined_path);
 }
@@ -63,7 +63,7 @@ check_joinpath_n(
 
 	cl_git_pass(git_buf_join_n(&joined_path, '/', 4,
 							   path_a, path_b, path_c, path_d));
-	cl_assert_strequal(expected_path, joined_path.ptr);
+	cl_assert_equal_s(expected_path, joined_path.ptr);
 
 	git_buf_free(&joined_path);
 }
@@ -189,7 +189,7 @@ check_path_to_dir(
 
 	git_buf_sets(&tgt, path);
 	cl_git_pass(git_path_to_dir(&tgt));
-	cl_assert_strequal(expected, tgt.ptr);
+	cl_assert_equal_s(expected, tgt.ptr);
 
 	git_buf_free(&tgt);
 }
@@ -197,16 +197,18 @@ check_path_to_dir(
 static void
 check_string_to_dir(
 	const char* path,
-	int         maxlen,
+	size_t      maxlen,
     const char* expected)
 {
-	int  len = strlen(path);
+	size_t len = strlen(path);
 	char *buf = git__malloc(len + 2);
+	cl_assert(buf);
+
 	strncpy(buf, path, len + 2);
 
 	git_path_string_to_dir(buf, maxlen);
 
-	cl_assert_strequal(expected, buf);
+	cl_assert_equal_s(expected, buf);
 
 	git__free(buf);
 }
@@ -247,28 +249,28 @@ void test_core_path__08_self_join(void)
 
 	asize = path.asize;
 	cl_git_pass(git_buf_sets(&path, "/foo"));
-	cl_assert_strequal(path.ptr, "/foo");
+	cl_assert_equal_s(path.ptr, "/foo");
 	cl_assert(asize < path.asize);
 
 	asize = path.asize;
 	cl_git_pass(git_buf_joinpath(&path, path.ptr, "this is a new string"));
-	cl_assert_strequal(path.ptr, "/foo/this is a new string");
+	cl_assert_equal_s(path.ptr, "/foo/this is a new string");
 	cl_assert(asize < path.asize);
 
 	asize = path.asize;
 	cl_git_pass(git_buf_joinpath(&path, path.ptr, "/grow the buffer, grow the buffer, grow the buffer"));
-	cl_assert_strequal(path.ptr, "/foo/this is a new string/grow the buffer, grow the buffer, grow the buffer");
+	cl_assert_equal_s(path.ptr, "/foo/this is a new string/grow the buffer, grow the buffer, grow the buffer");
 	cl_assert(asize < path.asize);
 
 	git_buf_free(&path);
 	cl_git_pass(git_buf_sets(&path, "/foo/bar"));
 
 	cl_git_pass(git_buf_joinpath(&path, path.ptr + 4, "baz"));
-	cl_assert_strequal(path.ptr, "/bar/baz");
+	cl_assert_equal_s(path.ptr, "/bar/baz");
 
 	asize = path.asize;
 	cl_git_pass(git_buf_joinpath(&path, path.ptr + 4, "somethinglongenoughtorealloc"));
-	cl_assert_strequal(path.ptr, "/baz/somethinglongenoughtorealloc");
+	cl_assert_equal_s(path.ptr, "/baz/somethinglongenoughtorealloc");
 	cl_assert(asize < path.asize);
 	
 	git_buf_free(&path);
@@ -279,7 +281,7 @@ static void check_percent_decoding(const char *expected_result, const char *inpu
 	git_buf buf = GIT_BUF_INIT;
 
 	cl_git_pass(git__percent_decode(&buf, input));
-	cl_assert_strequal(expected_result, git_buf_cstr(&buf));
+	cl_assert_equal_s(expected_result, git_buf_cstr(&buf));
 
 	git_buf_free(&buf);
 }
@@ -306,7 +308,7 @@ static void check_fromurl(const char *expected_result, const char *input, int sh
 
 	if (!should_fail) {
 		cl_git_pass(git_path_fromurl(&buf, input));
-		cl_assert_strequal(expected_result, git_buf_cstr(&buf));
+		cl_assert_equal_s(expected_result, git_buf_cstr(&buf));
 	} else
 		cl_git_fail(git_path_fromurl(&buf, input));
 
@@ -346,7 +348,7 @@ static int check_one_walkup_step(void *ref, git_buf *path)
 {
 	check_walkup_info *info = (check_walkup_info *)ref;
 	cl_assert(info->expect[info->expect_idx] != NULL);
-	cl_assert_strequal(info->expect[info->expect_idx], path->ptr);
+	cl_assert_equal_s(info->expect[info->expect_idx], path->ptr);
 	info->expect_idx++;
 	return 0;
 }
@@ -380,7 +382,7 @@ void test_core_path__11_walkup(void)
 			git_path_walk_up(&p, root[j], check_one_walkup_step, &info)
 		);
 
-		cl_assert_strequal(p.ptr, expect[i]);
+		cl_assert_equal_s(p.ptr, expect[i]);
 
 		/* skip to next run of expectations */
 		while (expect[i] != NULL) i++;
diff --git a/tests-clar/diff/diff_helpers.c b/tests-clar/diff/diff_helpers.c
index 055bd4b..c9a633c 100644
--- a/tests-clar/diff/diff_helpers.c
+++ b/tests-clar/diff/diff_helpers.c
@@ -5,7 +5,7 @@ git_tree *resolve_commit_oid_to_tree(
 	git_repository *repo,
 	const char *partial_oid)
 {
-	size_t len = strlen(partial_oid);
+	unsigned int len = (unsigned int)strlen(partial_oid);
 	git_oid oid;
 	git_object *obj = NULL;
 	git_tree *tree = NULL;
diff --git a/tests-clar/diff/iterator.c b/tests-clar/diff/iterator.c
index 60f416f..0ec2326 100644
--- a/tests-clar/diff/iterator.c
+++ b/tests-clar/diff/iterator.c
@@ -37,7 +37,7 @@ static void tree_iterator_test(
 
 	while (entry != NULL) {
 		if (expected_values != NULL)
-			cl_assert_strequal(expected_values[count], entry->path);
+			cl_assert_equal_s(expected_values[count], entry->path);
 
 		count++;
 
@@ -192,7 +192,7 @@ static void index_iterator_test(
 
 	while (entry != NULL) {
 		if (expected_names != NULL)
-			cl_assert_strequal(expected_names[count], entry->path);
+			cl_assert_equal_s(expected_names[count], entry->path);
 
 		if (expected_oids != NULL) {
 			git_oid oid;
@@ -330,7 +330,7 @@ static void workdir_iterator_test(
 		}
 
 		if (expected_names != NULL)
-			cl_assert_strequal(expected_names[count_all], entry->path);
+			cl_assert_equal_s(expected_names[count_all], entry->path);
 
 		if (an_ignored_name && strcmp(an_ignored_name,entry->path)==0)
 			cl_assert(ignored);
diff --git a/tests-clar/diff/tree.c b/tests-clar/diff/tree.c
index 91e1343..1e269ae 100644
--- a/tests-clar/diff/tree.c
+++ b/tests-clar/diff/tree.c
@@ -149,15 +149,15 @@ void test_diff_tree__options(void)
 			diff, &actual, diff_file_fn, diff_hunk_fn, diff_line_fn));
 
 		expected = &test_expects[i];
-		cl_assert_intequal(actual.files,     expected->files);
-		cl_assert_intequal(actual.file_adds, expected->file_adds);
- 		cl_assert_intequal(actual.file_dels, expected->file_dels);
-		cl_assert_intequal(actual.file_mods, expected->file_mods);
-		cl_assert_intequal(actual.hunks,     expected->hunks);
-		cl_assert_intequal(actual.lines,     expected->lines);
-		cl_assert_intequal(actual.line_ctxt, expected->line_ctxt);
-		cl_assert_intequal(actual.line_adds, expected->line_adds);
-		cl_assert_intequal(actual.line_dels, expected->line_dels);
+		cl_assert_equal_i(actual.files,     expected->files);
+		cl_assert_equal_i(actual.file_adds, expected->file_adds);
+ 		cl_assert_equal_i(actual.file_dels, expected->file_dels);
+		cl_assert_equal_i(actual.file_mods, expected->file_mods);
+		cl_assert_equal_i(actual.hunks,     expected->hunks);
+		cl_assert_equal_i(actual.lines,     expected->lines);
+		cl_assert_equal_i(actual.line_ctxt, expected->line_ctxt);
+		cl_assert_equal_i(actual.line_adds, expected->line_adds);
+		cl_assert_equal_i(actual.line_dels, expected->line_dels);
 
 		git_diff_list_free(diff);
 		diff = NULL;
diff --git a/tests-clar/diff/workdir.c b/tests-clar/diff/workdir.c
index 2a93039..1ea1af8 100644
--- a/tests-clar/diff/workdir.c
+++ b/tests-clar/diff/workdir.c
@@ -37,19 +37,19 @@ void test_diff_workdir__to_index(void)
 	 * - git diff
 	 * - mv .git .gitted
 	 */
-	cl_assert_intequal(12, exp.files);
-	cl_assert_intequal(0, exp.file_adds);
-	cl_assert_intequal(4, exp.file_dels);
-	cl_assert_intequal(4, exp.file_mods);
-	cl_assert_intequal(1, exp.file_ignored);
-	cl_assert_intequal(3, exp.file_untracked);
-
-	cl_assert_intequal(8, exp.hunks);
-
-	cl_assert_intequal(14, exp.lines);
-	cl_assert_intequal(5, exp.line_ctxt);
-	cl_assert_intequal(4, exp.line_adds);
-	cl_assert_intequal(5, exp.line_dels);
+	cl_assert_equal_i(12, exp.files);
+	cl_assert_equal_i(0, exp.file_adds);
+	cl_assert_equal_i(4, exp.file_dels);
+	cl_assert_equal_i(4, exp.file_mods);
+	cl_assert_equal_i(1, exp.file_ignored);
+	cl_assert_equal_i(3, exp.file_untracked);
+
+	cl_assert_equal_i(8, exp.hunks);
+
+	cl_assert_equal_i(14, exp.lines);
+	cl_assert_equal_i(5, exp.line_ctxt);
+	cl_assert_equal_i(4, exp.line_adds);
+	cl_assert_equal_i(5, exp.line_dels);
 
 	git_diff_list_free(diff);
 }
diff --git a/tests-clar/refs/lookup.c b/tests-clar/refs/lookup.c
new file mode 100644
index 0000000..ab563ac
--- /dev/null
+++ b/tests-clar/refs/lookup.c
@@ -0,0 +1,42 @@
+#include "clar_libgit2.h"
+#include "refs.h"
+
+static git_repository *g_repo;
+
+void test_refs_lookup__initialize(void)
+{
+	g_repo = cl_git_sandbox_init("testrepo.git");
+}
+
+void test_refs_lookup__cleanup(void)
+{
+	cl_git_sandbox_cleanup();
+}
+
+void test_refs_lookup__with_resolve(void)
+{
+	git_reference *a, *b, *temp;
+
+	cl_git_pass(git_reference_lookup(&temp, g_repo, "HEAD"));
+	cl_git_pass(git_reference_resolve(&a, temp));
+	git_reference_free(temp);
+
+	cl_git_pass(git_reference_lookup_resolved(&b, g_repo, "HEAD", 5));
+	cl_assert(git_reference_cmp(a, b) == 0);
+	git_reference_free(b);
+
+	cl_git_pass(git_reference_lookup_resolved(&b, g_repo, "head-tracker", 5));
+	cl_assert(git_reference_cmp(a, b) == 0);
+	git_reference_free(b);
+
+	git_reference_free(a);
+}
+
+void test_refs_lookup__oid(void)
+{
+	git_oid tag, expected;
+
+	cl_git_pass(git_reference_name_to_oid(&tag, g_repo, "refs/tags/point_to_blob"));
+	cl_git_pass(git_oid_fromstr(&expected, "1385f264afb75a56a5bec74243be9b367ba4ca08"));
+	cl_assert(git_oid_cmp(&tag, &expected) == 0);
+}
diff --git a/tests-clar/repo/open.c b/tests-clar/repo/open.c
index 6968c44..1813887 100644
--- a/tests-clar/repo/open.c
+++ b/tests-clar/repo/open.c
@@ -1,5 +1,6 @@
 #include "clar_libgit2.h"
 #include "fileops.h"
+#include <ctype.h>
 
 void test_repo_open__cleanup(void)
 {
diff --git a/tests-clar/status/status_data.h b/tests-clar/status/status_data.h
index e60b67c..7f078bf 100644
--- a/tests-clar/status/status_data.h
+++ b/tests-clar/status/status_data.h
@@ -1,11 +1,11 @@
 
 struct status_entry_counts {
-	int wrong_status_flags_count;
-	int wrong_sorted_path;
-	int entry_count;
+	size_t wrong_status_flags_count;
+	size_t wrong_sorted_path;
+	size_t entry_count;
 	const unsigned int* expected_statuses;
 	const char** expected_paths;
-	int expected_entry_count;
+	size_t expected_entry_count;
 };
 
 /* entries for a plain copy of tests/resources/status */
diff --git a/tests/t07-hashtable.c b/tests/t07-hashtable.c
index 6beaeac..4d45c7f 100644
--- a/tests/t07-hashtable.c
+++ b/tests/t07-hashtable.c
@@ -112,7 +112,7 @@ BEGIN_TEST(table2, "make sure the table resizes automatically")
 
 	const int objects_n = 64;
 	int i;
-	unsigned int old_size;
+	size_t old_size;
 	table_item *objects;
 	git_hashtable *table = NULL;
 
diff --git a/tests/test_helpers.c b/tests/test_helpers.c
index fc03519..a1689e3 100644
--- a/tests/test_helpers.c
+++ b/tests/test_helpers.c
@@ -87,7 +87,7 @@ void locate_loose_object(const char *repository_folder, git_object *object, char
 	static const char *objects_folder = "objects/";
 
 	char *ptr, *full_path, *top_folder;
-	int path_length, objects_length;
+	size_t path_length, objects_length;
 
 	assert(repository_folder && object);