diff -urN git-2.8.2-orig/builtin/clone.c git-2.8.2/builtin/clone.c
--- git-2.8.2-orig/builtin/clone.c	2016-05-17 11:31:07.469884100 +0100
+++ git-2.8.2/builtin/clone.c	2016-05-17 11:31:16.899423500 +0100
@@ -887,7 +887,7 @@
 		die(_("depth %s is not a positive number"), option_depth);
 
 	if (argc == 2)
-		dir = xstrdup(argv[1]);
+		dir = maybe_xstrdup_cyg_conv_path(argv[1], 1);
 	else
 		dir = guess_dir_name(repo_name, is_bundle, option_bare);
 	strip_trailing_slashes(dir);
diff -urN git-2.8.2-orig/cache.h git-2.8.2/cache.h
--- git-2.8.2-orig/cache.h	2016-05-17 11:31:07.561889400 +0100
+++ git-2.8.2/cache.h	2016-05-17 11:31:16.884422600 +0100
@@ -989,6 +989,7 @@
 int normalize_path_copy(char *dst, const char *src);
 int longest_ancestor_length(const char *path, struct string_list *prefixes);
 char *strip_path_suffix(const char *path, const char *suffix);
+char *maybe_xstrdup_cyg_conv_path(const char *path, int always_dupe);
 int daemon_avoid_alias(const char *path);
 extern int is_ntfs_dotgit(const char *name);
 
diff -urN git-2.8.2-orig/path.c git-2.8.2/path.c
--- git-2.8.2-orig/path.c	2016-05-17 11:31:06.252814500 +0100
+++ git-2.8.2/path.c	2016-05-17 11:38:34.828471600 +0100
@@ -6,6 +6,10 @@
 #include "string-list.h"
 #include "dir.h"
 
+#if defined(__CYGWIN__)
+#include <sys/cygwin.h>
+#endif
+
 static int get_st_mode_bits(const char *path, int *mode)
 {
 	struct stat st;
@@ -1101,6 +1105,39 @@
 	return xstrndup(path, chomp_trailing_dir_sep(path, path_len));
 }
 
+/* We're deliberately not changing the normal has_dos_drive_prefix
+ * here, since doing that would likely have unintended side-effects
+ * This version is only for maybe_xstrdup_cyg_conv_path which is
+ * called in very specific cases.
+ */
+#if defined(__CYGWIN__)
+#define cyg_conv_has_dos_drive_prefix(path) \
+	(isalpha(*(path)) && (path)[1] == ':' ? 2 : 0)
+#endif
+
+/*
+ * Avoids duplicating `path` if not needed unless `always_dupe` is non-zero.
+ */
+char *maybe_xstrdup_cyg_conv_path(const char *path, int always_dupe)
+{
+#if defined(__CYGWIN__)
+	int dos_prefix = cyg_conv_has_dos_drive_prefix(path) ? 1 : 0;
+	int backslash = strchr(path, '\\') ? 1 : 0;
+	if (dos_prefix || backslash)
+	{
+		cygwin_conv_path_t form = dos_prefix ? CCP_ABSOLUTE : CCP_RELATIVE;
+		form |= CCP_WIN_A_TO_POSIX;
+		ssize_t cyg_len = cygwin_conv_path(form, path, NULL, 0);
+		char *cyg_path = (char *)alloca(cyg_len + 1);
+		if (cyg_path == NULL)
+		    die("Couldn't alloca space for cyg_path");
+		cygwin_conv_path(form, path, cyg_path, cyg_len);
+		return xstrndup(cyg_path, cyg_len);
+	}
+#endif
+	return always_dupe ? xstrdup(path) : (char*)path;
+}
+
 int daemon_avoid_alias(const char *p)
 {
 	int sl, ndot;
diff -urN git-2.8.2-orig/pathspec.c git-2.8.2/pathspec.c
--- git-2.8.2-orig/pathspec.c	2016-05-17 11:31:06.253814600 +0100
+++ git-2.8.2/pathspec.c	2016-05-17 11:31:16.903423700 +0100
@@ -397,6 +397,10 @@
 			       const char *prefix, int prefixlen,
 			       const char *elt)
 {
+#if defined(__CYGWIN__)
+	const char *in_elt = elt;
+	elt = maybe_xstrdup_cyg_conv_path(elt, 0);
+#endif
 	unsigned magic = 0, element_magic = 0;
 	const char *copyfrom = elt;
 	char *match;
@@ -488,6 +492,10 @@
 	    item->prefix         > item->len) {
 		BUG("error initializing pathspec_item");
 	}
+#if defined(__CYGWIN__)
+	if (in_elt != elt)
+		free((void*)elt);
+#endif
 }
 
 static int pathspec_item_cmp(const void *a_, const void *b_)
diff -urN git-2.8.2-orig/strbuf.c git-2.8.2/strbuf.c
--- git-2.8.2-orig/strbuf.c	2016-05-17 11:31:06.336819300 +0100
+++ git-2.8.2/strbuf.c	2016-05-17 11:31:16.893423100 +0100
@@ -671,6 +671,10 @@
 
 void strbuf_add_absolute_path(struct strbuf *sb, const char *path)
 {
+#if defined(__CYGWIN__)
+	const char *in_path = path;
+	path = maybe_xstrdup_cyg_conv_path(path, 0);
+#endif
 	if (!*path)
 		die("The empty string is not a valid path");
 	if (!is_absolute_path(path)) {
@@ -692,6 +696,10 @@
 		free(cwd);
 	}
 	strbuf_addstr(sb, path);
+#if defined(__CYGWIN__)
+	if (in_path != path)
+		free((void*)path);
+#endif
 }
 
 int printf_ln(const char *fmt, ...)
