diff --git a/mercurial/templatefilters.py b/mercurial/templatefilters.py
--- a/mercurial/templatefilters.py
+++ b/mercurial/templatefilters.py
@@ -99,6 +99,26 @@
     """
     return os.path.basename(path)
 
+@templatefilter('commonprefix')
+def commonprefix(filelist):
+    """List of text. Treats each list item as file name, and returns
+    the longest common directory prefix shared by all list items.
+    Returns the empty string if no common prefix exists.
+    For example, ["foo/bar/baz", "foo/baz/bar"] becomes "foo" and
+    ["foo/bar", "baz"] becomes "".
+    """
+    def common(a, b):
+        while a != b:
+            if len(a) > len(b):
+                a = os.path.dirname(a)
+            else:
+                b = os.path.dirname(b)
+        return a
+    if not filelist:
+        return ""
+    dirlist = [os.path.dirname(os.path.normpath(f)) for f in filelist]
+    return reduce(common, dirlist)
+
 @templatefilter('count')
 def count(i):
     """List or text. Returns the length as an integer."""
diff --git a/tests/test-template-filters.t b/tests/test-template-filters.t
new file mode 100644
--- /dev/null
+++ b/tests/test-template-filters.t
@@ -0,0 +1,4 @@
+  $ hg debugtemplate '{"foo/bar\nfoo/baz\n"|splitlines|commonprefix}\n'
+  foo
+  $ hg debugtemplate '{"foo/bar\nbar/baz"|splitlines|commonprefix}\n'
+