On Oct 21, 2011, at 9:08 PM, Noah Slater wrote:

> Because 1.1 might have features in it that 1.2 does not. Or 1.1 might have a
> security problem that 1.2 does not.  As Adam points out, there are many small
> changes to files such as CHANGES or acinclude.in that are never
> forward-ported. This kind of things goes on more than you might imagine. 1.1
> is a branch of trunk, and it very likely has things in it that no future
> branch will ever have. The lineage of CouchDB is not a big long line, one
> release following on from another. It is much better to think of it as a
> tree, with branches coming off from it.

        I've never considered CHANGES, version numbers, or any other such thing 
that's managed by the revision control system as part of the source code, so I 
don't suffer these limitations in my projects.

        I write my human readable changelog directly into my tag and also 
generate a commit log to go along with the release.  So, so many maintenance 
issues have gone away in every project I've done that in.

        Consider my java memcached client.  The tag itself defines the tree 
version.  There is exactly *one* place where the number is defined.  The build 
system picks up that number and uses it to number itself.  While it's in there, 
it grabs the whole change log and makes it available via a command line:

        https://gist.github.com/gists/1305645

        The first file there is showing the output of introspection commands on 
the .jar itself.  The second is showing the tag the human typed up for release. 
 The source doesn't change when we branch.

        memcached has similar things for autoconf.  The version number exists 
in only one place, so merging conflicts have nothing to do with administrative 
stuff.

> Again, this assumes a linear progression of changes, which in reality does
> not exist.

        The only assumption I'm making is that you're not concurrently 
innovating on 1.1.x and 1.2.x and planning to maintain both forever.

> I am not sure I understand this point. Are you suggesting that in order to
> enforce an artificial linear progression of changes we should do fake noop
> merges of any changesets applied to older release branches on to newer
> release branches, even if those changes make no sense (such as updating a
> line in acinclude.in) or apply to non-existent bits of code? I'm sorry, but
> I m

        Nope.  I'm suggesting that the set of changes contained within the 
"maintenance" branches and the "new" branches (as well as other "maintenance" 
branches) will continue to grow and you'll have to have tools or procedures to 
know what changes went into one place that didn't go into another.  I'd prefer 
to just say, "What's in 1.1 that's not in 1.2?" (a trivial commandline op) and 
have it tell me "nothing" most of the time.  A growing list that requires 
people to think about stuff makes it easier to make mistakes.

        This strategy predates my git experience, but git only makes it easier.

        I'm not talking about something particularly strange enough to be 
labeled "fake", but pulling it up from more to less firm trees means always 
knowing the state of things.  Things that don't apply have to be resolved.  A 
perfectly valid resolution is "just keep what I have".  The histories merge so 
you can note in the merge that the bug was in code that no longer exists, but 
you've *explicitly* done that in a machine trackable way.

        We actually have the same kind of thing going on in memcached right 
now.  There are a lot of bugs fixed in the 1.4.x branch that don't exist (or 
are applied considerably differently) in 1.6.x.  Either way, I will record the 
1.4 changes in the 1.6 history.

> Again, this assumes a linear progression of changes. Like I said above, it's
> more like a literal tree trunk, or perhaps a set of parallel universes.
> Every time we cut a release branch, we're creating an alternate reality for
> CouchDB. Most of these wither away. For a short time, we will back-port
> fixes for them, or even apply fixes to them that never get forward ported.
> But they are separate time-lines, and they need to be thought about and
> managed as if that were the case. It's tricky at times, sure. But there are
> tricker parts of the release process!


        It's a graph.  Just because I can draw a line between two points on the 
graph doesn't mean that I think it's linear.  It really doesn't matter whether 
it's linear or if every couchdb contributor wrote a non-conflicting change at 
the same time and you did a 256-way octopus merge -- or anything in between.

        At the end of the night, a single commit represents the head of a 
branch or the commit pointed to by the tag.  A merge-base exists between that 
and any other branch in your system and you have tools that can tell you all 
the things that are to the left or the right of that merge-base (or more if 
you're looking to do an n-way octopus merge across more than two -- I've done 
up to 24 myself).

        I can do uni- or bi-directional set differences or just straight up 
diffs from either point and think about what the results mean.  In practice, I 
can't justify excluding changes from our 1.4 releases when we prep the 1.6 
release.  It just gives me too much to think about (there are 444 new changes 
in one direction and 16 in the other).

-- 
dustin sallings



Reply via email to