diff --git a/mercurial/thirdparty/xdiff/xprepare.c b/mercurial/thirdparty/xdiff/xprepare.c
--- a/mercurial/thirdparty/xdiff/xprepare.c
+++ b/mercurial/thirdparty/xdiff/xprepare.c
@@ -181,7 +181,7 @@
 	if ((cur = blk = xdl_mmfile_first(mf, &bsize)) != NULL) {
 		for (top = blk + bsize; cur < top; ) {
 			prev = cur;
-			hav = xdl_hash_record(&cur, top, xpp->flags);
+			xdl_next_record(&cur, top);
 			if (nrec >= narec) {
 				narec *= 2;
 				if (!(rrecs = (xrecord_t **) xdl_realloc(recs, narec * sizeof(xrecord_t *))))
@@ -192,7 +192,7 @@
 				goto abort;
 			crec->ptr = prev;
 			crec->size = (long) (cur - prev);
-			crec->ha = hav;
+			crec->ha = 0;
 			recs[nrec++] = crec;
 		}
 	}
@@ -243,7 +243,7 @@
 
 	unsigned int hbits;
 	long hsize;
-	long i;
+	long i, j;
 	long start = xdf->dstart - reserved;
 	long end = xdf->dend + reserved;
 
@@ -261,6 +261,16 @@
 	memset(rhash, 0, hsize * sizeof(xrecord_t *));
 
 	for (i = start; i <= end; i++) {
+		{
+			unsigned long ha = 5381;
+			char const *ptr = xdf->recs[i]->ptr;
+
+			for (j = 0; j < xdf->recs[i]->size; ++j) {
+				ha += (ha << 5);
+				ha ^= (unsigned long)ptr[j];
+			}
+			xdf->recs[i]->ha = ha;
+		}
 		if (xdl_classify_record(pass, cf, rhash, hbits, xdf->recs[i]) < 0)
 			goto abort;
 	}
diff --git a/mercurial/thirdparty/xdiff/xutils.h b/mercurial/thirdparty/xdiff/xutils.h
--- a/mercurial/thirdparty/xdiff/xutils.h
+++ b/mercurial/thirdparty/xdiff/xutils.h
@@ -34,6 +34,7 @@
 long xdl_guess_lines(mmfile_t *mf, long sample);
 int xdl_blankline(const char *line, long size, long flags);
 int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags);
+void xdl_next_record(char const **data, char const *top);
 unsigned long xdl_hash_record(char const **data, char const *top, long flags);
 unsigned int xdl_hashbits(unsigned int size);
 int xdl_num_out(char *out, long val);
diff --git a/mercurial/thirdparty/xdiff/xutils.c b/mercurial/thirdparty/xdiff/xutils.c
--- a/mercurial/thirdparty/xdiff/xutils.c
+++ b/mercurial/thirdparty/xdiff/xutils.c
@@ -298,6 +298,15 @@
 	return ha;
 }
 
+inline void xdl_next_record(char const **data, char const *top) {
+	char const *next = memchr(*data, '\n', top - *data);
+	if (next) {
+		*data = next + 1;
+	} else {
+		*data = top;
+	}
+}
+
 unsigned long xdl_hash_record(char const **data, char const *top, long flags) {
 	unsigned long ha = 5381;
 	char const *ptr = *data;