---
 sh.hist.c |   21 ++++++++++++++++-----
 1 file changed, 16 insertions(+), 5 deletions(-)

--- sh.hist.c
+++ sh.hist.c	2015-05-05 07:16:26.382084939 +0000
@@ -103,7 +103,7 @@ hremove(struct Hist *hp)
 
 /* Prune length of history list to specified size by history variable. */
 PG_STATIC void
-discardExcess(int hlen)
+discardExcess(int hlen, int flg)
 {
     struct Hist *hp, *np;
     if (histTail == NULL) {
@@ -114,7 +114,7 @@ discardExcess(int hlen)
      * the list is still too long scan the whole list as before.  But only do a
      * full scan if the list is more than 6% (1/16th) too long. */
     while (histCount > (unsigned)hlen && (np = Histlist.Hnext)) {
-        if (eventno - np->Href >= hlen || hlen == 0)
+        if ((eventno - np->Href >= hlen || hlen == 0) && ! (flg & HIST_MERGE))
             hremove(np), hfree(np);
         else
             break;
@@ -129,7 +129,7 @@ discardExcess(int hlen)
 	return;				/* don't bother doing the full scan */
     for (hp = &Histlist; histCount > (unsigned)hlen &&
 	(np = hp->Hnext) != NULL;)
-        if (eventno - np->Href >= hlen || hlen == 0)
+        if ((eventno - np->Href >= hlen || hlen == 0) || flg & HIST_MERGE)
             hremove(np), hfree(np);
         else
             hp = np;
@@ -146,7 +146,7 @@ savehist(
 	return;
     if (sp)
         (void) enthist(++eventno, sp, 1, flg, histlen);
-    discardExcess(histlen);
+    discardExcess(histlen, flg);
 }
 
 #define USE_JENKINS_HASH 1
@@ -1357,5 +1357,16 @@ void
 sethistory(int n)
 {
     histlen = n;
-    discardExcess(histlen);
+    int merge = 0;
+    struct varent *shist;
+    if ((shist = adrof(STRsavehist)) != NULL && shist->vec != NULL) {
+	size_t i;
+	for (i = 1; shist->vec[i]; i++) {
+	    if (eq(shist->vec[i], STRmerge)) {
+		merge = HIST_MERGE;
+		break;
+	    }
+	}
+    }
+    discardExcess(histlen, merge);
 }