<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Fog Creek Blog</title>
	
	<link>http://blog.fogcreek.com</link>
	<description>Helping the world's best developers make better software</description>
	<lastBuildDate>Wed, 05 Jun 2013 15:24:48 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/FogCreekBlog" /><feedburner:info uri="fogcreekblog" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>What’s new in Kiln On Demand? View a diff between any two changesets</title>
		<link>http://feedproxy.google.com/~r/FogCreekBlog/~3/v0nVPPYL-dY/</link>
		<comments>http://blog.fogcreek.com/whats-new-in-kiln-view-a-diff-between-any-two-changesets/#comments</comments>
		<pubDate>Fri, 17 May 2013 19:35:48 +0000</pubDate>
		<dc:creator>Kevin Gessner</dc:creator>
				<category><![CDATA[Kiln]]></category>
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.fogcreek.com/?p=3145</guid>
		<description><![CDATA[One of the first features we added to Kiln was diff viewing: click a changeset, see what was changed. In terms of raw page views, viewing diffs is one of the most popular features in Kiln. But viewing a single diff isn&#8217;t always everything you want. Often, you&#8217;ll want to see all the changes made [...]]]></description>
				<content:encoded><![CDATA[<p>One of the first features we added to Kiln was diff viewing: click a changeset, see what was changed. In terms of raw page views, viewing diffs is one of the most popular features in Kiln.</p>
<p>But viewing a single diff isn&#8217;t always everything you want. Often, you&#8217;ll want to see all the changes made between two changesets that are farther apart—perhaps the difference between two tagged releases, or the sum of the changes made in a feature branch. With Kiln Harmony, now you can!</p>
<p>Simply load any changeset, and you&#8217;ll see the diff from the changeset&#8217;s first parent. Click the &#8220;Diff from another changeset&#8230;&#8221; link to search for another changeset (you can search by commit hash, tag, and branch names, or phrases in the commit message, or even filter by author and date—it&#8217;s the full power of Kiln&#8217;s search engine). Click the results to view the diff from that changeset!</p>
<p><a href="http://blog.fogcreek.com/wp-content/uploads/2013/05/5-16-2013-6-04-31-PM-big.png"><img class="alignnone size-full wp-image-3146" alt="Changeset search" src="http://blog.fogcreek.com/wp-content/uploads/2013/05/5-16-2013-6-04-31-PM.png" width="667" height="202" /></a></p>
<p>You can see some examples on our demo site:</p>
<ul>
<li>What changed in Mercurial 2.6.1? <a href="https://mirrors.kilnhg.com/Code/Mirrors/Tools/Mercurial/History/2.6/2.6.1" title="https://mirrors.kilnhg.com/Code/Mirrors/Tools/Mercurial/History/2.6/2.6.1">https://mirrors.kilnhg.com/Code/Mirrors/Tools/Mercurial/History/2.6/2.6.1</a></li>
<li>What&#8217;s new since the last Git release? <a href="https://mirrors.kilnhg.com/Code/Mirrors/Tools/Git/History/master/pu" title="https://mirrors.kilnhg.com/Code/Mirrors/Tools/Git/History/master/pu">https://mirrors.kilnhg.com/Code/Mirrors/Tools/Git/History/master/pu</a></li>
</ul>
<p><em>This feature is available in Kiln 3.0.33 and higher. <a href="https://try.kilnhg.com/">Sign up for a free trial</a> and try it out!</em></p>
<img src="http://feeds.feedburner.com/~r/FogCreekBlog/~4/v0nVPPYL-dY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.fogcreek.com/whats-new-in-kiln-view-a-diff-between-any-two-changesets/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.fogcreek.com/feeder/?FeederAction=clicked&amp;feed=Fog+Creek+Blog&amp;seed=http%3A%2F%2Fblog.fogcreek.com%2Fwhats-new-in-kiln-view-a-diff-between-any-two-changesets%2F&amp;seed_title=What%26%238217%3Bs+new+in+Kiln+On+Demand%3F+View+a+diff+between+any+two+changesets</feedburner:origLink></item>
		<item>
		<title>Dive into parser combinators: parsing search queries with F# and FParsec in Kiln</title>
		<link>http://feedproxy.google.com/~r/FogCreekBlog/~3/SJfn7ZJMKMU/</link>
		<comments>http://blog.fogcreek.com/fparsec/#comments</comments>
		<pubDate>Tue, 23 Apr 2013 17:10:21 +0000</pubDate>
		<dc:creator>Hao Lian</dc:creator>
				<category><![CDATA[Kiln]]></category>
		<category><![CDATA[computer science]]></category>
		<category><![CDATA[fparsec]]></category>
		<category><![CDATA[fsharp]]></category>
		<category><![CDATA[kiln]]></category>
		<category><![CDATA[parser combinators]]></category>
		<category><![CDATA[search]]></category>
		<category><![CDATA[technical]]></category>

		<guid isPermaLink="false">http://blog.fogcreek.com/?p=3076</guid>
		<description><![CDATA[We open on: the past The year: 2012. The problem: search. With a new release of Kiln, search is now forefront and center. You can zip around repositories or code with a simple tap of the keys, and boy is the future bright. Powering search was our search engine. And powering it was our search-query [...]]]></description>
				<content:encoded><![CDATA[<h2>We open on: the past</h2>
<p>The year: 2012. The problem: search.  With a new release of <a href="/announcing-kiln-harmony-the-future-of-dvcs/">Kiln</a>, search is now forefront and center.  You can zip around repositories or code with a simple tap of the keys, and boy is the future bright.</p>
<p>Powering search was our search engine.  And powering <em>it</em> was our search-query parser,  a couple hundred lines of code that parsed a query into a list of keywords and filters.  For example, if you asked of Kiln</p>
<pre><code>foo bar project:Eggs date:yesterday..now author:Tyler</code></pre>
<p>Kiln finds all the commits, by people named “Tyler,”  to a repository in projects named “Eggs” since yesterday with the words “foo” or “bar” in the commit message.</p>
<p>But try to search <code>"foo bar"</code> and you would be disappointed.  The unspoken rule of the internet is that surrounding two words in  quotation marks should make a search engine look for both words as one <em>phrase</em> instead of two separate words.  So <code>"foo bar"</code> should match the string “boy I had a lot of foo bar pie”  but not the string “foo and bar are two friends from way back when.”  Pretty goofy rule, but the internet is a goofy place.</p>
<p>It’s 2012, and Kiln does not have phrase search.  We left it on the cutting floor to make room for everything else we wanted, and we regret it.  Life moves on.</p>
<h2>And we cut to: the present</h2>
<p>The year: 2013.  Not having phrase search: more and more irritating.  Having migrated our full-text indexing to <a href="/loving-the-code/">elasticsearch</a>,  phrase searches are not only possible but <a href="http://www.elasticsearch.org/guide/reference/query-dsl/text-query/">easy</a>.  So you, being a developer on the Kiln team, don glasses and open the .cs file containing the query parser.  Written in C# and presented for your consideration is a jumble of <a href="http://en.wikipedia.org/wiki/Backus%E2%80%93Naur_Form">grammar rules</a> and intermediate parse trees, a jungle of loops and state.  A flock of crows take off from a nearby tree.  You close the file.</p>
<p>“This seems like the ideal intern project,” you think to yourself.  “It would be a shame to not allow someone else to rewrite this.”</p>
<p>Just then, Andrew Pritchard walks by your office.  Andrew Pritchard was our summer 2012 intern who worked on a dazzling array of Kiln features, including phrase search.  We will borrow a hypothetical version of him.  Look at him, walking with the smooth confidence of a man not yet burdened by string parsing.</p>
<p>“Help us, Hypothetical Andrew Pritchard,” we said.  “What do you know about parsing?”</p>
<p>H.A.P. points you at <a href="http://www.quanttec.com/fparsec/">FParsec</a>, a parser combinator library for <a href="http://tryfsharp.org/">F#</a>.  He begins erasing your whiteboard and drawing diagrams while you wonder what he is talking about.</p>
<p>“Hold on,” you say, slapping the multi-colored markers out of his hand.  “I have many reservations about what’s happening right now but here’s the biggest one.  <a href="http://en.wikipedia.org/wiki/F_Sharp_(programming_language)">F# is that that new functional-programming language from Microsoft right</a>?  Kiln is a giant ASP.NET MVC application that uses C#.  There is no room for F#, Hypothetical Andrew Pritchard, you crazy lovable human being you.”</p>
<p>“No,” he replies.  You two stare at each other for a while.</p>
<p>It turns out that .NET’s <a href="http://en.wikipedia.org/wiki/Common_Language_Runtime">Common Language Runtime</a>, plus increasingly better F# support in Visual Studio, lets you create an F# library inside your solution and reference it from a C# project.  There are some quirks:  <a href="https://github.com/jetbrains/fsharper">ReSharper support for F#</a> is ongoing, F# files have to be sorted in the solution tree in the order  you want them to be compiled,  and F# collection types map awkwardly from and to C#—to name three big ones.  Overall though the experience is surprisingly pleasant.  I say in the year 2013 you can (and should) alternate between F# and C# depending on the problems you are solving.</p>
<p>We created an <a href="https://developers.kilnhg.com/Code/Kiln/Group/babybearparser">F# project</a> with the source code  in this blog post if you would like to follow along.  If you are not familiar with F#, fear not!  By and large the F# syntax can be intuited; for a look-see, <a href="http://c2.com/cgi/wiki?FunctionalProgramming">Wikipedia</a> also has a buffet of code snippets.  On my part I’ll use highly descriptive variable names and mention C# analogues to F# features when possible.</p>
<p>“FParsec is great, but we need F#.  No biggie,” H.A.P says, shrugging his shoulders.  “Besides, F# is <a href="http://c2.com/cgi/wiki?FunctionalProgramming"><em>functional</em></a>, which means it’s ideal for a self-contained, computer-science-y  project like string parsing.”</p>
<p>“It is fun.”</p>
<p>“You will like it.”</p>
<p>You are sort of convinced.  In any case, he has covered your whiteboard in figures and symbols.  He looks at you, then looks at the board.  He walks over and gently pushes you out of your chair.  You get up, brush yourself off, and read the notes on the whiteboard as he begins typing  into <em>your</em> computer.  Which notes are:</p>
<p><span id="more-3076"></span></p>
<h2>Parsers</h2>
<p>In the world of parser combinators, a <strong>parser</strong> is a function  that takes an initial state <code>s</code> and returns a final state <code>s'</code> in addition to  an <em>output</em> object:</p>
<p><img src="http://blog.fogcreek.com/wp-content/uploads/2013/04/0-regular.png" alt="p .&gt;&gt;. q"></p>
<p>If the output is of type <code>'t</code>, we say the parser is of type <code>'t</code>.  The black arrow shows the output.</p>
<p>The <em>state</em> is a set of facts about the world.</p>
<p>Let’s give ourselves a parser <code>p</code> that finds the string <code>hello</code> inside other strings.  And let’s run <code>p</code> on the string “hello, world”.  Then the state of the world prior to running <code>p</code> (the <em>initial state</em> <code>s</code>) as indicated by the first blue arrow has these facts:</p>
<ul>
<li>Our string is “hello, world”;</li>
<li>Our current position is index 0;</li>
<li>No errors so far;</li>
<li>etc.</li>
</ul>
<p>The state of the world after running <code>p</code> (the <em>final state</em> <code>s'</code>) as indicated by the second blue arrow has these other facts:</p>
<ul>
<li>String: still “hello, world”;</li>
<li>Current position: now index 5 (the comma);</li>
<li>Errors: still none;</li>
<li>etc.</li>
</ul>
<p>We say that the parser has <em>consumed</em> the string “hello”,  which means the parser has read  the string “hello” and has adjusted the current position accordingly.</p>
<p>A parser can also <em>fail</em>.  For example, if we run <code>p</code> on the string “salutations, world”  an exception is raised as soon as the parser realizes there is no “hello”,  and the whole thing is called off.</p>
<p>FParsec comes with <a href="http://www.quanttec.com/fparsec/reference/charparsers.html">a smörgåsbord of helper functions</a>  for parsing common chores.  Some that are relevant to us:</p>
<ul>
<li><code>pchar</code>: <a href="http://www.quanttec.com/fparsec/reference/charparsers.html#members.pchar">consumes one character of your choice</a>.  For example, <code>pchar '"'</code> consumes a quotation mark.</li>
<li><code>manySatisfy</code>: <a href="http://www.quanttec.com/fparsec/reference/charparsers.html#members.manySatisfy">consumes as many characters as possible that matches a given function</a>.  For example, <code>manySatisfy (fun c -&gt; c &lt;&gt; ' ')</code> consumes all non-space characters.</li>
<li><code>many1Satisfy</code>: like <code>manySatisfy</code> but will <a href="http://www.quanttec.com/fparsec/reference/charparsers.html#members.many1Satisfy">fail if it cannot consume at least one match</a>.</li>
</ul>
<p>These higher-order functions take arguments and return a parser.  (By the way, <code>fun c -&gt; c &lt;&gt; ' '</code> is just a lambda.  The C# equivalent, which is actually terser!, would be <code>c =&gt; c != ' '</code>.)</p>
<p><code>pchar '"'</code> and <code>manySatisfy (fun c -&gt; c &lt;&gt; ' ')</code> are parsers of type <code>string</code>, as indicated by their type  <code>Parser&lt;string, unit&gt;</code>, which makes sense since they consume a string and then immediately output it.  (You may be wondering what that second generic type argument <code>unit</code> is for.  [<code>unit</code> is the same as <code>void</code> in C#.]  We will leave the resolution to that mystery to the <a href="http://www.quanttec.com/fparsec/users-guide/parsing-with-user-state.html">excellent FParsec documentation</a>.)</p>
<h2>Parser combinators</h2>
<p>A <strong>parser combinator</strong> is function that takes multiple parsers and returns a new one.  Every parser you’ll ever write in FParsec will be a pyramid with small simple parsers at the bottom  building up to something big and wonderful at the top.</p>
<p>FParsec comes with a <a href="http://www.quanttec.com/fparsec/reference/primitives.html">zoo of parser combinators</a>.  Some are functions, but most are operators.  In F#, you can define custom operators and  FParsec is nothing if not a testament to that feature.  This lets us write, for example, <code>p &lt;|&gt; q</code> instead of  (say, hypothetically) <code>alternate p q</code>.  There is a trade-off though: the library can be intimidating at first.  It may seem like a place of tall runes and cold magic,  where the flesh and soul are tested,  and light is dim, joyless.  But armed with logic and courage, you will  soon be able to write fairly complicated  parsers in only a few terse lines.</p>
<p>So, using these primitives, little itty parsers get glued together into a big ol’ parser,  which is what we will be doing for Kiln.  You can take apart the pieces when you are reading and understanding it,  and you can build up the pieces when you are writing and debugging it.  You might even dare to reuse a parser or two.  The same cannot be said for the kind of parsers out there  in the harsh imperative world—try refactoring that while-loop with the big switch statement  into modular components without  messing up the big global state object.</p>
<p>And also: no <a href="http://en.wikipedia.org/wiki/Yacc">preprocessor</a>.</p>
<p>Some combinators that are relevant to us:</p>
<h3>Sequencing with &gt;&gt;. and .&gt;&gt;</h3>
<pre><code>val (&gt;&gt;.):   Parser&lt;'a,'u&gt; -&gt; Parser&lt;'b,'u&gt; -&gt; Parser&lt;'b,'u&gt;
</code></pre>
<p>Here’s what you do if you’re <code>&gt;&gt;.</code>:  First run <code>p</code> and throw away its output (black arrow).  Then, following the state (blue arrows), run <code>q</code> and take its output.</p>
<p><img src="http://blog.fogcreek.com/wp-content/uploads/2013/04/1-right-eye.png" alt="p &gt;&gt;. q" style="width: 627px;height: 291.17359050445106px"></p>
<p>The cousin of <code>&gt;&gt;.</code> is <code>.&gt;&gt;</code>, which throws away the second output and takes the first:</p>
<pre><code>val (.&gt;&gt;):   Parser&lt;'a,'u&gt; -&gt; Parser&lt;'b,'u&gt; -&gt; Parser&lt;'a,'u&gt;
</code></pre>
<p><img src="http://blog.fogcreek.com/wp-content/uploads/2013/04/3-left-eye.png" alt="p .&gt;&gt; q" style="width: 627px;height: 291.17359050445106px"></p>
<h3>Tuple sequencing with .&gt;&gt;. (or “two eyes, full hearts”)</h3>
<pre><code>val (.&gt;&gt;.):  Parser&lt;'a,'u&gt; -&gt; Parser&lt;'b,'u&gt; -&gt; Parser&lt;('a * 'b),'u&gt;
</code></pre>
<p>First run <code>p</code>.  Then run <code>q</code>.  Take <em>both</em> outputs and tuple them, which we denote by multiplying the two  types together, just as F# does.  (For example, a tuple of an integer and a string in F# has a type <code>int * string</code>,  which is just shorthand for <code>Tuple&lt;int, string&gt;</code> like you might see in C#.)</p>
<p><img src="http://blog.fogcreek.com/wp-content/uploads/2013/04/6-tuple.png" alt="p .&gt;&gt;. q" style="width: 627px;height: 428.85311572700294px"></p>
<h3>Alternation with &lt;|&gt;</h3>
<pre><code>val (&lt;|&gt;): Parser&lt;'a,'u&gt; -&gt; Parser&lt;'a,'u&gt; -&gt; Parser&lt;'a,'u&gt;
</code></pre>
<p>Say you have two parsers of the same type <code>'t</code>.  Run <code>p</code> first.  If it fails without altering the state, run <code>q</code> instead.</p>
<p><img src="http://blog.fogcreek.com/wp-content/uploads/2013/04/4-alternate.png" alt="p &lt;|&gt; q"></p>
<p>If you recall from compilers, you can write down <a href="http://docs.python.org/2/reference/grammar.html">a grammar</a> in a hoity-toity syntax  that looks like</p>
<pre><code>compound_stmt: if_stmt | while_stmt | for_stmt | try_stmt | with_stmt
if_stmt: 'if' test ':' suite ('elif' test ':' suite)* ['else' ':' suite]
while_stmt: 'while' test ':' suite ['else' ':' suite]
for_stmt: 'for' exprlist 'in' testlist ':' suite ['else' ':' suite]
try_stmt: ('try' ':' suite
           ((except_clause ':' suite)+
            ['else' ':' suite]
            ['finally' ':' suite] |
           'finally' ':' suite))
with_stmt: 'with' with_item (',' with_item)*  ':' suite
with_item: test ['as' expr]
</code></pre>
<p>You can think of the <code>&lt;|&gt;</code> operator from FParsec as a rough correspondence to the <code>|</code> operator from  <a href="http://en.wikipedia.org/wiki/Extended_Backus%E2%80%93Naur_Form">Backus-Naur syntax</a>.  Note that <code>&lt;|&gt;</code> will fail if <code>p</code> alters the parser state.  If <em>backtracking</em> (trying a parser without actually altering the state) is what you are looking for,  seek <a href="http://www.quanttec.com/fparsec/users-guide/parsing-alternatives.html">FParsec’s excellent documentation on parsing alternatives</a>.</p>
<h3>Separation with sepBy</h3>
<pre><code>val sepBy: Parser&lt;'a,'u&gt; -&gt; Parser&lt;'b,'u&gt; -&gt; Parser&lt;'a list,'u&gt;
</code></pre>
<p>The combinator to turn to when parsing a list of things:</p>
<p><img src="http://blog.fogcreek.com/wp-content/uploads/2013/04/7-sepBy.png" alt="sepBy"></p>
<ol>
<li>Allocate a list of type <code>'p list</code>.</li>
<li>On failure, stop and output the list.</li>
<li>On success, append the output of type <code>'p</code> to the list.  Then run <code>sep</code> and then go to step 2.</li>
</ol>
<p>In F#, generic types’ arguments go <em>before</em> the generic type.  So the type of the output is <code>'a list</code> instead of, in C#, <code>List&lt;'a&gt;</code>.  Also in F#, as you might have noticed, type variables are prefixed with a single quote  because single quotes go out on Friday night and have all sorts of fun.</p>
<h3>Function application with |&gt;&gt;</h3>
<pre><code>val (|&gt;&gt;): Parser&lt;'a,'u&gt; -&gt; ('a -&gt; 'b) -&gt; Parser&lt;'b,'u&gt;
</code></pre>
<p><img src="http://blog.fogcreek.com/wp-content/uploads/2013/04/5-applicative.png" alt="p |&gt;&gt; f"></p>
<p>Run <code>p</code> once, which outputs an object of type <code>'t</code>.  Pass said object to <code>f: 'a -&gt; 'b</code>.  Result: output of type <code>'b</code>.</p>
<h2>The code</h2>
<p>“OK,” you say. “This is snazzy, but now what?”</p>
<p>H.A.P. is kneading his temples back and forth with his fingers.  “This is what I am thinking,” he says.  You wonder if he could think less dramatically.</p>
<ul>
<li>A keyword is a <em>phrase</em> or just a <em>word</em>.
<ul>
<li>A phrase is a bunch of characters surrounded by quotation marks.</li>
<li>A word is a bunch of non-space characters.</li>
</ul>
</li>
<li>A filter is a word (from a whitelist of approved words) followed by a colon followed by an argument (which is a word or phrase).</li>
<li>Our input is a list of keywords and filters.</li>
</ul>
<h3>Keywords</h3>
<p>Since elasticsearch differentiates between phrase and word searches,  we need to encode the difference using types so that the code that  calls into our query parser knows what to do.  In F#, the way we model this is with a <a href="http://msdn.microsoft.com/en-us/library/dd233226.aspx">union type</a>, which is analogous to  <code>union</code> in the C programming language.  So you push H.A.P. out of the way and type:</p>
<pre><code>type Keyword = Word of String | Phrase of string
</code></pre>
<p>In F#, you should read this as “<code>Keyword</code> is a type with two constructors.  Constructor number one is <code>Word</code>, which takes a <code>string</code> and returns a <code>Keyword</code>.  (Constructors are just functions.)  Constructor number two is <code>Phrase</code>, which takes a <code>string</code> and returns an <code>Keyword</code>.”</p>
<p>A word is a string of one or more characters that are not spaces,  so we pull out the built-in <code>many1Satisfy</code> from earlier:</p>
<pre><code>let notSpace c = c &lt;&gt; ' '
let word = many1Satisfy notSpace
</code></pre>
<p>A phrase is trickier.  A phrase is a string of characters (let’s call them <em>innards</em>) between two quotation marks.  Innards cannot contain a quotation mark unless it is escaped by a backslash.  For example: <code>"Maria said, \"I love you,\" to Mark. Mark gasped."</code> would be a single valid phrase.</p>
<p>So a rigorous definition: one innard is  <em>either</em> (1) parse a non-quotation-mark character <em>or</em>  (2) parse a backslash followed by a quotation mark.  This calls for another <code>&lt;|&gt;</code>.</p>
<pre><code>let phraseEscape = pchar '\\' &gt;&gt;. pchar '"'
let phraseInnard = phraseEscape &lt;|&gt; noneOf "\""
</code></pre>
<p>And a phrase is just many innards surrounded by quotation marks:</p>
<pre><code>let phraseInnards = manyChars phraseInnard
let phrase = between (pchar '"') (pchar '"') phraseInnards
</code></pre>
<p><code>between left right middle</code> is another built-in parser.  As the <a href="http://www.quanttec.com/fparsec/reference/primitives.html#members.between">documentation for <code>between</code> notes</a>, it is really just shortand for <code>left &gt;&gt;. middle .&gt;&gt; right</code>.</p>
<p>We now have two parsers of type <code>string</code>: <code>word</code> and <code>phrase</code>.  All that remains is to lift them into the <code>Keyword</code> type:</p>
<pre><code>let keyword = (phrase |&gt;&gt; Phrase) &lt;|&gt; (word |&gt;&gt; Word)
</code></pre>
<p>“Quiz:”, announces H.A.P.  “This will not work if we switched around the arguments to <code>&lt;|&gt;</code> i.e. <code>(word |&gt;&gt; Word) &lt;|&gt; (phrase |&gt;&gt; Phrase)</code>.  Why?”</p>
<p>Who just <em>gives out</em> quiz questions?  What kind of person does that?  Quiz: What kind of person does that?</p>
<h3>Filters</h3>
<p>Here are all the filters we have in Kiln search:</p>
<pre><code>type Filter =
    | Author of string
    | File of string
    | Project of string
    | Repo of string
</code></pre>
<p>Remember, the right-hand side of a type definition lists the constructors  for that type and also the arguments of the constructor.  For example, we can infer from this that <code>Author</code> has type <code>string -&gt; Filter</code>.</p>
<p>There are three parts to a filter in the Kiln search-query syntax:</p>
<ol>
<li>The name of the filter.  Like <code>author</code>.</li>
<li>The colon.</li>
<li>The filter’s argument(s).  Like <code>Tyler</code> in <code>author:Tyler</code>.</li>
<li>We also want to allow phrase searches like <code>author:"Tyler"</code> or <code>author:"Tyler H"</code>.  Because phrases are cool.</li>
</ol>
<p>The code:</p>
<pre><code>let filterName = (* to be written *)
let findFilter = function
    | "author" -&gt; Author
    | "file" -&gt; File
    | "project" -&gt; Project
    | "repo" -&gt; Repo
    | _ -&gt; raise &lt;| Exception "Invalid filter name"
let pipeline (f, x) = f x
let filter =
    (filterName |&gt;&gt; findFilter)
        .&gt;&gt; (pchar ':')
        .&gt;&gt;. (phrase &lt;|&gt; word)
        |&gt;&gt; pipeline
</code></pre>
<p>The strategy:</p>
<ol>
<li>Parse the filter name. For example, given <code>author:"Tyler"</code>, consume <code>author</code>.</li>
<li>Find the corresponding <code>Filter</code> constructor (<code>findFilter</code>).  For example, <code>author</code> means <code>Author: string -&gt; Filter</code>.  If the filter name is not one of the ones we recognize, the parser should fail.</li>
<li>Parse a colon, throw it away (<code>.&gt;&gt;</code>).  In our example, this now leaves us with just <code>"Tyler"</code>.</li>
<li>Parse the filter argument, which can be a word or, now, a phrase.</li>
<li>With <code>.&gt;&gt;.</code>, tuple the <code>Filter</code> constructor and the <code>string</code> argument together.</li>
<li>Pass the tuple to <code>pipeline</code>, which applies the filter constructor (<code>string -&gt; Filter</code>) to the filter argument (<code>string</code>)  and returns a <code>Filter</code>.</li>
<li>We now have a <code>Parser&lt;Filter, unit&gt;</code>!</li>
</ol>
<p>Which looks like:</p>
<p><img src="http://blog.fogcreek.com/wp-content/uploads/2013/04/8-filter.png" alt="filter" style="width: 627px;height: 892.4940079893476px"></p>
<p>Remember that the blue arrows track how the string is consumed,  which in this case is fairly simple, and the black arrows track how the output  is manipulated, which is more complicated.</p>
<p>FParsec’s operators sure are a double-edged sword:  the code for <code>filter</code> is hard to read without knowing what the operators do.  But we did just compose a smart complicated parser without breaking a sweat.  Overall I would say the library hurts the bright-eyed beginner  but benefits the adept novice—but look at you guys,  you guys are all adept novices already and I am proud of you.</p>
<p>Speaking of getting advanced in F#, H.A.P. has taken your wireless keyboard  and typed:</p>
<pre><code>let filterName =
    ["author"; "file"; "project"; "repo"]
    |&gt; Seq.map pstring
    |&gt; choice
</code></pre>
<p>“Get out of here, H.A.P.  Do you ever drink water?”  He stares out the window, licking his lips.</p>
<p>You should know that <code>x |&gt; f</code> in F# is the same as <code>f x</code>.  Futhermore, <code>Seq.map f</code> maps a function over a list and returns the new list,  and <code>choice [p, q, r]</code> is roughly the same as <code>p &lt;|&gt; q &lt;|&gt; r</code>.  While you are puzzling this all out, H.A.P. has placed one hand gently on the window,  the way people do at inmate visitations.</p>
<h3>Putting keywords and filters together</h3>
<p>We want to store keywords and filters together in one list  for simplicity’s sake, so let’s introduce another union type:</p>
<pre><code>type Atom = KeywordAtom of Keyword | FilterAtom of Filter
</code></pre>
<p>Example: in the query</p>
<pre><code>"foo bar" project:Eggs date:yesterday..now
</code></pre>
<p>The first atom is a phrase <code>foo bar</code>.  The second and third atoms are filters.</p>
<p>And so we turn to the <code>&lt;|&gt;</code> operator one last time:</p>
<pre><code>let atom = (filter |&gt;&gt; FilterAtom) &lt;|&gt; (keyword |&gt;&gt; KeywordAtom)
</code></pre>
<p>This has the type <code>Parser&lt;Atom, unit&gt;</code>, as desired.  “Always satisfying to have the type of a function match the name of the function, isn’t it?”  H.A.P. says as he reclines in your office chair.  You were not aware your office chair had reclining capabilities.</p>
<h2>It’s a magical world, Hobbes, ol’ buddy</h2>
<p>H.A.P. stands up from the nap he was taking on the floor.  “I am proud as well,” he says.  He takes out an “A+” sticker and puts it on your hand.  With a flourish of his hat—which was your hat, that he took—he  leaves your office.</p>
<p>There is not much left to do.  Now that we can parse an atom, we can parse a bunch of atoms separated by spaces,  which is the parser we wanted all along:</p>
<pre><code>let spaces = many1Satisfy (fun c -&gt; c = ' ')
let parser = sepBy atom spaces
</code></pre>
<p>And that’s it.  To run the parser, FParsec comes with a library function called <code>run</code>:</p>
<pre><code>exception ParseError of string

let parse input =
    match run parser input with
    | Success (atoms, _, _) -&gt; atoms
    | Failure (error, _, _) -&gt; raise (ParseError error)
</code></pre>
<p><code>run</code> returns a success or an error (another union type!).  On success, <code>atoms</code> is of type <code>atom list</code> and we simply return it.  On error, <code>error</code> is of type <code>string</code> and, since this is a toy parser,  we simply raise an exception.  (With <code>match</code>, we are using <a href="http://msdn.microsoft.com/en-us/library/dd547125.aspx">pattern matching</a>, which alone  is reason enough to try out F#.  It’s the same trick that made <code>findFilter</code> so short.)</p>
<p>And what’s the type of <code>parse</code>?  <code>parse: string -&gt; Atom list</code>.  That’s jazz, baby.</p>
<p>Sure there are some i’s to dot and t’s to cross:</p>
<ul>
<li>Parsing date-range filters.  The date filter constructor will have the type <code>DateTime -&gt; DateTime -&gt; Filter</code>  so it is not as simple as just extending <code>filterName</code> and <code>findFilter</code>.</li>
<li>Part of that is also translating human date descriptions like “yesterday” and “today” into  usable <code>System.DateTime</code> objects.</li>
<li>Better error reporting, <a href="http://www.quanttec.com/fparsec/users-guide/customizing-error-messages.html">about which there is much to say</a>.</li>
<li>Using <a href="http://www.quanttec.com/fparsec/users-guide/looking-ahead-and-backtracking.html">lookahead and backtracking</a> to make the parser more robust.</li>
<li>Writing a blog post, to which you commit not knowing that it requires you to learn more Photoshop than you ever wanted to.</li>
</ul>
<p>But it <em>is</em> nice outside and you <em>do</em> love your family.</p>
<p>I pushed <a href="https://developers.kilnhg.com/Code/Kiln/Group/babybearparser">the source code to a public Kiln repository</a>,  which contains not only the code in this blog post but also <a href="https://developers.kilnhg.com/Code/Kiln/Group/babybearparser/File/babybearparser/Testing.fs?rev=tip">some of the tests we use</a>  for our in-production parser; we are a big fan of unit testing, but who isn’t these days?  (You can run the tests by hitting <code>Test -&gt; Run -&gt; All Tests</code> in  Visual Studio.)  I took a <a href="https://developers.kilnhg.com/Code/Kiln/Group/babybearparser/History/2d328d5a9b48">crack at implementing a date-range parser</a> as a quick one-hour project but it is fairly fragile—you can do better!  Play around!  It’s what H.A.P. would want,  with those big sad eyes of his.</p>
<p>And afterward, <a href="https://secure.fogcreek.com/kiln/try/?fccmp=_blog">sign up for Kiln Harmony</a> to see all the  other cool stuff we put into our last release.</p>
<p><i><a href="http://haolian.org/">Hao Lian</a> is a programmer on the Kiln team. Did you know you can create custom vibrations in iOS?</i></p>
<img src="http://feeds.feedburner.com/~r/FogCreekBlog/~4/SJfn7ZJMKMU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.fogcreek.com/fparsec/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.fogcreek.com/feeder/?FeederAction=clicked&amp;feed=Fog+Creek+Blog&amp;seed=http%3A%2F%2Fblog.fogcreek.com%2Ffparsec%2F&amp;seed_title=Dive+into+parser+combinators%3A+parsing+search+queries+with+F%23+and+FParsec+in+Kiln</feedburner:origLink></item>
		<item>
		<title>What’s new in Kiln? Sprint.ly integration!</title>
		<link>http://feedproxy.google.com/~r/FogCreekBlog/~3/NjEX8v75y9o/</link>
		<comments>http://blog.fogcreek.com/whats-new-in-kiln-sprint-ly-integration/#comments</comments>
		<pubDate>Wed, 03 Apr 2013 16:48:12 +0000</pubDate>
		<dc:creator>Kevin Gessner</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.fogcreek.com/?p=3067</guid>
		<description><![CDATA[Do you use Sprint.ly for project management? Kiln now has a web hook that you’ll like! You can manage your Sprint.ly items using special comments in your commit messages. Simply enable the web hook in your Kiln account, then reference Sprint.ly items using Sprint.ly&#8217;s commands. As you push to Kiln, you&#8217;ll see your changesets linked [...]]]></description>
				<content:encoded><![CDATA[<p>Do you use <a href="http://sprint.ly">Sprint.ly</a> for project management? Kiln now has a web hook that you’ll like! You can manage your Sprint.ly items using special comments in your commit messages.</p>
<p><a href="http://blog.fogcreek.com/wp-content/uploads/2013/04/sprintly.png"><img class="alignnone size-full wp-image-3068" alt="sprint.ly integration" src="http://blog.fogcreek.com/wp-content/uploads/2013/04/sprintly.png" width="592" height="522" /></a></p>
<p>Simply enable the web hook in your Kiln account, then reference Sprint.ly items using <a href="http://help.sprint.ly/knowledgebase/articles/108139-available-scm-vcs-commands">Sprint.ly&#8217;s commands</a>. As you push to Kiln, you&#8217;ll see your changesets linked from your Sprint.ly items.</p>
<p><em>This web hook is available in Kiln 3.0.28 and higher. <a href="http://try.kilnhg.com">Sign up for a free trial</a> and try it out!</em></p>
<img src="http://feeds.feedburner.com/~r/FogCreekBlog/~4/NjEX8v75y9o" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.fogcreek.com/whats-new-in-kiln-sprint-ly-integration/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.fogcreek.com/feeder/?FeederAction=clicked&amp;feed=Fog+Creek+Blog&amp;seed=http%3A%2F%2Fblog.fogcreek.com%2Fwhats-new-in-kiln-sprint-ly-integration%2F&amp;seed_title=What%26%238217%3Bs+new+in+Kiln%3F+Sprint.ly+integration%21</feedburner:origLink></item>
		<item>
		<title>Sign Up For the FogBugz Beta!</title>
		<link>http://feedproxy.google.com/~r/FogCreekBlog/~3/WFYroJJTMQc/</link>
		<comments>http://blog.fogcreek.com/sign-up-for-the-fogbugz-beta/#comments</comments>
		<pubDate>Tue, 26 Mar 2013 13:57:59 +0000</pubDate>
		<dc:creator>Aaron Maenpaa</dc:creator>
				<category><![CDATA[FogBugz]]></category>
		<category><![CDATA[beta]]></category>
		<category><![CDATA[ocelot]]></category>

		<guid isPermaLink="false">http://blog.fogcreek.com/?p=2987</guid>
		<description><![CDATA[Want to see what&#8217;s coming in the next version of FogBugz? Now you can! The FogBugz team has been hard at work on a project we&#8217;ve code-named &#8221;Ocelot&#8221; for the past several months. We&#8217;ve rebuilt the core pages of FogBugz to use a completely new architecture that&#8217;s significantly faster. Like, seriously fast. And now we’re ready to start [...]]]></description>
				<content:encoded><![CDATA[<p>Want to see what&#8217;s coming in the next version of FogBugz? Now you can! The FogBugz team has been hard at work on a project we&#8217;ve code-named &#8221;Ocelot&#8221; for the past several months. We&#8217;ve rebuilt the core pages of FogBugz to use a completely new architecture that&#8217;s significantly faster. Like, seriously fast. And now we’re ready to start sharing it with you!</p>
<p>&nbsp;</p>
<h1>What&#8217;s shiny and new?</h1>
<p>The new version of FogBugz is a single page app when it comes to the list page and the case page. What&#8217;s that mean exactly?</p>
<ul>
<li>a<strong> super fast list page</strong> for listing and filtering your cases</li>
<li>a<strong> wicked fast case page</strong> for viewing and editing individual cases</li>
<li><strong>blazing fast search</strong> for finding the cases you&#8217;re interested in</li>
<li>and blink-of-an-eye fast transitions between these pages</li>
</ul>
<p>We’ve been dogfooding the new UI internally for a couple of months now and it has really improved our own experience of using FogBugz. We hope you&#8217;ll like it!</p>
<p><a href="http://blog.fogcreek.com/wp-content/uploads/2099/03/RidingTheOcelot-white3.png"><img class="alignnone  wp-image-3012" title="Riding the Ocelot" alt="Riding the Ocelot" src="http://blog.fogcreek.com/wp-content/uploads/2099/03/RidingTheOcelot-white3.png" width="490" height="354" /></a></p>
<p>&nbsp;</p>
<h1>A Word of Caution</h1>
<p>This is a beta, so <strong>there will be bugs</strong>. If you find one, <a href="http://www.fogcreek.com/sendmail.html">please contact our customer service team</a> and let them know. Furthermore, since we&#8217;re trying to get this into your hands as soon as is humanly possible, there are some caveats to the beta:</p>
<ul>
<li>The beta is for FogBugz On Demand accounts only.</li>
<li>The beta UI has only been tested in Firefox and Chrome. Support for IE10 and Safari are on our TODO list and they should mostly work, but they might not and you will probably run into cosmetic issues.</li>
<li>Customizations from the BugMonkey Plugin will not apply to the beta UI.</li>
<li>With a few exceptions, existing plugins will not interact with the beta UI.</li>
<li>A number of features have not yet been implemented including:
<ul>
<li>Custom fields</li>
<li>Quick case add on the list page</li>
<li>Graceful handling of concurrent case editing</li>
<li>Similar speed improvements and single-page-appification to Wikis, Discussion Groups, Reporting, Admin pages, etc.</li>
<li>The Working On menu</li>
<li>Searching Wiki Pages and Discussion Groups from the main search box</li>
</ul>
</li>
<li>With the exception of some specific text used in outgoing emails, the beta UI is not localized</li>
</ul>
<p>&nbsp;</p>
<h1>Share your Feedback</h1>
<p>We&#8217;re looking for feedback on: How the application feels, your general impressions, any missing features that impact your day-to-day workflow, and of course any bugs you find. Once you&#8217;ve started using the beta, please <a href="http://www.fogcreek.com/sendmail.html">contact our customer service team</a> and let them know what you think!</p>
<p>Once your account is enabled for the FogBugz Beta, you can enable and disable the beta UI on a per user basis from a link in the top right corner. If you later decide that you&#8217;d like your entire account taken off of the Beta, just let us know and we&#8217;ll be happy to take care of that for you.</p>
<p>&nbsp;</p>
<h1 id="sign-up">Sign Up!</h1>
<form id="ss-form" action="https://docs.google.com/a/fogcreek.com/spreadsheet/formResponse?formkey=dDM2NGJ3M3ZMVVNMTmRKTzB5RTdHdkE6MQ&amp;ifq" method="POST">
<div class="errorbox-good">
<div class="ss-item ss-item-required ss-text">
<div class="ss-form-entry"><label class="ss-q-title" for="entry_0">Name <span class="ss-required-asterisk">(required)</span></label><br />
<label class="ss-q-help" for="entry_0"></label><br />
<input class="ss-q-short" id="entry_0" type="text" name="entry.0.single" required="" value="" /></div>
</div>
</div>
<div class="errorbox-good">
<div class="ss-item ss-item-required ss-text">
<div class="ss-form-entry"><label class="ss-q-title" for="entry_1">Email Address <span class="ss-required-asterisk">(required)</span></label><br />
<label class="ss-q-help" for="entry_1">We will be enabling accounts in groups, and we will contact you when we&#8217;ve enabled your account.</label><br />
<input class="ss-q-short" id="entry_1" type="text" name="entry.1.single" required="" value="" /></div>
</div>
</div>
<div class="errorbox-good">
<div class="ss-item ss-item-required ss-text">
<div class="ss-form-entry"><label class="ss-q-title" for="entry_2">FogBugz Account URL <span class="ss-required-asterisk">(required)</span></label><br />
<label class="ss-q-help" for="entry_2">Feel free to <a href="https://secure.fogcreek.com/fogbugz/try/" tabindex="1024">sign up for a trial account</a> to test it out.</label><br />
<input class="ss-q-short" id="entry_2" type="text" name="entry.2.single" required="" value="" /></div>
</div>
</div>
<p><input type="hidden" name="pageNumber" value="0" /><br />
<input type="hidden" name="backupCache" value="" /></p>
<div class="ss-item ss-navigate">
<div class="ss-form-entry"><input type="submit" name="submit" value="Submit" /></div>
</div>
</form>
<style><!--
.ss-q-help, .ss-required-asterisk { color: #666; } #ss-form br, #ss-form p { display: none; } #ss-form input, .ss-q-help { display: block; } .ss-item { margin-bottom: 1em; } .ss-q-help a { text-decoration: none;}
--></style>
<img src="http://feeds.feedburner.com/~r/FogCreekBlog/~4/WFYroJJTMQc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.fogcreek.com/sign-up-for-the-fogbugz-beta/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.fogcreek.com/feeder/?FeederAction=clicked&amp;feed=Fog+Creek+Blog&amp;seed=http%3A%2F%2Fblog.fogcreek.com%2Fsign-up-for-the-fogbugz-beta%2F&amp;seed_title=Sign+Up+For+the+FogBugz+Beta%21</feedburner:origLink></item>
		<item>
		<title>Securing the Future</title>
		<link>http://feedproxy.google.com/~r/FogCreekBlog/~3/Kpnk4IQFTT8/</link>
		<comments>http://blog.fogcreek.com/securing-the-future/#comments</comments>
		<pubDate>Tue, 19 Mar 2013 16:01:18 +0000</pubDate>
		<dc:creator>Benjamin Pollack</dc:creator>
				<category><![CDATA[Kiln]]></category>

		<guid isPermaLink="false">http://blog.fogcreek.com/?p=2965</guid>
		<description><![CDATA[Congratulations! You&#8217;ve survived the first week of peacefully coexisting with both your Git- and Mercurial-loving coworkers.  With all the extra time you&#8217;ve had from not debating constantly over whose DVCS is better, you&#8217;ve written a tremendous amount of code. But you&#8217;re concerned about security.  There are so many public hack attempts going on these days. [...]]]></description>
				<content:encoded><![CDATA[<p>Congratulations! You&#8217;ve survived the first week of <a href="http://blog.fogcreek.com/announcing-kiln-harmony-the-future-of-dvcs/">peacefully coexisting with both your Git- and Mercurial-loving coworkers</a>.  With all the extra time you&#8217;ve had from not debating constantly over whose DVCS is better, you&#8217;ve written a tremendous amount of code.</p>
<p>But you&#8217;re concerned about security.  There are so many public hack attempts going on these days.  Now that you&#8217;ve actually written tons of code, you want to make sure it stays safe.  Can Kiln Harmony help you there?</p>
<p>It sure can!  In addition to all of the security features Kiln On Demand already has in place, Kiln Harmony introduces two great new features to help you secure your code: SSH and IP whitelisting.</p>
<h2>SSH support</h2>
<p>SSH used to be a way for people to remotely manage Unix systems, but it&#8217;s broadened out far beyond that original purpose, and is now widely used for all kinds of things, including securely and efficiently using Mercurial and Git with remote servers.  SSH can both be more secure, and more convenient, than traditional HTTPS approaches: it&#8217;s more convenient because you can use a single encryption key to access dozens of servers, and it&#8217;s more secure because the only password involved is one used on your local machine to manage your encryption key.  Dictionary attacks have no meaning in the world of properly secured SSH.</p>
<p><img src="http://blog.fogcreek.com/wp-content/uploads/2013/03/SSH-with-SSH-URL.png" alt="The protocol selector, set to SSH" width="416" height="201" class="alignnone size-full wp-image-2981" /></p>
<p>If you&#8217;re already comfortable with SSH, all you have to do is upload your public key and you&#8217;ll be good to go.  If you aren&#8217;t, <a href="http://kiln.stackexchange.com/questions/4719/how-do-i-use-kiln-with-ssh">check out our guide for using SSH with Kiln Harmony</a>.</p>
<h2>IP Whitelisting</h2>
<p><em>Okay</em>, you ask, <em>but I actually like HTTPS just fine.  What I&#8217;m <strong>really</strong> worried about is someone from a foreign country accessing my Kiln account.  What about me?</em></p>
<p>We&#8217;ve got a solution for you, too.  It&#8217;s called IP whitelisting, and it allows you to restrict access to your Kiln account to a specific collection of IP addresses.  Say, the IP block your company uses for its public internet access.</p>
<p><img src="http://blog.fogcreek.com/wp-content/uploads/2013/03/IP-whitelisting.png" alt="IP whitelisting" width="437" height="145" class="alignnone size-full wp-image-2969" /></p>
<p>To use IP whitelists, just have an administrator add the IP blocks that should be allowed access to your Kiln account (in <a href="https://en.wikipedia.org/w/index.php?title=Classless_Inter-Domain_Routing&#038;oldid=501560525#IPv4_CIDR_blocks">IPv4 CIDR format</a>), and then&#8230;well, actually, that&#8217;s it.  As far as people outside your company know, your Kiln website doesn&#8217;t even exist.</p>
<h2>Better understand your permissions</h2>
<p>Permissions may not be a sexy topic, but they&#8217;re important.  Even if a developer ought to be using your Kiln account, you probably still want to make sure they don&#8217;t accidentally alter the release source code two days before you ship.</p>
<p>Kiln has long provided a powerful, hierarchical access control mechanism to set detailed permissions on your projects and repositories, but we thought it could be a little difficult both to quickly see what someone&#8217;s permissions were, and to change them if necessary.</p>
<p><a href="http://blog.fogcreek.com/wp-content/uploads/2013/03/Permissions.png"><img src="http://blog.fogcreek.com/wp-content/uploads/2013/03/Permissions-300x145.png" alt="Permissions" width="300" height="145" class="alignnone size-medium wp-image-2975" /></a></p>
<p>In Kiln Harmony, we&#8217;ve completely redone the permissions UI.  You can now see at a glance who has what permissions, and changing someone&#8217;s permissions is as easy as drag-and-drop.  For those of you with very large Kiln accounts, we think you&#8217;ll find the new interface also scales better, too, ensuring that Kiln Harmony can grow just as easily as your organization.</p>
<h2>Kiln&#8217;s got your back</h2>
<p>On top of all that, don&#8217;t forget all the existing security features in Kiln.  The Activity Feed is a great way to monitor who&#8217;s pushing changes into your source, and because both Git and Mercurial identify all of their contents by SHA-1 hash, it&#8217;s incredibly difficult for a malicious hacker to replace your code without anyone knowing.  And, as always, the Kiln On Demand data center is stored in a secure building staffed 24/7, so the only way for data to get out is via secure HTTPS and SSH connections.  We keep your data safe.</p>
<img src="http://feeds.feedburner.com/~r/FogCreekBlog/~4/Kpnk4IQFTT8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.fogcreek.com/securing-the-future/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.fogcreek.com/feeder/?FeederAction=clicked&amp;feed=Fog+Creek+Blog&amp;seed=http%3A%2F%2Fblog.fogcreek.com%2Fsecuring-the-future%2F&amp;seed_title=Securing+the+Future</feedburner:origLink></item>
		<item>
		<title>Loving the Code</title>
		<link>http://feedproxy.google.com/~r/FogCreekBlog/~3/ndnVJV-FYls/</link>
		<comments>http://blog.fogcreek.com/loving-the-code/#comments</comments>
		<pubDate>Fri, 15 Mar 2013 14:37:57 +0000</pubDate>
		<dc:creator>Benjamin Pollack</dc:creator>
				<category><![CDATA[Kiln]]></category>

		<guid isPermaLink="false">http://blog.fogcreek.com/?p=2950</guid>
		<description><![CDATA[So you&#8217;ve written tons of code that you&#8217;ve pushed to Kiln using both Mercurial and Git. But what about after that point? What has Kiln done for you lately to make working with code better after you push it? Revised reviews and rejecting rejection There&#8217;s a lot more in a name than most people realize. [...]]]></description>
				<content:encoded><![CDATA[<p>So you&#8217;ve written tons of code that you&#8217;ve <a href="http://blog.fogcreek.com/announcing-kiln-harmony-the-future-of-dvcs/">pushed to Kiln using both Mercurial and Git</a>. But what about after that point? What has Kiln done for you lately to make working with code better <em>after</em> you push it?</p>
<h2>Revised reviews and rejecting rejection</h2>
<p>There&#8217;s a lot more in a name than most people realize. Kiln code reviews, one of the oldest pieces of the product, have offered only two real ways to mark your attitude towards a piece of code: &#8220;Approved&#8221; and &#8220;Rejected.&#8221; But developers, just like everyone else, hate rejection—especially when the thing getting rejected is our code. It makes us feel bad. Plus, most of the time, the person who marks the review as &#8220;Rejected&#8221; doesn&#8217;t <em>really</em> mean that the code is rejected forever and ever—just that the current version needs some work before it&#8217;ll be ready to get merged into the rest of the code base. Surely there should be some way to indicate that the code still needs some love, but that it&#8217;s headed generally in the right direction?</p>
<p><img class="alignnone size-full wp-image-2962" alt="needswork2" src="http://blog.fogcreek.com/wp-content/uploads/2013/03/needswork2.png" width="416" height="269" /></p>
<p>We know it&#8217;s a small thing, but we created a new status just for all of you: &#8220;Needs Work.&#8221; When something isn&#8217;t quite ready to merge, but isn&#8217;t actually all that bad, just press the &#8220;Needs Work&#8221; button. The reviewee will know you saw the code and formed an opinion, but you won&#8217;t sound like you&#8217;re being a mean developer and rejecting your colleague&#8217;s almost-awesome work.</p>
<p>We also made it easier than ever to get your code out of &#8220;Needs Review&#8221;: we now flag unread comments, so you can focus just on what&#8217;s changed since you last visited, and we allow you to use <a href="http://blog.fogcreek.com/kiln-powered-by-elasticsearch/">Kiln&#8217;s excellent search</a> to add <em>and remove</em> changesets from a review.</p>
<h2>Searching for the impatient</h2>
<p>In Kiln 2.9, we introduced an entirely new search architecture based around <a href="http://www.elasticsearch.org/">elasticsearch</a> that gave you instant results on changesets, code, and more. But we made one very annoying design decision: we made you press &#8220;enter&#8221; before we started showing results. But come on: in this day of rapid-fire Internet news and Google results, you want your searches <em>now</em>, before you&#8217;ve even finished figuring out quite what you&#8217;re searching for.</p>
<p><img class="alignnone size-full wp-image-2955" alt="SearchEverywhere_small" src="http://blog.fogcreek.com/wp-content/uploads/2013/03/SearchEverywhere_small.png" width="405" height="220" /></p>
<p>We heard you, so beginning in Kiln Harmony, we&#8217;ll start looking through changesets, code, and file names, beginning the second you start typing. Not only does this get you the results you want faster; the feedback you get as you type helps you figure out what you&#8217;re looking for in the first place. On the Kiln team, we&#8217;ve found instant searches so useful that we barely ever go to the &#8220;real&#8221; results page, and we bet you will, too.</p>
<h2>Organizing for the harried</h2>
<p>So, finding stuff via search is easier, but what about organizing and navigating your massive amounts of code? Kiln Harmony&#8217;s got two new features to help you manage your projects, and we think they add up to make a big difference.</p>
<p><img class="alignnone size-full wp-image-2956" alt="StarredRepos_small" src="http://blog.fogcreek.com/wp-content/uploads/2013/03/StarredRepos_small.png" width="405" height="220" /></p>
<p>First, we&#8217;ve got starred projects. Kiln already figures out which repositories you&#8217;ve used recently and adds them to the top of your &#8220;Browse Repositories&#8221; drop-down, but until now, there was no way to pin repositories you cared about, but didn&#8217;t frequently access.</p>
<p>Second, we&#8217;ve ditched the old modal project editing interface. Administrators can now edit projects directly. You can create and edit groups, reorganize repositories, restore deleted repositories, and manage project permissions, all without having to dive into any settings windows or activating organization mode.</p>
<h2>Read me! Read me! Read all about it!</h2>
<p>It&#8217;s a little thing, but a little bit of documentation can go a long way. Unfortunately, Kiln doesn&#8217;t really have any type of documentation store of its own, but many projects, at the very least, include a <code>readme</code> file of some variety; wouldn&#8217;t it be nice if you could quickly view that inline in Kiln?</p>
<p><img class="alignnone size-full wp-image-2957" alt="Readme_small" src="http://blog.fogcreek.com/wp-content/uploads/2013/03/Readme_small.png" width="405" height="220" /></p>
<p>Now you can. If you have a file named any variant of <code>readme</code>, <code>readme.txt</code>, or (for Markdown) <code>readme.md</code>, we&#8217;ll let you browse a formatted version of it, right on a repository&#8217;s landing page. Just click the &#8220;Read More&#8221; link. This can be especially handy for open-source projects mirrored into your Kiln installation, since those generally have very well-written Markdown-based <code>README</code> files that can be a great introduction to using the code.</p>
<h2>Plays well with others</h2>
<p>Kiln is the grand fortress where you prepare all of your code, but ultimately, that code needs to interact with lots of other services.</p>
<p><img class="alignnone size-full wp-image-2958" alt="WebHooks_small" src="http://blog.fogcreek.com/wp-content/uploads/2013/03/WebHooks_small.png" width="405" height="220" /></p>
<p>Beginning with Kiln Harmony, we&#8217;ve dramatically expanded our integrated services. And remember that because Kiln Harmony makes all repositories available as both Git and Mercurial, that means that you can suddenly integrate your Mercurial repositories with services that do not traditionally allow you to do so, such as Microsoft Azure. We&#8217;re excited to rapidly roll out more integration with other services leveraging exactly this functionality in the coming months.</p>
<h2>And even more!</h2>
<p>Kiln Harmony is a tremendously large release, and while these are some of our favorite stand-out features, there&#8217;s even more that we haven&#8217;t covered: you can subscribe to repositories, getting emails whenever new changesets are pushed. You can move Git refs and Mercurial bookmarks through drag-and-drop. You can adjust how often code reviews send you email, you can take advantage of Mercurial phases, and you can customize reviews much more flexibly right from the activities page. And we haven&#8217;t even had a chance to discuss all the new security improvements; we&#8217;ll save that &#8217;til next time.</p>
<p>No matter where you look, Kiln Harmony is a tremendous step forward. We really hope you enjoy it. We know we have.</p>
<img src="http://feeds.feedburner.com/~r/FogCreekBlog/~4/ndnVJV-FYls" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.fogcreek.com/loving-the-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.fogcreek.com/feeder/?FeederAction=clicked&amp;feed=Fog+Creek+Blog&amp;seed=http%3A%2F%2Fblog.fogcreek.com%2Floving-the-code%2F&amp;seed_title=Loving+the+Code</feedburner:origLink></item>
		<item>
		<title>Kiln Harmony Internals: the Basics</title>
		<link>http://feedproxy.google.com/~r/FogCreekBlog/~3/d8CE5kqVpcc/</link>
		<comments>http://blog.fogcreek.com/kiln-harmony-internals-the-basics/#comments</comments>
		<pubDate>Thu, 14 Mar 2013 14:33:52 +0000</pubDate>
		<dc:creator>Benjamin Pollack</dc:creator>
				<category><![CDATA[Kiln]]></category>

		<guid isPermaLink="false">http://blog.fogcreek.com/?p=2917</guid>
		<description><![CDATA[So let&#8217;s cut to the chase: you&#8217;re here because you saw Tuesday&#8217;s announcement of Kiln Harmony, you know enough about Mercurial and Git to know that the two systems aren&#8217;t actually isomorphic, and you&#8217;re therefore wondering what the catch is. You want to know how we actually pull it off, diving as far under the [...]]]></description>
				<content:encoded><![CDATA[<p>So let&#8217;s cut to the chase: you&#8217;re here because you saw <a href="http://blog.fogcreek.com/announcing-kiln-harmony-the-future-of-dvcs/">Tuesday&#8217;s announcement of Kiln Harmony</a>, you know enough about Mercurial and Git to know that the two systems aren&#8217;t actually isomorphic, and you&#8217;re therefore wondering what the catch is. You want to know how we actually pull it off, diving as far under the covers as it takes to really believe it&#8217;s possible and that we&#8217;ve done it.</p>
<p>We hear you. In fact, it took us <em>months</em> of prototyping to reach a point where we were getting happy with the results, and lots of actually <em>using</em> Kiln Harmony to get all of the actual workflow-related issues right. And until that point, we ourselves weren&#8217;t 100% sure if it&#8217;d ever really be possible, so we definitely don&#8217;t blame you for having the same doubts.</p>
<p>What we want to do here is to provide a series of posts where we dive right down into the algorithms that make this whole thing work. In each post, we&#8217;ll take a look at one part of the system, discuss the high-level view, dive into the low-level gotchas, and hopefully convince you that, yes, while this is insanely complicated, it&#8217;s also tractable, and there aren&#8217;t any catches involved. And, as a bonus, we&#8217;ll even be hosting <a href="http://www.fogcreek.com/nocompromise/">a Q&amp;A with the Kiln Harmony developers</a> next week for you to ask any questions we&#8217;re not answering in this series.</p>
<p>In the meantime, since today is our first day, let&#8217;s start at the top: we&#8217;ll discuss how and when Kiln Harmony engages, and then dive into how Git commit objects become Mercurial changeset entries and vice-versa.</p>
<p>Ah yes, one more thing: posts like this don&#8217;t really have much use for images. It&#8217;s kind of one of those text-and-source-code affairs. To make up for that, and to prevent your brain turning into those &#8220;this is your brain on drugs&#8221; fried egg shticks, I&#8217;ll try to include lots of pictures of my cats. Here comes one now:</p>
<p><img class="alignnone size-medium wp-image-2930" alt="Hugging Kitties" src="http://blog.fogcreek.com/wp-content/uploads/2013/03/Hugging-Kitties-300x224.jpg" width="300" height="224" /></p>
<h2>If you push me, I&#8217;ll push you</h2>
<p>As <a href="http://blog.fogcreek.com/announcing-kiln-harmony-the-future-of-dvcs/">mentioned in our launch post</a>, Kiln Harmony had three iron requirements: it had to be repeatable (you couldn&#8217;t get different repos on subsequent translation attempts), lossless (we couldn&#8217;t discard data just because it was hard to preserve), and idempotent (a given Git commit or Mercurial changeset had to always generate <em>exactly</em> the same counterpart for a given repository, with no exceptions—even across Kiln installations or with a side-trip through a site like GitHub or Google Code). This suggested to us a pretty straightforward architecture: every single repository would be stored both as Git and Mercurial on-disk, and we would write a daemon that synchronized changes between the two repositories.</p>
<p>The exact nature of this daemon will continue to change as we improve Kiln Harmony. At the moment, the daemon—let&#8217;s call it the Harmonizer—is written in Python, interacting with Git repositories via a customized version of Dulwich, and Mercurial repositories via a customized version of&#8230;well, since it was already written in Python, Mercurial itself. What customizations, you ask? Well, we had to customize both of these libraries to allow us to <em>deliberately generate corrupt repositories</em>—not something we expect would be readily accepted upstream. (That statement probably sounds both evil and insane to you, but it&#8217;s neither. We&#8217;ll make use of generating corrupt data in today&#8217;s blog post, which will give you a feel for where this comes up.)</p>
<p>Whenever you push to Kiln Harmony, we lock all incoming pushes from the <em>other</em> DVCS (e.g., if you just pushed Git, we will block any incoming Mercurial pushes), and begin translation. When the translation is complete, we run translation the other direction, in a cycle, until no work happens for one complete iteration. We then notify the website new data is available, store information about the new changesets (including the Git to Mercurial mapping), and relinquish the write lock.</p>
<p>So far, no rocket surgery. This is important, but mind-numbingly boring, so here&#8217;s another picture of a cat.</p>
<p><img class="size-medium wp-image-2923" alt="Bulldozer_Small" src="http://blog.fogcreek.com/wp-content/uploads/2013/03/Bulldozer_Small-300x225.jpg" width="300" height="225" /></p>
<h2>I&#8217;m a committer</h2>
<p>Let&#8217;s talk about nearly isomorphic data.</p>
<p>Git commits and Mercurial changesets include nearly the same stuff: they both include timestamps, a committer, a description of what happened, some parents (optional), and what amounts to a pointer to what code is actually included in that version. So we have our first naive algorithm to convert: get the file contents and metadata converted somehow (we&#8217;ll cover that in another post, but for now, assume we&#8217;ve somehow already got that part working), then make a changeset or commit, using the field-for-field copy of the data in its peer.</p>
<p>Great idea, and it&#8217;ll work for very simple Mercurial or Git repositories. But it falls down fast in the real world.</p>
<p>Let&#8217;s start by just trying to figure out how to convert the <em>valid</em> data we&#8217;re going to come across—because, trust me, there&#8217;s going to be a lot of <em>invalid</em> data we&#8217;re going to have to work with, too.</p>
<h2>Extra, extra, read all about it</h2>
<p>Let&#8217;s start with something insanely common in the Git world that gets us into trouble: the distinction between authors and committers. In Git, the person who actually <em>wrote</em> the code is called the author. Let&#8217;s say that person is Sara. Sara might commit and push the code herself to the official repository, in which case the author and committer will both be her. But more likely, she&#8217;ll submit it as a pull request or send her patch to a mailing list, where someone else (let&#8217;s call him John) rebases the change on master and then pushes <em>that</em> to the official repository. In that case, Sara stays the author, but John is now the committer.</p>
<p>Problem: Mercurial changesets have only one field, the username, which corresponds most directly with a Git commit&#8217;s <em>author</em>. They don&#8217;t have an equivalent of the committer. Further, I&#8217;ve been glossing this a bit, but the author and the committer can also both have their own timezones and their own time stamps, so we&#8217;ll need to preserve that data somehow, too.</p>
<p>Thankfully, there&#8217;s a solution: both Git and Mercurial allow additional data, called <em>extras</em>, to be stored in their commits and changesets. So here&#8217;s what we&#8217;ll do: whenever we have data only Git can understand, we store it as an extra in the Mercurial side. When we have data only Mercurial understands, we&#8217;ll store it as an extra on the Git side. Finally, while it&#8217;s not quite applicable here, we&#8217;ll decree that explicitly stored extras that we recognize trump any data &#8220;officially&#8221; in the commit.</p>
<p>How does that apply here? Git authors become Mercurial usernames. Git committers, and their associated data, will become custom extras in the Mercurial changeset.</p>
<p>You can see these right now, if you grab the Harmony version of a Git repository that has these. Let&#8217;s take a look:</p>
<pre>$ hg clone -U https://mirrors.kilnhg.com/Code/Mirrors/Tools/Dulwich
destination directory: Dulwich
requesting all changes
adding changesets
adding manifests
adding file changes
added 1671 changesets with 3630 changes to 355 files (+1 heads)
$ cd Dulwich
$ hg debugdata -c 3ff0539fff4f
2065f43762d222a70e915735b4d348e579ed45c6
Jelmer Vernooij &lt;jelmer@samba.org&gt;
1243726211 7200 -kiln-git-author:Ronald Blaschke &lt;ron@rblasch.org&gt; -kiln-git-commit-message:Mrn8;b7gLHX&gt;Mg~b1n
dulwich/_objects.c
dulwich/_pack.c

Fix sentinels.</pre>
<p>As you can see, the fields Kiln adds are all prefixed with <code>-kiln-</code>, to minimize the chance that any other software tries to use the same keys. We also try to minimize their use, so if the committer and author are the same, or at least share the same timestamp, we won&#8217;t store the redundant data. But worst-case, we&#8217;ve introduced just a couple extras keys: <code>-kiln-git-author</code>, <code>-kiln-git-author-time</code>, and <code>-kiln-git-author-tz</code>. So far, so good. (There&#8217;s also an extra key in there, but we&#8217;ll come back to that later.)</p>
<h2>A rose by any other name would be a spatula</h2>
<p>So are we all set for users now? Not quite. All we did was switch which tool gives us problems. Git expects usernames for committers and authors to have a set format, which is (approximately) the regex <code>[^&lt;]* +&lt;(.*)&gt;</code>. This is all well and good, and <em>most</em> Mercurial repositories have usernames in this format as well, but, unlike Git, Mercurial does not <em>require</em> this format. Especially in repositories converted from Subversion, you&#8217;ll frequently see usernames like <code>john</code> or <code>sara</code> instead of <code>John Example &lt;john@example.com&gt;</code>.</p>
<p>We&#8217;ll fix this in two pieces: first, to make Git happy, we unilaterally declare that every anonymous user who has a commit in Kiln Harmony shares the free email address <code>unknown@kiln.example.com</code>. Second, to keep Mercurial happy on the return, we store the raw username as a <em>Git</em> extras field, <code>kilnhgusername</code>, so we can restore the verbatim name when we go back to Hg. Remember how I said earlier that extras win over &#8220;official&#8221; data? That comes up here so that Mercurial won&#8217;t pick up the munged Git username on the return: if <code>kilnhgusername</code> is present, it trumps the Git username on the commit.</p>
<p>Let&#8217;s take a look:</p>
<pre>$ git clone https://mirrors.kilnhg.com/Code/Mirrors/Tools/Mercurial.git
Cloning into 'Mercurial'...
remote: Counting objects: 98193, done.
remote: Compressing objects: 100% (22363/22363), done.
remote: Total 98193 (delta 75822), reused 98117 (delta 75746)
Receiving objects: 100% (98193/98193), 24.33 MiB | 2.63 MiB/s, done.
Resolving deltas: 100% (75822/75822), done.
Checking out files: 100% (1015/1015), done.
$ cd Mercurial
$ git show --format=raw 12a7480271a2
commit 12a7480271a246ae990c4558a878b6628bb19550
tree 8bf68397176781c35ad65bccbeb29be8833600c3
parent 16bd8634c95aa7120aa7a7371705538b89e51576
author Stephen Darnell &lt;unknown@kiln.example.com&gt; 1122488324 +0800
committer Stephen Darnell &lt;unknown@kiln.example.com&gt; 1122488324 +0800
kilnhgrawdescription L1bhgVIVCnbZKp6AY*TBZDDR?AZ%%FWgu^GbZKvHAarjabZKp6AZTYGV{dJ3VQyq|3JL
kilnhgusername Stephen Darnell

    Add a --time command line option to time hg commands

diff --git a/mercurial/commands.py b/mercurial/commands.py
...</pre>
<p>Okay, not so bad. Plus, I think we earned a cat. A good one. Maybe something retro?</p>
<p><img class="alignnone size-medium wp-image-2926" alt="Elaine clawing the oven" src="http://blog.fogcreek.com/wp-content/uploads/2013/03/IMG_0013-300x300.jpg" width="300" height="300" /></p>
<h2>Commits beyond description</h2>
<p>Mercurial and Git both allow you to have descriptions to, erm, describe what you&#8217;ve done. So we just copy those, right?</p>
<p>Well, no. Git descriptions can have any encoding, whereas Mercurial ones have to be UTF-8. But, thankfully, we can use a similar trick here to what we used with Git authors: we&#8217;ll use changeset extras to store the Git encoding (<code>-kiln-git-commit-encoding</code>) and the original description&#8217;s byte sequence (<code>-kiln-git-commit-message</code>), and we&#8217;ll lossily transcode the Git commit message to UTF-8 so Mercurial users do see a description when they run <code>hg log</code>. Going the other direction, we just mark Mercurial descriptions as being UTF-8 encoded, and we&#8217;re done. Right?</p>
<p>Almost. Up to this point, we&#8217;ve been focusing on how we translate <em>valid</em> data found in Git and Mercurial repositories. But it turns out that a lot of the actual repositories out there have <em>grossly invalid data</em>. You see, both tools started getting used, in big ways, before their data formats were really 100% stabilized. In some cases, it&#8217;s not that the data is so much invalid as that the formats slightly changed. In others, insufficient data validation meant corrupt data could make it to disk.</p>
<p>How&#8217;s that apply here? Well, <em>in theory</em>, all Mercurial descriptions are UTF-8. <em>In practice</em>, you will find Mercurial repositories whose descriptions are in completely random encodings (we found lots of Latin-1, a little KOI8, some ShiftJIS, and smatters of other encodings), and, worse, you will find descriptions which are not valid in <em>any</em> known encoding. So now, even though &#8220;all&#8221; Mercurial descriptions are UTF-8, we also need to store the raw <em>Mercurial</em> description in Git (<code>kilnhgrawdescription</code>), and then our best-effort lossy description as the &#8220;official&#8221; Git description, so Git users have at least some chance of figuring out what was going on in a given commit. So does <em>that</em> work?</p>
<p>No. Weren&#8217;t you listening? Mercurial descriptions are UTF-8, and, <em>nowadays</em>, Mercurial actually enforces that. So out-of-the-box, working with the Mercurial API, even if you take the above steps, you can end up with repositories you can convert to Git, but that you <em>cannot convert back to Mercurial.</em></p>
<p>As the French say: <em>nom d&#8217;un chien.</em></p>
<p><img class="alignnone size-medium wp-image-2932" alt="Huddled Elaine" src="http://blog.fogcreek.com/wp-content/uploads/2013/03/Huddled-Elaine-224x300.jpg" width="224" height="300" /></p>
<p>Er, <em>nom d&#8217;un chat.</em></p>
<p>Remember how I said some of our modifications to Mercurial allow us to deliberately store invalid data, and that these modifications are neither nefarious nor insane? This is why: to allow these repositories to round-trip, we need to bypass all the safety mechanisms in Mercurial, and commit a description that is a blob of bytes in an unknown encoding. See? Purely, totally, sanely logical.</p>
<p><img class="size-medium wp-image-2924" alt="1031071313" src="http://blog.fogcreek.com/wp-content/uploads/2013/03/1031071313-300x225.jpg" width="300" height="225" /></p>
<p>Whoops, that was a <a href="https://www.khanacademy.org/">Khan Academy</a> engineer, not a cat. My bad. It won&#8217;t happen again.</p>
<p>So, anyway: <em>now</em> do we have descriptions?</p>
<p>Of course not!</p>
<p>Mercurial descriptions cannot end with a newline. Git descriptions must end with a newline. So we&#8217;ll add a newline when going to Git and remove it going to Mercurial. Right? Wrong: because Mercurial didn&#8217;t always enforce that rule. So while we do add and remove a single newline 99% of the time, the remaining 1% of the time, we store the raw Mercurial description, newline and all, in the <code>kilnhgrawdescription</code> extra in the Git commit. Oh, and because that will by definition have newlines, which we can&#8217;t (sanely) store in a Git extras field, we&#8217;ll also <a href="http://en.wikipedia.org/wiki/Ascii85">base85 encode it</a>. Ah yes, and this will of course be another modification of Mercurial so that you can deliberately store improperly <em>formatted</em> descriptions that are nevertheless valid encodings.</p>
<p>So <em>now</em> are we call good with descriptions? Well, descriptions, yes, but commits in general? Not even close. Git timezones aren&#8217;t always valid, so we happily welcome our new <code>-kiln-git-commit-tz-raw</code> and <code>-kiln-git-author-tz-raw</code> overlords. Mercurial changesets end up having the same problem, so <code>kilnhgdatetime</code> is born unto the world. And so on and so forth.</p>
<p>When you&#8217;re done, you have a disgusting pile of extras on both sides, but you <em>also</em> have repositories that are human-friendly, <em>and</em> round-trip. So it&#8217;s worth it in the end.</p>
<p>Wait a minute. Disgusting pile of extras. Do we round-trip extras?</p>
<h2>No, no, no, this won&#8217;t do at all!</h2>
<p>Git extras are really more like a text blob at the end of the official commit area, while Mercurial&#8217;s are a sorted key-value store. That wouldn&#8217;t matter if we were the only ones using the extras, but there are, of course, other uses: both Git and Mercurial use their extras area to track rebases and to store what Subversion commit a changeset or commit came from, among other things. So we&#8217;re going to have to round-trip those, too.</p>
<p>In a maneuver that made me once jokingly refer to this product as Kiln <a href="http://en.wikipedia.org/wiki/Ouroboros">Ouroboros</a>, we of course solve the problem of how to preserve extras by using extras. The implementation here is incredibly uninteresting: we use prefixes to avoid having Git extras collide with Mercurial extras or use base85-encoded JSON dictionaries, depending on which direction we&#8217;re going and what we&#8217;re doing. And <em>that</em> ends up getting you <em>almost all the way through commits and changesets</em>.</p>
<h2>But wait, there&#8217;s more!</h2>
<p>Almost? Well, yeah. Those concepts of branching and merging that practically make DVCSes what they are? We skipped past all of that.</p>
<p>But I&#8217;m out of cat pictures, and you&#8217;ve got enough to think about for the time being. So let&#8217;s start tackling those concepts in our next post. In the meantime, go out, get some coffee, and enjoy knowing that the Kiln team worried about all of this so that you don&#8217;t have to.  (And, if you haven&#8217;t yet, go <a href="http://try.kilnhg.com">make a Kiln Harmony account</a> so you can start playing with everything we just talked about yourself.)</p>
<img src="http://feeds.feedburner.com/~r/FogCreekBlog/~4/d8CE5kqVpcc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.fogcreek.com/kiln-harmony-internals-the-basics/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.fogcreek.com/feeder/?FeederAction=clicked&amp;feed=Fog+Creek+Blog&amp;seed=http%3A%2F%2Fblog.fogcreek.com%2Fkiln-harmony-internals-the-basics%2F&amp;seed_title=Kiln+Harmony+Internals%3A+the+Basics</feedburner:origLink></item>
		<item>
		<title>Announcing Kiln Harmony: the Future of DVCS</title>
		<link>http://feedproxy.google.com/~r/FogCreekBlog/~3/xp7A74QM_aY/</link>
		<comments>http://blog.fogcreek.com/announcing-kiln-harmony-the-future-of-dvcs/#comments</comments>
		<pubDate>Tue, 12 Mar 2013 15:43:36 +0000</pubDate>
		<dc:creator>Benjamin Pollack</dc:creator>
				<category><![CDATA[Kiln]]></category>

		<guid isPermaLink="false">http://blog.fogcreek.com/?p=2886</guid>
		<description><![CDATA[For the past year, the Kiln team at Fog Creek has been increasingly silent. Sure, we&#8217;ve shipped bug fixes and a few nice new features, but there&#8217;s been a definite feeling that things have been slowing down, and we know a lot of you were wondering what on Earth we were up to. We were [...]]]></description>
				<content:encoded><![CDATA[<p>For the past year, the Kiln team at Fog Creek has been increasingly silent. Sure, we&#8217;ve shipped bug fixes and a few nice new features, but there&#8217;s been a definite feeling that things have been slowing down, and we know a lot of you were wondering what on Earth we were up to.</p>
<p>We were locked in a year-long development marathon to bring you an amazing, secret product, and we&#8217;re ready to let you in on that secret project <em>right now.</em></p>
<p>Today, we&#8217;re shipping <a href="http://www.fogcreek.com/kiln/">Kiln Harmony</a>. While Kiln Harmony ships with piles of new features, from SSH support to IP white-listing to better services integration and more, we want to focus on exactly one major feature today:</p>
<p><strong>Every single repository in Kiln Harmony can be used from both Git and Mercurial. Simultaneously.</strong></p>
<p>You read that right. <em>The war is over, and everyone wins.</em></p>
<h2>Ending the Flame War</h2>
<p>There are quite a few hosting products right now that support both Git and Mercurial, but these tools always require you to pick which DVCS you&#8217;ll use on any given project. In other words, their support is an either/or proposition: it supports <em>either</em> Mercurial <em>or</em> Git, but not both on a given project at the same time. That means you inevitably fight it out on your team on which DVCS gets to win. Pretty soon, your Mercurial and Git users aren&#8217;t even talking to one another, the company goes bankrupt, and you&#8217;re contemplating arson for the insurance money.</p>
<p>That ends now. A repository in Kiln Harmony is a repository in Kiln Harmony, and each <em>repository</em> fully supports both Git and Mercurial. No more flame wars, no more fights. Just productive coding.</p>
<iframe src="http://fast.wistia.net/embed/iframe/zk7rc2mdaq?controlsVisibleOnLoad=true&playerColor=006595&version=v1&videoHeight=353&videoWidth=627" allowtransparency="true" frameborder="0" scrolling="no" class="wistia_embed" name="wistia_embed" width="627" height="353"></iframe>
<h2>How it Works</h2>
<p>Under the hood, Kiln Harmony has a bunch of voodoo that translates Git data to Mercurial data and vice-versa in a way that is <em>repeatable</em>, <em>lossless</em>, and <em>idempotent</em>. That&#8217;s a really fancy way of saying that a given Mercurial changeset will always become the same Git commit and vice-versa, <em>even if you use that repository on another hosting service or move it to a new Kiln installation,</em> and that we don&#8217;t lose any information in the process.</p>
<p>We&#8217;ll have a whole series of blog posts this week on the technology that makes that possible, but for now, I want to focus on how you can actually use Kiln Harmony.</p>
<h2>The Magic Drop-Down</h2>
<p><img style="box-shadow: none; border: none; border-image-width: 0;" alt="The Kiln Harmony DVCS selector widget" src="http://blog.fogcreek.com/wp-content/uploads/2013/03/Harmony-DVCS-Selector.png" width="432" height="254" /></p>
<p>This is the yin-yang Kiln Harmony drop-down. If it is possible to fall in love with a drop-down, we know you&#8217;ll fall in love with this one. Whenever you&#8217;re exploring in Kiln—whether in a review, browsing history, looking at files, or reading a diff—simply click this little widget to switch between viewing the page in Mercurial or Git mode.</p>
<p>Most of the time, you&#8217;ll notice absolutely no difference—and that&#8217;s a good thing! If a file or a diff looks a given way in Mercurial, it ought to look the same way in Git. But in those few cases, like subrepositories and submodules, where Git and Mercurial have different ways to do something, you can see the difference with two clicks of a mouse.</p>
<h2>Branching</h2>
<p><img style="border: none; box-shadow: none; border-image-width: 0;" alt="Git head selector" src="http://blog.fogcreek.com/wp-content/uploads/2013/03/Git-head-selector1.png" width="485" height="322" /></p>
<p>There is one area where Git and Mercurial work pretty differently: branching. We really wanted this to be no-compromise: Mercurial and Git users shouldn&#8217;t have to change their workflows to work with each other. How do we handle that in Kiln Harmony?</p>
<p>First, the easy case: it turns out that <em>many</em> published Git and Mercurial repositories actually only ever have one branch in them to begin with. In those cases, we&#8217;ll automatically keep the Git <code>master</code> branch in sync with the Mercurial repository&#8217;s <code>tip</code> transparently. So far, so good.</p>
<p>What about multiple branches? That turns out to be a lot easier than you&#8217;d think. The past several versions of Mercurial have had a concept called bookmarks, which work similarly to Git refs: they can be added or deleted, they don&#8217;t have history, and you can be &#8220;on&#8221; one when you&#8217;re making changes. So, at a high level, Git branches just become Mercurial bookmarks and vice-versa.</p>
<p>There&#8217;s a bit of voodoo here, though, for a couple of reasons. Mercurial allows anonymous heads, which is a fancy way of saying that not all active branches necessarily have distinct names. Git doesn&#8217;t allow that. Mercurial also has a concept called <em>named branches</em>, which Git lacks. What do we do with those?</p>
<p>Kiln Harmony&#8217;s got you covered: we&#8217;ll provide bookmarks on all anonymous heads, so that all Mercurial changesets are also accessible from Git. If you use named branches, we&#8217;ll translate those into Git refs as well, so that when you refer to branch <code>foobar</code>, Git users will know what you&#8217;re talking about.</p>
<p>There&#8217;s one other little footnote, though: what about Mercurial users who have never used bookmarks before? Do you have to learn bookmarks to work with Git users through Kiln Harmony?</p>
<p>We actually think bookmarks are awesome and you should learn them even if you&#8217;re <em>not</em> using Kiln Harmony, but the general answer is, &#8220;No, you don&#8217;t.&#8221; Kiln Harmony is smart enough to infer what you meant even if you never want to play with bookmarks, or if you&#8217;re using a version of Mercurial that&#8217;s so old you don&#8217;t even have them. If you make changes that correspond to a bookmark, we&#8217;ll automatically move both the bookmark and the ref when you push.</p>
<p>What about everything else?</p>
<p>There&#8217;s a <em>lot</em> of magic that goes into Kiln Harmony. Rather than try to cram all that material into a little blog-post, we&#8217;ll be running a series of articles in the coming days on how Kiln Harmony works. We&#8217;ll take you under the covers into the details of our implementation, how we handle bizarre corner-cases, how we handle data formats that are more defined by their violations than their nominal structure, and more. If you&#8217;re the kind of person who loves reading about that kind of nitty-gritty detail, then you&#8217;ll probably enjoy reading our <a href="http://blog.fogcreek.com/kiln-harmony-internals-the-basics/">detailed articles on exactly how Kiln Harmony works</a>. You can also <a href="http://www.fogcreek.com/nocompromise/index.html?fccmp=bannounce" title="Live Kiln Harmony Q&amp;A - March 19th" target="_blank">sign up for the Kiln team&#8217;s live Q&amp;A</a>  next week.</p>
<h2>How do I get it?</h2>
<p>Beginning today, all new Kiln On Demand accounts automatically come with Kiln Harmony. If you don&#8217;t have an account, <a href="https://www.fogcreek.com/kiln/try/">make a free trial</a> and you&#8217;ll have Kiln Harmony in minutes. For our existing Kiln On Demand customers, we&#8217;ll be upgrading your accounts over the next couple of weeks. If you want to jump to the front of the queue, just <a href="http://www.fogcreek.com/sendmail.html">drop us a line</a> and we&#8217;ll make sure you&#8217;re one of the first accounts upgraded.</p>
<h2>Where do we go from here?</h2>
<p>Kiln Harmony is an incredible product, and while we think you&#8217;ll love it today, we&#8217;re going to continue making it faster, more powerful, and even easier-to-use in the months to come.</p>
<p>In the meantime, welcome to the flamewar-free future.</p>

<script charset="ISO-8859-1" src="http://fast.wistia.com/static/concat/iframe-api-v1.js"></script><img src="http://feeds.feedburner.com/~r/FogCreekBlog/~4/xp7A74QM_aY" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.fogcreek.com/announcing-kiln-harmony-the-future-of-dvcs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.fogcreek.com/feeder/?FeederAction=clicked&amp;feed=Fog+Creek+Blog&amp;seed=http%3A%2F%2Fblog.fogcreek.com%2Fannouncing-kiln-harmony-the-future-of-dvcs%2F&amp;seed_title=Announcing+Kiln+Harmony%3A+the+Future+of+DVCS</feedburner:origLink></item>
		<item>
		<title>How to Share Your Trello Board, But Not Your Secrets</title>
		<link>http://feedproxy.google.com/~r/FogCreekBlog/~3/10bmUV49I9g/</link>
		<comments>http://blog.fogcreek.com/how-to-share-your-trello-board-but-not-your-secrets/#comments</comments>
		<pubDate>Thu, 07 Mar 2013 21:40:20 +0000</pubDate>
		<dc:creator>Rich Armstrong</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.fogcreek.com/?p=2872</guid>
		<description><![CDATA[We really liked seeing this post on how WooThemes uses Trello. We love it when people show their Trello boards. However, the screenshot has the text on the cards blurred out individually. That seems like a huge hassle. There had to be a better way to share screenshots without giving away the particulars of their board. [...]]]></description>
				<content:encoded><![CDATA[<p>We really liked seeing <a href="http://adii.me/prioritization-optimization" title="Woothemes Post" target="_blank">this post</a> on how WooThemes uses Trello. We love it when people show their Trello boards. However, the screenshot has the text on the cards blurred out individually. That seems like a huge hassle. There had to be a better way to share screenshots without giving away the particulars of their board.</p>
<p>So we poked around on the internet and found <a href="http://blogs.sitepointstatic.com/examples/tech/link-blur/index.html" title="Blur Links Demo" target="_blank">this technique</a> for blurring text with CSS. (Neat!) We tailored it for Trello and created a bookmarklet that we call &#8220;Blur My Board&#8221;. </p>
<p><a href="http://goo.gl/OHeCe" title="Blur My Board Bookmarklet" target="_blank">Check out the bookmarklet here!</a></p>
<p>Need an example? Here&#8217;s an unaltered screen shot of the Trello dev board:</p>
<p><a href="http://blog.fogcreek.com/wp-content/uploads/2013/03/unblurred.jpg"><img class="aligncenter size-large wp-image-2874" alt="unblurred" src="http://blog.fogcreek.com/wp-content/uploads/2013/03/unblurred-1024x753.jpg" width="1024" height="753" /></a></p>
<p>Click the &#8220;Blur My Board&#8221; bookmarklet and here&#8217;s what it looks like afterward:</p>
<p><a href="http://blog.fogcreek.com/wp-content/uploads/2013/03/blurred.jpg"><img class="aligncenter size-large wp-image-2873" alt="blurred" src="http://blog.fogcreek.com/wp-content/uploads/2013/03/blurred-1024x633.jpg" width="1024" height="633" /></a></p>
<p>Now snap a screenshot. Refresh the page and everything goes back to normal.</p>
<p>If only there were some aphorism we could use that would capture the concept that images convey more information than text. Oh well, we hope you enjoy the bookmarklet at least.</p>
<p>If you want to show us your board, get your bookmarklet <a href="http://goo.gl/OHeCe" title="Blur My Board Bookmarklet" target="_blank">here</a>, and after you&#8217;ve blurred it, put it online somewhere and tweet us about it <a href="https://www.twitter.com/trello">@trello</a>!</p>
<img src="http://feeds.feedburner.com/~r/FogCreekBlog/~4/10bmUV49I9g" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.fogcreek.com/how-to-share-your-trello-board-but-not-your-secrets/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.fogcreek.com/feeder/?FeederAction=clicked&amp;feed=Fog+Creek+Blog&amp;seed=http%3A%2F%2Fblog.fogcreek.com%2Fhow-to-share-your-trello-board-but-not-your-secrets%2F&amp;seed_title=How+to+Share+Your+Trello+Board%2C+But+Not+Your+Secrets</feedburner:origLink></item>
		<item>
		<title>Cage Set Match: Fog Creek Infrastructure Changes</title>
		<link>http://feedproxy.google.com/~r/FogCreekBlog/~3/9C5B8e6Ny4w/</link>
		<comments>http://blog.fogcreek.com/cage-set-match-fog-creek-infrastructure-changes/#comments</comments>
		<pubDate>Fri, 01 Mar 2013 15:47:23 +0000</pubDate>
		<dc:creator>Mendy Berkowitz</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.fogcreek.com/?p=2857</guid>
		<description><![CDATA[Back in October the New York harbor paid an unwelcome visit to the datacenter that houses our servers. Followers of this space are aware of the heroic efforts that literally kept the lights on. Those events were  inspiring and made us all proud to be part of Fog Creek. But as Sys Admins our job [...]]]></description>
				<content:encoded><![CDATA[<p>Back in October the New York harbor paid an <a href="http://en.wikipedia.org/wiki/Hurricane_sandy">unwelcome visit</a> to the datacenter that houses our servers. Followers of this <a href="http://blog.fogcreek.com/hurricane-sandy-wrap-up/">space</a> are aware of the <a href="http://status.fogcreek.com/2012/10/400-pm-changing-of-the-guard-still-on-backup-power.html">heroic</a> <a href="http://blog.stackoverflow.com/2012/11/se-podcast-36-we-got-hit-by-a-hurricane/">efforts</a> that literally kept the lights on. Those events were  inspiring and made us all proud to be part of Fog Creek. But as Sys Admins our job is to view heroic efforts as a failure in planning, preparation and architecture. So as soon as the flood waters receded we set ourselves on a path to improve the continuity and availability of FogBugz and Kiln, with the ultimate goal a second geographically diverse datacenter. As with all lofty goals the path has several large phases and milestones. Now, some of those milestones are upon us and it is time for an update.</p>
<p>The first major step is moving all of our servers from six individual colocation cabinets to seven racks in a cage. The actual move distance is only about 10 meters but represents an upgrade in almost every way. These infrastructure upgrades will enable us to support new releases the FogBugz and Kiln teams are about to ship (teaser alert: we&#8217;ve been <a href="http://blog.fogcreek.com/dogfooding-until-it-hurts/">dog fooding </a>them the last couple of months and they are awesome, <a href="http://www.fogcreek.com/contact.html">contact us</a> if you want to participate in the beta). The cage will provide Fog Creek a solid foundation for the future and the ability to free up enough gear to equip a second datacenter.</p>
<p>We are striving to keep the impact of this move as transparent as possible. However, during March we will have three significant Saturday night maintenance windows during which FogBugz and Kiln will be unavailable. Our goal is to keep these outages a short as possible, as few as possible, and during a time of low usage for a majority of customers. To paraphrase <a href="http://en.wikipedia.org/wiki/Helmuth_von_Moltke_the_Elder">Moltke</a> “No project plan survives first contact with the server room,” so more details on the timing and scheduling will be forthcoming. Watch this space and our <a href="http://fogcreekstatus.com/">status blog</a> for more details. We are committed to the Fog Creek guarantee of not wanting your money if you are not amazingly happy. These upgrades are a huge  part of our commitment to live up to that guarantee. Please let us know if these outages materially impact your business and we will make it right.</p>
<p>Here are some questions you are probably asking and we have asked ourselves over the past months:</p>
<p><strong>Why stay in Peer1?</strong><br />
Why stay in a datacenter located in one of the most expensive pieces of real estate, in a flood zone, in a shared building? All excellent questions, but as we debated the various answers we realized there was nothing wrong with our current datacenter that a second datacenter wouldn&#8217;t fix. In a disaster (natural or man made)  situation, a second geographically diverse datacenter with a tested and practiced failover procedure is our best option for providing our customers with continued service. Fog Creek has grown up with Peer1 over the past 10 years and we have a great relationship with Mike and Scott (the real heroes of Sandy) who operate the facility. So we decided to stay and make Peer1 part of our overall strategy.</p>
<p><strong>Why not move to the cloud like Trello?</strong><br />
We aren&#8217;t parochial about choosing technology solutions. We want the best technology to solve the problem at hand (just search for cloud vs. dedicated server if you are looking for parochial arguments). Before Sandy arrived we had begun the process of moving Trello to AWS. A <a href="http://blog.fogcreek.com/the-trello-tech-stack/">technology stack</a> well suited to horizontal scaling and <a href="http://blog.trello.com/thanks-a-million/">stellar growth</a> made Trello an excellent candidate for cloud hosting. FogBugz and Kiln use different technology stacks and are more I/O intensive than Trello. For these and many other reasons, the cloud isn&#8217;t the right solution for FogBugz and Kiln at this time.</p>
<p>We will have before and after pictures and some other fun vignettes into the process. If you want to work on awesome exciting projects, we are <a href="http://www.fogcreek.com/Jobs/SystemAdministrator.html">looking for experienced unstoppable Sys Admins</a>!</p>
<img src="http://feeds.feedburner.com/~r/FogCreekBlog/~4/9C5B8e6Ny4w" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.fogcreek.com/cage-set-match-fog-creek-infrastructure-changes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.fogcreek.com/feeder/?FeederAction=clicked&amp;feed=Fog+Creek+Blog&amp;seed=http%3A%2F%2Fblog.fogcreek.com%2Fcage-set-match-fog-creek-infrastructure-changes%2F&amp;seed_title=Cage+Set+Match%3A+Fog+Creek+Infrastructure+Changes</feedburner:origLink></item>
	</channel>
</rss><!-- Dynamic page generated in 0.641 seconds. --><!-- Cached page generated by WP-Super-Cache on 2013-06-14 16:48:31 -->
