Skip to content

Instantly share code, notes, and snippets.

@steveklabnik
Last active August 29, 2015 14:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save steveklabnik/17b7bbf1c7aa5784ad55 to your computer and use it in GitHub Desktop.
Save steveklabnik/17b7bbf1c7aa5784ad55 to your computer and use it in GitHub Desktop.

Branching

I’d like to lay out the branching strategy for future Rust releases. The 1.0 release is going to be a bit different than the rest, but will initiate the ‘usual’ process going on into the future.

1.0

Why have a different process for 1.0? There are two reasons:

  1. We’re already past the point of the ‘usual’ process. That is, we haven’t actually started branching yet. Doing it the usual way would require a time machine.
  2. 1.0 has special requirements, as we’ll be backporting basically all patches from master for this initial period, and so branching too early just adds overhead.

Let’s get to it. I’m going to be using graphs like this to show the branching:

master: A - B - C
             \
release:      D - C'

The branch name is on the left, and commits are capital letters. Primes (') are used to indicate backported commits. release branched off of master at B, and C' was backported from C on master, in this diagram.

Rust has more than three commits on master so far, but we’ll pretend like all that history doesn’t exist for simplification purposes.

Here’s Rust development today:

master: A - B

At some point, preferably on the 24th of April, halfway through the beta cycle, we’ll cut a branch for 1.0, called 1.0-beta:

master: A - B
             \
1.0-beta:      

All regular work will keep going on the master branch:

master: A - B - C - D
             \
1.0-beta:      

This is the important part of this strategy. Everything lands on master first. master is the canonical source of truth from which all else flows. New -beta branches always end up forking off of master.

When a committer determines that a commit should be backported to the beta branch, they’ll open a second PR against the beta branch directly. We could also possibly automate this through @bors, though some commits may need massaging, of course. And generally speaking, after 1.0, backports should be relatively rare.

master: A - B - C - D - E
             \
1.0-beta:     E'

And work continues...

master: A - B - C - D - E - F
             \
1.0-beta:     E'

And other commits are backported:

master: A - B - C - D - E - F - G
             \
1.0-beta:     E' - G'

I’m going to shorten the commits a tad to make it smaller:

master: A - B - C - ... - G
             \
1.0-beta:     E' - G'

Anyway, then, on May 15, the release happens. At that time, we cut a 1.0-stable branch from 1.0-beta:

master: A - B - C - ... - G
             \
1.0-beta:     E' - G'
                    \
1.0-stable:          

Just like -beta branches always come off of master, -stable branches always come off of their associated -beta branch.

Speaking of which, we cut a new, 1.1-beta branch from master:

master: A - B - C - ... - G
             \             \
1.1-beta:     \              
               \
1.0-beta:       E' - G'
                      \
1.0-stable:          

Ideally, the 1.0-* branches won’t need anything more than that. But let’s say we discover a critical security, and fix it with H:

master: A - B - C - ... - G - H
             \             \
1.1-beta:     \             H' 
               \
1.0-beta:       E' - G' - H''
                      \
1.0-stable:            H'''

H needs to be backported against every relevant branch, possibly a number of them.

1.1 and beyond

Let’s do some more work:

master: A - B - C - ... - G - H - I
             \             \
1.1-beta:     \             H' 
               \
1.0-beta:       E' - G' - H''
                      \
1.0-stable:            H'''

and backport a new commit to 1.1-beta:

master: A - B - C - ... - G - H - I - J
             \             \
1.1-beta:     \             H' - J'
               \
1.0-beta:       E' - G' - H''
                      \
1.0-stable:            H'''

Now it’s time to release 1.1. We do the same as before: we make a new 1.1-stable and 1.2-beta branches:

master: A - B - C - ... - G - H - I - J
             \             \           \
1.2-beta:     \             \
               \             \
1.1-beta:       \             H' - J'
                 \                  \
1.1-stable:       \                  
                   \
1.0-beta:           E' - G' - H''
                          \
1.0-stable:                H'''

And more work gets done on master:

master: A - B - C - ... - G - H - I - J - K
             \             \           \
1.2-beta:     \             \
               \             \
1.1-beta:       \             H' - J'
                 \                  \
1.1-stable:       \                  
                   \
1.0-beta:           E' - G' - H''
                          \
1.0-stable:                H'''

And backported to 1.2-beta where need be:

master: A - B - C - ... - G - H - I - J - K - L
             \             \           \
1.2-beta:     \             \           L'
               \             \
1.1-beta:       \             H' - J'
                 \                  \
1.1-stable:       \                  
                   \
1.0-beta:           E' - G' - H''
                          \
1.0-stable:                H'''

Until 1.2 gets released, when a new 1.2-stable and 1.3-beta branches get made. And so on and so on and so on.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment