diff -Naur a/bashline.c b/bashline.c
--- a/bashline.c	2014-03-13 16:36:07.995800000 +0400
+++ b/bashline.c	2014-03-13 16:36:08.994200000 +0400
@@ -758,7 +758,11 @@
   char *temp, buffer[256], name[256];
   register int i, start;
 
-  file = fopen (filename, "r");
+#ifdef __MSYS__
+  file = fopen (filename, "rt");
+#else
+   file = fopen (filename, "r");
+#endif
   if (file == 0)
     return;
 
diff -Naur a/builtins/fc.def b/builtins/fc.def
--- a/builtins/fc.def	2013-08-14 00:25:38.000000000 +0400
+++ b/builtins/fc.def	2014-03-13 16:36:08.994200000 +0400
@@ -594,6 +594,10 @@
      FILE *stream;
 {
   register int c;
+#ifdef __MSYS__
+  register int d;
+#endif
+
   int line_len = 0, lindex = 0;
   char *line = (char *)NULL;
 
@@ -604,12 +608,19 @@
 
       if (c == '\n')
 	{
+#ifdef __MSYS__
+	  if (d == '\r')
+	    lindex--;
+#endif
 	  line[lindex++] = '\n';
 	  line[lindex++] = '\0';
 	  return (line);
 	}
       else
 	line[lindex++] = c;
+#ifdef __MSYS__
+      d = c;
+#endif
     }
 
   if (!lindex)
diff -Naur a/general.c b/general.c
--- a/general.c	2014-03-13 16:36:08.869400000 +0400
+++ b/general.c	2014-03-13 16:36:09.009800000 +0400
@@ -612,7 +612,8 @@
 absolute_program (string)
      const char *string;
 {
-  return ((char *)mbschr (string, '/') != (char *)NULL);
+  return ((char *)mbschr (string, '/') != (char *)NULL ||
+          (char *)mbschr (string, '\\') != (char *)NULL);
 }
 
 /* **************************************************************** */
diff -Naur a/lib/readline/display.c b/lib/readline/display.c
--- a/lib/readline/display.c	2013-12-27 22:10:56.000000000 +0400
+++ b/lib/readline/display.c	2014-03-13 16:36:09.009800000 +0400
@@ -381,7 +381,10 @@
   if (lp)
     *lp = rl;
   if (lip)
-    *lip = last;
+    /* Hack: faking that the last character is invisible seems to work around
+       prompt display bugs.  I wish I knew what the real bug was...  */
+    *lip = r - ret;
+/*     *lip = last; */
   if (niflp)
     *niflp = invfl;
   if  (vlp)
diff -Naur a/parse.y b/parse.y
--- a/parse.y	2014-03-13 16:36:06.264200000 +0400
+++ b/parse.y	2014-03-13 16:36:09.009800000 +0400
@@ -1374,7 +1374,13 @@
 static int
 yy_getc ()
 {
-  return (*(bash_input.getter)) ();
+#ifdef __MSYS__
+  int c;
+  while ((c = (*(bash_input.getter)) ()) == '\r');
+  return c;
+#else
+   return (*(bash_input.getter)) ();
+#endif
 }
 
 /* Call this to unget C.  That is, to make C the next character
diff -Naur a/shell.c b/shell.c
--- a/shell.c	2014-03-13 16:36:06.264200000 +0400
+++ b/shell.c	2014-03-13 16:36:09.009800000 +0400
@@ -1507,7 +1507,11 @@
   default_buffered_input = fd;
   SET_CLOSE_ON_EXEC (default_buffered_input);
 #else /* !BUFFERED_INPUT */
-  default_input = fdopen (fd, "r");
+#ifdef __MSYS__
+  default_input = fdopen (fd, "rt");
+#else
+   default_input = fdopen (fd, "r");
+#endif
 
   if (default_input == 0)
     {
diff -Naur a/stringlib.c b/stringlib.c
--- a/stringlib.c	2012-03-19 22:38:06.000000000 +0400
+++ b/stringlib.c	2014-03-13 16:36:09.025400000 +0400
@@ -270,7 +270,15 @@
     {
       if ((newlines_only && string[len] == '\n') ||
 	  (!newlines_only && whitespace (string[len])))
+      {
 	len--;
+#ifdef __MSYS__
+	if (newlines_only && string[len + 1] == '\n' && string[len] == '\r')
+	{
+	  len--;
+	}
+#endif
+      }
       else
 	break;
     }
diff -Naur a/subst.c b/subst.c
--- a/subst.c	2014-03-13 16:36:06.279800000 +0400
+++ b/subst.c	2014-03-13 16:36:09.025400000 +0400
@@ -5322,6 +5322,15 @@
 	      /* If the newline was quoted, remove the quoting char. */
 	      if (istring[istring_index - 1] == CTLESC)
 		--istring_index;
+
+	      if (istring_index > 0 && istring[istring_index - 1] == '\r')
+	      {
+		--istring_index;
+
+	        /* If the caret return was quoted, remove the quoting char. */
+	        if (istring[istring_index - 1] == CTLESC)
+		  --istring_index;
+	      }
 	    }
 	  else
 	    break;
diff -Naur a/variables.c b/variables.c
--- a/variables.c	2014-03-13 16:36:06.279800000 +0400
+++ b/variables.c	2014-03-13 16:36:09.041000000 +0400
@@ -2175,6 +2175,20 @@
 {
   SHELL_VAR *v;
 
+#if defined (__MSYS__)
+  /* Remove trailing \r from value */
+  {
+    char *tpos;
+    if (value && *value)
+    {
+      tpos = strchr (value, '\0');
+      tpos--;
+      if (*tpos == '\r')
+	*tpos = '\0';
+    }
+  }
+#endif
+
   if (shell_variables == 0)
     create_variable_tables ();
 
diff -Naur a/y.tab.c b/y.tab.c
--- a/y.tab.c	2014-02-11 19:57:47.000000000 +0400
+++ b/y.tab.c	2014-03-13 16:36:09.072200000 +0400
@@ -3686,7 +3686,13 @@
 static int
 yy_getc ()
 {
-  return (*(bash_input.getter)) ();
+#ifdef __MSYS__
+  int c;
+  while ((c = (*(bash_input.getter)) ()) == '\r');
+  return c;
+#else
+   return (*(bash_input.getter)) ();
+#endif
 }
 
 /* Call this to unget C.  That is, to make C the next character
@@ -4625,6 +4631,10 @@
 	  else
 	    RESIZE_MALLOCED_BUFFER (shell_input_line, i, 2, shell_input_line_size, 256);
 
+#ifdef __MSYS__
+	  if (c == '\r')
+	    continue;
+#endif
 	  if (c == EOF)
 	    {
 	      if (bash_input.type == st_stream)
